You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
387 lines
10 KiB
387 lines
10 KiB
/*
|
|
* Copyright (c) 2015, Intel Corporation
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation and/or
|
|
* other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#include "ElementHandle.h"
|
|
#include "ParameterAccessContext.h"
|
|
#include "BaseParameter.h"
|
|
#include "XmlParameterSerializingContext.h"
|
|
#include "Subsystem.h"
|
|
#include <assert.h>
|
|
#include "ParameterMgr.h"
|
|
|
|
#include <mutex>
|
|
|
|
using std::string;
|
|
using std::mutex;
|
|
using std::lock_guard;
|
|
|
|
/** @return 0 by default, ie for non overloaded types. */
|
|
template <class T>
|
|
static size_t getUserInputSize(const T & /*scalar*/)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/** @return the vector's size. */
|
|
template <class T>
|
|
static size_t getUserInputSize(const std::vector<T> &vector)
|
|
{
|
|
return vector.size();
|
|
}
|
|
|
|
ElementHandle::ElementHandle(CConfigurableElement &element, CParameterMgr ¶meterMgr)
|
|
: mElement(element), mParameterMgr(parameterMgr)
|
|
{
|
|
}
|
|
|
|
string ElementHandle::getName() const
|
|
{
|
|
return mElement.getName();
|
|
}
|
|
|
|
size_t ElementHandle::getSize() const
|
|
{
|
|
return mElement.getFootPrint();
|
|
}
|
|
|
|
bool ElementHandle::isParameter() const
|
|
{
|
|
return mElement.isParameter();
|
|
}
|
|
|
|
string ElementHandle::getDescription() const
|
|
{
|
|
return mElement.getDescription();
|
|
}
|
|
|
|
// Parameter features
|
|
bool ElementHandle::isRogue() const
|
|
{
|
|
return mElement.isRogue();
|
|
}
|
|
|
|
bool ElementHandle::isArray() const
|
|
{
|
|
return getArrayLength() != 0;
|
|
}
|
|
|
|
size_t ElementHandle::getArrayLength() const
|
|
{
|
|
// Only instances can be arrays, SystemClass can not, nor subsystems
|
|
auto *instance = dynamic_cast<CInstanceConfigurableElement *>(&mElement);
|
|
if (instance == nullptr) {
|
|
return 0;
|
|
}
|
|
return instance->getArrayLength();
|
|
}
|
|
|
|
string ElementHandle::getPath() const
|
|
{
|
|
return mElement.getPath();
|
|
}
|
|
|
|
string ElementHandle::getKind() const
|
|
{
|
|
return mElement.getKind();
|
|
}
|
|
|
|
std::vector<ElementHandle> ElementHandle::getChildren()
|
|
{
|
|
size_t nbChildren = mElement.getNbChildren();
|
|
|
|
std::vector<ElementHandle> children;
|
|
children.reserve(nbChildren);
|
|
|
|
for (size_t childIndex = 0; childIndex < nbChildren; ++childIndex) {
|
|
auto *child = static_cast<CConfigurableElement *>(mElement.getChild(childIndex));
|
|
// Can not use emplace back as the constructor is private
|
|
children.push_back({*child, mParameterMgr});
|
|
}
|
|
return children;
|
|
}
|
|
|
|
bool ElementHandle::getMappingData(const string &strKey, string &strValue) const
|
|
{
|
|
const std::string *pStrValue;
|
|
|
|
// Seach for the key in self and ancestors
|
|
auto elements = mElement.getConfigurableElementContext();
|
|
|
|
for (auto *element : elements)
|
|
if (element->getMappingData(strKey, pStrValue)) {
|
|
strValue = *pStrValue;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool ElementHandle::getStructureAsXML(std::string &xmlSettings, std::string &error) const
|
|
{
|
|
// Use default access context for structure export
|
|
CParameterAccessContext accessContext(error);
|
|
return mParameterMgr.exportElementToXMLString(
|
|
&mElement, mElement.getXmlElementName(),
|
|
CXmlParameterSerializingContext{accessContext, error}, xmlSettings);
|
|
}
|
|
|
|
template <class T>
|
|
struct isVector : std::false_type
|
|
{
|
|
};
|
|
template <class T>
|
|
struct isVector<std::vector<T>> : std::true_type
|
|
{
|
|
};
|
|
|
|
bool ElementHandle::getAsXML(std::string &xmlValue, std::string &error) const
|
|
{
|
|
std::string result;
|
|
if (not mParameterMgr.getSettingsAsXML(&mElement, result)) {
|
|
error = result;
|
|
return false;
|
|
}
|
|
|
|
xmlValue = result;
|
|
return true;
|
|
}
|
|
|
|
bool ElementHandle::setAsXML(const std::string &xmlValue, std::string &error)
|
|
{
|
|
return mParameterMgr.setSettingsAsXML(&mElement, xmlValue, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsBytes(std::vector<uint8_t> &bytesValue, std::string & /*error*/) const
|
|
{
|
|
mParameterMgr.getSettingsAsBytes(mElement, bytesValue);
|
|
|
|
// Currently this operation can not fail.
|
|
// Nevertheless this is more a design than intrinsic property.
|
|
// Use the same error reporting pattern to avoid breaking the api in future
|
|
// release if an error need to be reported (and be consistent with all other getAs*).
|
|
return true;
|
|
}
|
|
|
|
bool ElementHandle::setAsBytes(const std::vector<uint8_t> &bytesValue, std::string &error)
|
|
{
|
|
return mParameterMgr.setSettingsAsBytes(mElement, bytesValue, error);
|
|
}
|
|
|
|
template <class T>
|
|
bool ElementHandle::setAs(const T value, string &error) const
|
|
{
|
|
if (not checkSetValidity(getUserInputSize(value), error)) {
|
|
return false;
|
|
}
|
|
// Safe downcast thanks to isParameter check in checkSetValidity
|
|
auto ¶meter = static_cast<CBaseParameter &>(mElement);
|
|
|
|
// When in tuning mode, silently skip "set" requests
|
|
if (mParameterMgr.tuningModeOn()) {
|
|
|
|
return true;
|
|
}
|
|
|
|
CParameterAccessContext parameterAccessContext(error, mParameterMgr.getParameterBlackboard());
|
|
|
|
// BaseParamere::access takes a non-const argument - therefore we need to
|
|
// copy the value
|
|
T copy = value;
|
|
|
|
// Ensure we're safe against blackboard foreign access
|
|
lock_guard<mutex> autoLock(mParameterMgr.getBlackboardMutex());
|
|
|
|
return parameter.access(copy, true, parameterAccessContext);
|
|
}
|
|
|
|
template <class T>
|
|
bool ElementHandle::getAs(T &value, string &error) const
|
|
{
|
|
if (not checkGetValidity(isVector<T>::value, error)) {
|
|
return false;
|
|
}
|
|
// Safe downcast thanks to isParameter check in checkGetValidity
|
|
auto ¶meter = static_cast<const CBaseParameter &>(mElement);
|
|
|
|
// Ensure we're safe against blackboard foreign access
|
|
lock_guard<mutex> autoLock(mParameterMgr.getBlackboardMutex());
|
|
|
|
CParameterAccessContext parameterAccessContext(error, mParameterMgr.getParameterBlackboard());
|
|
|
|
return parameter.access(value, false, parameterAccessContext);
|
|
}
|
|
|
|
// Boolean access
|
|
bool ElementHandle::setAsBoolean(bool value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsBoolean(bool &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::setAsBooleanArray(const std::vector<bool> &value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsBooleanArray(std::vector<bool> &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
// Integer Access
|
|
bool ElementHandle::setAsInteger(uint32_t value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsInteger(uint32_t &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::setAsIntegerArray(const std::vector<uint32_t> &value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsIntegerArray(std::vector<uint32_t> &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
// Signed Integer Access
|
|
bool ElementHandle::setAsSignedInteger(int32_t value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsSignedInteger(int32_t &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::setAsSignedIntegerArray(const std::vector<int32_t> &value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsSignedIntegerArray(std::vector<int32_t> &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
// Double Access
|
|
bool ElementHandle::setAsDouble(double value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsDouble(double &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::setAsDoubleArray(const std::vector<double> &value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsDoubleArray(std::vector<double> &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
// String Access
|
|
bool ElementHandle::setAsString(const string &value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsString(string &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::setAsStringArray(const std::vector<string> &value, string &error)
|
|
{
|
|
return setAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::getAsStringArray(std::vector<string> &value, string &error) const
|
|
{
|
|
return getAs(value, error);
|
|
}
|
|
|
|
bool ElementHandle::checkGetValidity(bool asArray, string &error) const
|
|
{
|
|
if (not isParameter()) {
|
|
error = "Can not set element " + getPath() + " as it is not a parameter.";
|
|
return false;
|
|
}
|
|
|
|
if (asArray != isArray()) {
|
|
|
|
auto toStr = [](bool array) { return array ? "an array" : "a scalar"; };
|
|
error = "Can not get \"" + getPath() + "\" as " + toStr(asArray) + " because it is " +
|
|
toStr(isArray());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Access validity
|
|
bool ElementHandle::checkSetValidity(size_t arrayLength, string &error) const
|
|
{
|
|
// Settings a parameter necessitates the right to get it
|
|
if (not checkGetValidity(arrayLength != 0, error)) {
|
|
return false;
|
|
}
|
|
|
|
if (!isRogue()) {
|
|
|
|
error = "Can not set parameter \"" + getPath() + "\" as it is not rogue.";
|
|
return false;
|
|
}
|
|
|
|
if (arrayLength && (arrayLength != getArrayLength())) {
|
|
|
|
using std::to_string;
|
|
error = "Array length mismatch for \"" + getPath() + "\", expected: " +
|
|
to_string(getArrayLength()) + ", got: " + to_string(arrayLength);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|