aboutsummaryrefslogtreecommitdiffstats
path: root/bindings/c/ParameterFramework.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/c/ParameterFramework.cpp')
-rw-r--r--bindings/c/ParameterFramework.cpp397
1 files changed, 397 insertions, 0 deletions
diff --git a/bindings/c/ParameterFramework.cpp b/bindings/c/ParameterFramework.cpp
new file mode 100644
index 0000000..efc7d99
--- /dev/null
+++ b/bindings/c/ParameterFramework.cpp
@@ -0,0 +1,397 @@
+/*
+ * 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 "ParameterFramework.h"
+#include <ParameterMgrPlatformConnector.h>
+
+#include <iostream>
+#include <limits>
+#include <string>
+#include <map>
+
+#include <cassert>
+#include <cstring>
+#include <cstdlib>
+
+using std::string;
+
+/** Rename long pfw types to short ones in pfw namespace. */
+namespace pfw
+{
+ typedef ISelectionCriterionInterface Criterion;
+ typedef std::map<string, Criterion *> Criteria;
+ typedef CParameterMgrPlatformConnector Pfw;
+}
+
+/** Class to abstract the boolean+string status api. */
+class Status
+{
+public:
+ /** Fail without an instance of status. */
+ static bool failure() { return false; }
+ /** Fail with the given error msg. */
+ bool failure(const string &msg) { mMsg = msg; return false; }
+ /** Success (no error message). */
+ bool success() { mMsg.clear(); return true; }
+
+ /** Forward a status operation.
+ * @param success[in] the operaton status to forward
+ * or forward a previous failure if omitted
+ */
+ bool forward(bool success = false) {
+ if (success) { mMsg.clear(); }
+ return success;
+ }
+ /** Error message accessors.
+ *
+ * Pfw api requires to provide a reference to a string in order
+ * for it to log. This function provide a reference to a string that
+ * will be added to the error message on failure.
+ */
+ string &msg() { return mMsg; }
+private:
+ string mMsg;
+};
+
+///////////////////////////////
+///////////// Log /////////////
+///////////////////////////////
+
+/** Default log callback. Log to cout or cerr depending on level. */
+static void defaultLogCb(void *, PfwLogLevel level, const char *logLine) {
+ switch (level) {
+ case pfwLogInfo:
+ std::cout << logLine << std::endl;
+ break;
+ case pfwLogWarning:
+ std::cerr << logLine << std::endl;
+ break;
+ };
+}
+
+static PfwLogger defaultLogger = { NULL, &defaultLogCb };
+
+class LogWrapper : public CParameterMgrPlatformConnector::ILogger
+{
+public:
+ LogWrapper(const PfwLogger &logger) : mLogger(logger) {}
+ LogWrapper() : mLogger() {}
+ virtual ~LogWrapper() {}
+private:
+ virtual void log(bool bIsWarning, const string &strLog)
+ {
+ // A LogWrapper should NOT be register to the pfw (thus log called)
+ // if logCb is NULL.
+ assert(mLogger.logCb != NULL);
+ mLogger.logCb(mLogger.userCtx,
+ bIsWarning ? pfwLogWarning : pfwLogInfo,
+ strLog.c_str());
+ }
+ PfwLogger mLogger;
+};
+
+///////////////////////////////
+///////////// Core ////////////
+///////////////////////////////
+
+struct PfwHandler_
+{
+ void setLogger(const PfwLogger *logger);
+ bool createCriteria(const PfwCriterion criteria[], size_t criterionNb);
+
+ pfw::Criteria criteria;
+ pfw::Pfw *pfw;
+ /** Status of the last called function.
+ * Is mutable because even a const function can fail.
+ */
+ mutable Status lastStatus;
+private:
+ LogWrapper mLogger;
+};
+
+
+PfwHandler *pfwCreate()
+{
+ return new PfwHandler();
+}
+
+void pfwDestroy(PfwHandler *handle)
+{
+ if(handle != NULL and handle->pfw != NULL) {
+ delete handle->pfw;
+ }
+ delete handle;
+}
+
+void PfwHandler::setLogger(const PfwLogger *logger)
+{
+ if (logger != NULL and logger->logCb == NULL) {
+ return; // There is no callback, do not log => do not add a logger
+ }
+ mLogger = logger != NULL ? *logger : defaultLogger;
+ pfw->setLogger(&mLogger);
+}
+
+
+bool PfwHandler::createCriteria(const PfwCriterion criteriaArray[], size_t criterionNb)
+{
+ Status &status = lastStatus;
+ // Add criteria
+ for (size_t criterionIndex = 0; criterionIndex < criterionNb; ++criterionIndex) {
+ const PfwCriterion &criterion = criteriaArray[criterionIndex];
+ if (criterion.name == NULL) {
+ return status.failure("Criterion name is NULL");
+ }
+ if (criterion.values == NULL) {
+ return status.failure("Criterion values is NULL");
+ }
+ // Check that the criterion does not exist
+ if (criteria.find(criterion.name) != criteria.end()) {
+ return status.failure("Criterion \"" + string(criterion.name) +
+ "\" already exist");
+ }
+
+ // Create criterion type
+ ISelectionCriterionTypeInterface *type =
+ pfw->createSelectionCriterionType(criterion.inclusive);
+ assert(type != NULL);
+ // Add criterion values
+ for (size_t valueIndex = 0; criterion.values[valueIndex] != NULL; ++valueIndex) {
+ int value;
+ if (criterion.inclusive) {
+ // Check that (int)1 << valueIndex would not overflow (UB)
+ if(std::numeric_limits<int>::max() >> valueIndex == 0) {
+ return status.failure("Too many values for criterion " +
+ string(criterion.name));
+ }
+ value = 1 << valueIndex;
+ } else {
+ value = valueIndex;
+ }
+ const char * valueName = criterion.values[valueIndex];
+ if(not type->addValuePair(value, valueName)) {
+ return status.failure("Could not add value " + string(valueName) +
+ " to criterion " + criterion.name);
+ }
+ }
+ // Create criterion and add it to the pfw
+ criteria[criterion.name] = pfw->createSelectionCriterion(criterion.name, type);
+ }
+ return status.success();
+}
+
+
+bool pfwStart(PfwHandler *handle, const char *configPath,
+ const PfwCriterion criteria[], size_t criterionNb,
+ const PfwLogger *logger)
+{
+ // Check that the api is correctly used
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->lastStatus;
+
+ if (handle->pfw != NULL) {
+ return status.failure("Can not start an already started parameter framework");
+ }
+ if (configPath == NULL) {
+ return status.failure("char *configPath is NULL, "
+ "while starting the parameter framework");
+ }
+ if (criteria == NULL) {
+ return status.failure("char *criteria is NULL, "
+ "while starting the parameter framework "
+ "(config path is " + string(configPath) + ")");
+ }
+ // Create a pfw
+ handle->pfw = new CParameterMgrPlatformConnector(configPath);
+
+ handle->setLogger(logger);
+
+ if (not handle->createCriteria(criteria, criterionNb)) {
+ return status.failure();
+ }
+
+ return status.forward(handle->pfw->start(status.msg()));
+}
+
+const char *pfwGetLastError(const PfwHandler *handle)
+{
+ return handle == NULL ? NULL : handle->lastStatus.msg().c_str();
+}
+
+static pfw::Criterion *getCriterion(const pfw::Criteria &criteria,
+ const string &name)
+{
+ pfw::Criteria::const_iterator it = criteria.find(name);
+ return it == criteria.end() ? NULL : it->second;
+}
+
+bool pfwSetCriterion(PfwHandler *handle, const char name[], int value)
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->lastStatus;
+ if (name == NULL) {
+ return status.failure("char *name of the criterion is NULL, "
+ "while setting a criterion.");
+ }
+ if (handle->pfw == NULL) {
+ return status.failure("Can not set criterion \"" + string(name) +
+ "\" as the parameter framework is not started.");
+ }
+ pfw::Criterion *criterion = getCriterion(handle->criteria, name);
+ if (criterion == NULL) {
+ return status.failure("Can not set criterion " + string(name) + " as does not exist");
+ }
+ criterion->setCriterionState(value);
+ return status.success();
+}
+bool pfwGetCriterion(const PfwHandler *handle, const char name[], int *value)
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->lastStatus;
+ if (name == NULL) {
+ return status.failure("char *name of the criterion is NULL, "
+ "while getting a criterion.");
+ }
+ if (handle->pfw == NULL) {
+ return status.failure("Can not get criterion \"" + string(name) +
+ "\" as the parameter framework is not started.");
+ }
+ if (value == NULL) {
+ return status.failure("Can not get criterion \"" + string(name) +
+ "\" as the out value is NULL.");
+ }
+ pfw::Criterion *criterion = getCriterion(handle->criteria, name);
+ if (criterion == NULL) {
+ return status.failure("Can not get criterion " + string(name) + " as it does not exist");
+ }
+ *value = criterion->getCriterionState();
+ return status.success();
+}
+
+bool pfwApplyConfigurations(const PfwHandler *handle)
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->lastStatus;
+ if (handle->pfw == NULL) {
+ return status.failure("Can not commit criteria "
+ "as the parameter framework is not started.");
+ }
+ handle->pfw->applyConfigurations();
+ return status.success();
+}
+
+///////////////////////////////
+/////// Parameter access //////
+///////////////////////////////
+
+struct PfwParameterHandler_
+{
+ PfwHandler &pfw;
+ CParameterHandle &parameter;
+};
+
+PfwParameterHandler *pfwBindParameter(PfwHandler *handle, const char path[])
+{
+ if (handle == NULL) { return NULL; }
+ Status &status = handle->lastStatus;
+ if (path == NULL) {
+ status.failure("Can not bind a parameter without its path");
+ return NULL;
+ }
+ if (handle->pfw == NULL) {
+ status.failure("The parameter framework is not started, "
+ "while trying to bind parameter \"" + string(path) + "\")");
+ return NULL;
+ }
+
+ CParameterHandle *paramHandle;
+ paramHandle = handle->pfw->createParameterHandle(path, status.msg());
+ if (paramHandle == NULL) {
+ return NULL;
+ }
+
+ status.success();
+ PfwParameterHandler publicHandle = {*handle, *paramHandle};
+ return new PfwParameterHandler(publicHandle);
+}
+
+void pfwUnbindParameter(PfwParameterHandler *handle)
+{
+ if (handle == NULL) { return; }
+ delete &handle->parameter;
+ delete handle;
+}
+
+
+bool pfwGetIntParameter(const PfwParameterHandler *handle, int32_t *value)
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->pfw.lastStatus;
+ if (value == NULL) {
+ return status.failure("int32_t *value is NULL, "
+ "while trying to get parameter \"" +
+ handle->parameter.getPath() + "\" value as int)");
+ }
+ return status.forward(handle->parameter.getAsSignedInteger(*value, status.msg()));
+}
+bool pfwSetIntParameter(PfwParameterHandler *handle, int32_t value)
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->pfw.lastStatus;
+ return status.forward(handle->parameter.setAsSignedInteger(value, status.msg()));
+}
+
+bool pfwGetStringParameter(const PfwParameterHandler *handle, const char *value[])
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->pfw.lastStatus;
+ if (value == NULL) {
+ return status.failure("char **value is NULL, "
+ "while trying to get parameter \"" +
+ handle->parameter.getPath() + "\" value as string)");
+ }
+ *value = NULL;
+ string retValue;
+ bool success = handle->parameter.getAsString(retValue, status.msg());
+ if (not success) { return status.forward(); }
+
+ *value = strdup(retValue.c_str());
+ return status.success();
+}
+
+bool pfwSetStringParameter(PfwParameterHandler *handle, const char value[])
+{
+ if (handle == NULL) { return Status::failure(); }
+ Status &status = handle->pfw.lastStatus;
+ return status.forward(handle->parameter.setAsString(value, status.msg()));
+}
+
+void pfwFree(void *ptr) { std::free(ptr); }
+