diff options
Diffstat (limited to 'parameter/Subsystem.cpp')
-rw-r--r-- | parameter/Subsystem.cpp | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/parameter/Subsystem.cpp b/parameter/Subsystem.cpp new file mode 100644 index 0000000..a501f91 --- /dev/null +++ b/parameter/Subsystem.cpp @@ -0,0 +1,341 @@ +/* <auto_header> + * <FILENAME> + * + * INTEL CONFIDENTIAL + * Copyright © 2011 Intel + * Corporation All Rights Reserved. + * + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. Title to the Material remains with Intel Corporation or its + * suppliers and licensors. The Material contains trade secrets and proprietary + * and confidential information of Intel or its suppliers and licensors. The + * Material is protected by worldwide copyright and trade secret laws and + * treaty provisions. No part of the Material may be used, copied, reproduced, + * modified, published, uploaded, posted, transmitted, distributed, or + * disclosed in any way without Intel’s prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or delivery + * of the Materials, either expressly, by implication, inducement, estoppel or + * otherwise. Any license under such intellectual property rights must be + * express and approved by Intel in writing. + * + * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com) + * CREATED: 2011-06-01 + * UPDATED: 2011-07-27 + * + * + * </auto_header> + */ +#include "Subsystem.h" +#include "ComponentLibrary.h" +#include "InstanceDefinition.h" +#include "XmlParameterSerializingContext.h" +#include "ParameterAccessContext.h" +#include "ConfigurationAccessContext.h" +#include "SubsystemObjectCreator.h" +#include <assert.h> + +#define base CConfigurableElement + +CSubsystem::CSubsystem(const string& strName) : base(strName), _pComponentLibrary(new CComponentLibrary), _pInstanceDefinition(new CInstanceDefinition), _bBigEndian(false) +{ + // Note: A subsystem contains instance components + // InstanceDefintion and ComponentLibrary objects are then not chosen to be children + // They'll be delt with locally +} + +CSubsystem::~CSubsystem() +{ + // Remove subsystem objects + SubsystemObjectListIterator subsystemObjectIt; + + for (subsystemObjectIt = _subsystemObjectList.begin(); subsystemObjectIt != _subsystemObjectList.end(); ++subsystemObjectIt) { + + delete *subsystemObjectIt; + } + + // Remove susbsystem creators + uint32_t uiIndex; + + for (uiIndex = 0; uiIndex < _subsystemObjectCreatorArray.size(); uiIndex++) { + + delete _subsystemObjectCreatorArray[uiIndex]; + } + + // Order matters! + delete _pInstanceDefinition; + delete _pComponentLibrary; +} + +string CSubsystem::getKind() const +{ + return "Subsystem"; +} + +// Susbsystem Endianness +bool CSubsystem::isBigEndian() const +{ + return _bBigEndian; +} + +// From IXmlSink +bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +{ + // Context + CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext); + + // Install temporary component library for further component creation + parameterBuildContext.setComponentLibrary(_pComponentLibrary); + + CXmlElement childElement; + + // XML populate ComponentLibrary + xmlElement.getChildElement("ComponentLibrary", childElement); + + if (!_pComponentLibrary->fromXml(childElement, serializingContext)) { + + return false; + } + + // XML populate InstanceDefintion + xmlElement.getChildElement("InstanceDefintion", childElement); + if (!_pInstanceDefinition->fromXml(childElement, serializingContext)) { + + return false; + } + + // Create components + _pInstanceDefinition->createInstances(this); + + // Execute mapping to create subsystem mapping entities + string strError; + if (!mapSubsystemElements(strError)) { + + serializingContext.setError(strError); + + return false; + } + + // Endianness + _bBigEndian = xmlElement.getAttributeBoolean("Endianness", "Big"); + + return true; +} + +// XML configuration settings parsing +bool CSubsystem::serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const +{ + // Fix Endianness + configurationAccessContext.setBigEndianSubsystem(_bBigEndian); + + return base::serializeXmlSettings(xmlConfigurableElementSettingsElement, configurationAccessContext); +} + + +bool CSubsystem::mapSubsystemElements(string& strError) +{ + // Default mapping context + _contextStack.push(CMappingContext(_contextMappingKeyArray.size())); + + // Map all instantiated subelements in subsystem + uint32_t uiNbChildren = getNbChildren(); + uint32_t uiChild; + + for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { + + CInstanceConfigurableElement* pInstanceConfigurableChildElement = static_cast<CInstanceConfigurableElement*>(getChild(uiChild)); + + if (!pInstanceConfigurableChildElement->map(*this, strError)) { + + return false; + } + } + return true; +} + +// Parameter access +bool CSubsystem::setValue(CPathNavigator& pathNavigator, const string& strValue, CErrorContext& errorContext) const +{ + CParameterAccessContext& parameterContext = static_cast<CParameterAccessContext&>(errorContext); + + // Deal with Endianness + parameterContext.setBigEndianSubsystem(_bBigEndian); + + return base::setValue(pathNavigator, strValue, errorContext); +} + +bool CSubsystem::getValue(CPathNavigator& pathNavigator, string& strValue, CErrorContext& errorContext) const +{ + CParameterAccessContext& parameterContext = static_cast<CParameterAccessContext&>(errorContext); + + // Deal with Endianness + parameterContext.setBigEndianSubsystem(_bBigEndian); + + return base::getValue(pathNavigator, strValue, errorContext); +} + +void CSubsystem::logValue(string& strValue, CErrorContext& errorContext) const +{ + CParameterAccessContext& parameterContext = static_cast<CParameterAccessContext&>(errorContext); + + // Deal with Endianness + parameterContext.setBigEndianSubsystem(_bBigEndian); + + return base::logValue(strValue, errorContext); +} + +// Used for simulation only +void CSubsystem::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +{ + // Deal with Endianness + parameterAccessContext.setBigEndianSubsystem(_bBigEndian); + + base::setDefaultValues(parameterAccessContext); +} + +// Belonging subsystem +const CSubsystem* CSubsystem::getBelongingSubsystem() const +{ + return this; +} + +// Subsystem context mapping keys publication +void CSubsystem::addContextMappingKey(const string& strMappingKey) +{ + _contextMappingKeyArray.push_back(strMappingKey); +} + +// Subsystem object creator publication (strong reference) +void CSubsystem::addSubsystemObjectCreator(CSubsystemObjectCreator* pSubsystemObjectCreator) +{ + _subsystemObjectCreatorArray.push_back(pSubsystemObjectCreator); +} + +// Mapping generic context handling +bool CSubsystem::handleMappingContext(const CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError) +{ + // Feed context with found mapping data + uint32_t uiItem; + + for (uiItem = 0; uiItem < _contextMappingKeyArray.size(); uiItem++) { + + string strKey = _contextMappingKeyArray[uiItem]; + string strValue; + + if (pInstanceConfigurableElement->getMappingData(strKey, strValue)) { + // Assign item to context + if (!context.setItem(uiItem, strValue)) { + + getMappingError(strError, strKey, "Already set", pInstanceConfigurableElement); + + return false; + } + } + } + return true; +} + +// Creation handling +bool CSubsystem::handleSubsystemObjectCreation(CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError) +{ + uint32_t uiItem; + + for (uiItem = 0; uiItem < _subsystemObjectCreatorArray.size(); uiItem++) { + + const CSubsystemObjectCreator* pSubsystemObjectCreator = _subsystemObjectCreatorArray[uiItem]; + + // Mapping key + string strKey = pSubsystemObjectCreator->getMappingKey(); + // Object id + string strId; + + if (pInstanceConfigurableElement->getMappingData(strKey, strId)) { + + // First check context consisteny + uint32_t uiAncestorKey; + uint32_t uiAncestorMask = pSubsystemObjectCreator->getAncestorMask(); + + for (uiAncestorKey = 0; uiAncestorKey & uiAncestorMask; uiAncestorKey++) { + + string strAncestorKey = _subsystemObjectCreatorArray[uiAncestorKey]->getMappingKey(); + + if (!context.iSet(uiAncestorKey)) { + + getMappingError(strError, strKey, strAncestorKey + " not set", pInstanceConfigurableElement); + + return false; + } + } + + // Do create object + string strCreationError; + + CSubsystemObject* pSubsystemObject = pSubsystemObjectCreator->objectCreate(strId, pInstanceConfigurableElement, context, strCreationError); + + if (!pSubsystemObject) { + + getMappingError(strError, strKey, strCreationError, pInstanceConfigurableElement); + + return false; + } + // Keep track of created object + _subsystemObjectList.push_back(pSubsystemObject); + + // Done + return true; + } + } + getMappingError(strError, "Mapping key", "Not found", pInstanceConfigurableElement); + + return false; +} + +// Generic error handling from derived subsystem classes +void CSubsystem::getMappingError(string& strError, const string& strKey, const string& strMessage, const CInstanceConfigurableElement* pInstanceConfigurableElement) +{ + strError = getName() + " " + getKind() + " mapping:\n" + strKey + " error : \"" + strMessage + "\" for element " + pInstanceConfigurableElement->getPath(); +} + +// From IMapper +bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, string& strError) +{ + // Get current context + CMappingContext context = _contextStack.top(); + + switch(pInstanceConfigurableElement->getType()) { + + case CInstanceConfigurableElement::EComponent: + + if (!handleMappingContext(pInstanceConfigurableElement, context, strError)) { + + return false; + } + break; + case CInstanceConfigurableElement::EParameterBlock: + case CInstanceConfigurableElement::EBitParameterBlock: + case CInstanceConfigurableElement::EParameter: + { + if (!handleSubsystemObjectCreation(pInstanceConfigurableElement, context, strError)) { + + return false; + } + break; + } + default: + assert(0); + return false; + } + + // Push context + _contextStack.push(context); + + return true; +} + +void CSubsystem::mapEnd() +{ + // Unstack context + _contextStack.pop(); +} |