diff options
| author | François Gaffie <francois.gaffie@intel.com> | 2016-02-17 10:58:44 +0100 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2016-03-04 17:42:09 -0800 |
| commit | 9368eea42a1afb01dd44110582f997115b50e742 (patch) | |
| tree | 5efc2015ec5d52fc32453ad5a1a82a3f4a6b4919 | |
| parent | 0efdadfc1eacc7271c8f854a8a610fdc2cc66102 (diff) | |
| download | platform_external_parameter-framework-9368eea42a1afb01dd44110582f997115b50e742.tar.gz platform_external_parameter-framework-9368eea42a1afb01dd44110582f997115b50e742.tar.bz2 platform_external_parameter-framework-9368eea42a1afb01dd44110582f997115b50e742.zip | |
parameter-framework: Drop of github upstream version v3.2.4
Main features are:
-Networking code may now be opted-out
(for android build: no socket opened for user build)
-Get rid of python prebuild for XML generation
Bug: 22887211
Change-Id: Ieee49b439f694f14ce48c23127d34622691397ef
Signed-off-by: François Gaffie <francois.gaffie@intel.com>
Signed-off-by: David Wagner <david.wagner@intel.com>
470 files changed, 19999 insertions, 12705 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..41d5116 --- /dev/null +++ b/.clang-format @@ -0,0 +1,94 @@ +# 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. + +--- +# The extra indent or outdent of access modifiers +AccessModifierOffset: -4 + +# Align parameters on the open bracket +AlignAfterOpenBracket: Align + +# Disallows contracting simple braced statements to a single line +AllowShortBlocksOnASingleLine: 'false' + +# Short case labels wont't be contracted to a single line +AllowShortCaseLabelsOnASingleLine: 'false' + +# Merge all inline functions fitting on a single line +AllowShortFunctionsOnASingleLine: 'Inline' + +# If (a) return; cannot be put on a single line +AllowShortIfStatementsOnASingleLine: 'false' + +# While (true) continue; cannot be put on a single line +AllowShortLoopsOnASingleLine: 'false' + +# Break after the template<...> of a template declaration. +AlwaysBreakTemplateDeclarations: 'true' + +# Configure each individual brace in BraceWrapping +BreakBeforeBraces: 'Custom' + +# Control of individual brace wrapping cases +BraceWrapping: { + AfterClass: 'true' + AfterControlStatement: 'false' + AfterEnum : 'true' + AfterFunction : 'true' + AfterNamespace : 'true' + AfterStruct : 'true' + AfterUnion : 'true' + BeforeCatch : 'false' + BeforeElse : 'false' + IndentBraces : 'false' +} + +# The column limit +ColumnLimit: '100' + +# The number of columns to use for indentation. +IndentWidth: '4' + +# Targeted language +Language: Cpp + +# No indentation for namespaces. +NamespaceIndentation: None + +# Pointer is aligned to right side +PointerAlignment: Right + +# High penalty to avoid line break just after return type +PenaltyReturnTypeOnItsOwnLine: 10000 + +# Treat 'catch' BDD macros as control instructions +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, GIVEN, WHEN, AND_WHEN, THEN, AND_THEN, + SECTION ] + +SortIncludes: 'false' +... diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b977122 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +.version export-subst +.gitattributes export-ignore +.gitignore export-ignore diff --git a/.travis.yml b/.travis.yml index 48c84b7..db18b6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,52 +14,100 @@ compiler: # it will not be necessary once travis worker is based on ubuntu > 12.04. # Install SWIG for bindings generation # Install valgrind for memcheck tests +# Adding george-edison55-precise-backports ppa for for cmake 3.x. +# Install python3-dev for the client simulator addons: apt: + # Travis white list of ppa + # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json sources: - ubuntu-toolchain-r-test + - george-edison55-precise-backports + - llvm-toolchain-precise + # Travis white list of dpkg packages + # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise packages: - swig - valgrind - g++-4.8 + - cmake-data + - cmake + - python3-dev + - clang-format-3.8 install: - - pip install --user cpp-coveralls; export PATH=$HOME/.local/bin:$PATH + - wget https://codecov.io/bash -O $HOME/codecov; chmod +x $HOME/codecov + # This version of catch is known to work. - wget --directory-prefix $PREFIX/include - https://raw.github.com/philsquared/Catch/master/single_include/catch.hpp + https://raw.github.com/philsquared/Catch/v1.2.1/single_include/catch.hpp + - wget 'https://01.org/sites/default/files/asio-1.10.6.tar.gz' + - tar xf asio-1.10.6.tar.gz -C $PREFIX --strip-components=1 before_script: - - if [ "$CC" = "gcc" ]; then export CC=gcc-4.8 CXX=g++-4.8; fi + - coverage=OFF + # Force the manualy installed 4.8 version as it is not the default + # Only enable coverage on gcc as clang segfault on coverage file write + - if [ "$CC" = "gcc" ]; then + export CC=gcc-4.8 CXX=g++-4.8; + coverage=ON; + fi # how to build script: + # Check coding style + - git ls-files | grep -E '\.[ch](pp)?$' | xargs clang-format-3.8 -i && + git diff --exit-code || { git reset --hard; false; } + - ( mkdir build_debug && cd build_debug && - cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Debug -DCOVERAGE=ON .. && + cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Debug -DCOVERAGE=${coverage} .. && make -j && CTEST_OUTPUT_ON_FAILURE=1 make ExperimentalTest ExperimentalMemCheck ) - ( mkdir build && cd build && - cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_INSTALL_PREFIX=../install .. && + cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_BUILD_TYPE=Release .. && make -j && CTEST_OUTPUT_ON_FAILURE=1 make test && - make install) + make install && + cpack --verbose -G DEB && dpkg --info *.deb) - ( cd skeleton-subsystem && + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../install . && + make && + CTEST_OUTPUT_ON_FAILURE=1 make ExperimentalTest ExperimentalMemCheck && + make install ) + - ( cd tools/clientSimulator && + echo "TODO - install the generated .deb instead of using ../install." + "This would permit to test the packaging" && cmake -DCMAKE_INSTALL_PREFIX=../install . && make && make install ) + # Keep this last + - ( mkdir build_less_features && cd build_less_features && + rm -rf $PREFIX/asio-1.10.6 && + cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Debug + -DNETWORKING=OFF -DPYTHON_BINDINGS=OFF -DC_BINDINGS=OFF .. && + make -j && + CTEST_OUTPUT_ON_FAILURE=1 make test ) after_success: - # Push coverage info on coveralls.io. + # Push coverage info on codecov.io. # Ignore generated files, samples and tests - - coveralls - --exclude "build_debug/bindings/python" - --exclude "build_debug/CMakeFiles" - --exclude "build" - --exclude "skeleton-subsystem" - --exclude "test/test-subsystem" - --exclude "bindings/c/Test.cpp" - --exclude "test/tokenizer" - --gcov /usr/bin/gcov-4.8 - --gcov-options '\--long-file-names --preserve-paths' + - if [ "${coverage}" = "ON" ]; then + $HOME/codecov + -g "*/build_debug/bindings/python/*" + -g "*/build_debug/CMakeFiles/*" + -g "*/build/*" + -g "*/install/*" + -g "*/skeleton-subsystem/*" + -g "*/tools/clientSimulator/*" + -g "*/test/test-subsystem/*" + -g "*/test/introspection-subsystem/*" + -g "*/test/functional-tests/*" + -g "*/test/tmpfile/*" + -g "*/test/tokenizer/*" + -g "*/bindings/c/Test.cpp" + -g "*/utility/test/*" + -x /usr/bin/gcov-4.8 + -a '\--long-file-names --preserve-paths'; + fi notifications: irc: diff --git a/.version b/.version new file mode 100644 index 0000000..dd5b792 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +$Format:%D$ diff --git a/Android.mk b/Android.mk deleted file mode 100644 index b0ec4a5..0000000 --- a/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -# For Android L MR1 and lower, need to include libstlport -# For M, this is not needed -MAJOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -f1 -d.) -MINOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -f2 -d.) - -ifeq ($(shell test $(MAJOR_VERSION) -le 4 && echo 1), 1) -INCLUDE_STLPORT:=true -else ifeq ($(shell test $(MAJOR_VERSION) -eq 5 -a $(MINOR_VERSION) -le 1 && echo 1), 1) -INCLUDE_STLPORT:=true -else -INCLUDE_STLPORT:=false -endif - -# Recursive call sub-folder Android.mk -# -ifneq ($(USE_CUSTOM_PARAMETER_FRAMEWORK), true) -ifeq ($(HOST_OS),linux) -include $(call all-subdir-makefiles) -endif -endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 66602d7..8bf7941 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,29 +26,77 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# has been tested on 2.8 only - might work on older versions -cmake_minimum_required(VERSION 2.8) - -# linking policy (see cmake --help-policy CMP0003) -if(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif(COMMAND cmake_policy) +# Known to work with CMake 3.2.2, might work with older 3.x versions, will not +# work with versions prior to 3.0.0. +# Visual Studio 14 needs 3.3.0; see https://cmake.org/Bug/print_bug_page.php?bug_id=15552 +cmake_minimum_required(VERSION 3.2.2) +if((CMAKE_GENERATOR MATCHES "Visual Studio .*") + AND (CMAKE_GENERATOR STRGREATER "Visual Studio 14 2015")) + cmake_minimum_required(VERSION 3.3.0) +endif() project(parameter-framework) -# find and set the Parameter Framework's version -execute_process(COMMAND git describe --tags --dirty - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - OUTPUT_VARIABLE PARAMETER_FRAMEWORK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) +include(CMakeDependentOption) + +option(COVERAGE "Build with coverage support" OFF) +cmake_dependent_option(BASH_COMPLETION "Install bash completion configuration" + ON + UNIX # Only allow installing bash completion on Unix environments + OFF) +option(DOXYGEN "Enable doxygen generation (you still have to run 'make doc')" OFF) +option(REQUIREMENTS "Generate the html version of the 'requirements' documentation" OFF) +option(PYTHON_BINDINGS "Python library to use the Parameter Framework from python" ON) +option(C_BINDINGS "Library to use the Parameter Framework using a C API" ON) +option(FATAL_WARNINGS "Turn warnings into errors (-Werror flag)" ON) +option(NETWORKING "Set to OFF in order to stub networking code" ON) + +include(SetVersion.cmake) + +# Add FindLibXml2.cmake in cmake path so that `find_package(LibXml2)` will +# call the wrapper +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/cmake") + +if(WIN32) + # By default cmake adds a warning level. + # Nevertheless a different level is wanted for this project. + # If a two different warning levels are present on the command line, cl raises a warning. + # Thus delete the default level to set a different one. + string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra") + # Force include iso646.h to support alternative operator form (and, or, not...) + # Such support is require by the standard and can be enabled with /Za + # but doing so breaks compilation of windows headers... + # + # Suppress warning 4127 (Conditional expression is constant) as it break + # compilation when testing template value arguments or writing `while(true)`. + # + # Suppress warning 4251 (related to exported symbol without dll interface) + # as it refers to private members (coding style forbids exposing attribute) + # and thus are not to be used by the client. A better fix would be to export + # only public methods instead of the whole class, but they are too many to + # do that. A separated plugin interface would fix that. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /FIiso646.h -wd4127 -wd4251") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + # FIXME: Once we have removed all warnings on windows, add the /WX flags if + # FATAL_WARNINGS is enabled +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wconversion -Wno-sign-conversion") + if(FATAL_WARNINGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + endif() +endif() + +# Hide symbols by default, then exposed symbols are the same in linux and windows +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN true) + + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) include(ctest/CMakeLists.txt) -option(COVERAGE "Build with coverage support" OFF) if(COVERAGE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") @@ -57,14 +105,14 @@ endif() add_subdirectory(xmlserializer) add_subdirectory(parameter) add_subdirectory(utility) +add_subdirectory(asio) add_subdirectory(remote-processor) add_subdirectory(remote-process) add_subdirectory(test) -option(BASH_COMPLETION "Install bash completion configuration" ON) -if (BASH_COMPLETION) +if(BASH_COMPLETION) add_subdirectory(tools/bash_completion) endif() @@ -74,3 +122,7 @@ add_subdirectory(tools/xmlValidator) add_subdirectory(bindings) add_subdirectory(doc) + +add_subdirectory(schemas) + +add_subdirectory(cpack) @@ -1,31 +0,0 @@ -parameter-framework and associated libraries and tools are licensed under the -3-Clause BSD license: - -Copyright (c) 2011-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. - @@ -1,7 +1,8 @@ # parameter-framework [](https://travis-ci.org/01org/parameter-framework) -[](https://coveralls.io/r/01org/parameter-framework) +[](https://ci.appveyor.com/project/parameter-framework/parameter-framework) +[](https://codecov.io/github/01org/parameter-framework?branch=master) ## Introduction @@ -63,19 +64,102 @@ See [the wiki on github](https://github.com/01org/parameter-framework/wiki). ## Compiling +**You may take a look at `.travis.yml` and `appveyor.yml` for examples on how we +build the Parameter Framework in the CI.** It will probably help if you have +troubles building the Parameter Framework even after reading the following +sections: + +### Dependencies + +In order to compile you'll need, at the very least: + +- CMake (v3.2.2 or later) (v3.3.0 or later on Windows); +- A C/C++ compiler supporting C++11; +- libxml2 headers and libraries (Provided by the `libxml2-dev` on debian-based +distributions); + +If you want to use the remote command interface (`NETWORKING=ON` by default), +you'll also need: + +- Standalone ASIO (1.10.6 or later) (Provided by `libasio-dev` on debian-based +distributions) ASIO is C++ header-only ASynchronous-IO library. + +If you want to compile the *Python bindings* (`PYTHON_BINDINGS=ON` by default), +you'll also need: + +- SWIG 2.0 (A binding generator); +- Python2.7 development environment (Provided by `python2.7-dev` on debian-based +distributions) + +If you want to *compile and run the tests* (`BUILD_TESTING=ON` by default), +you'll also need: + +- Catch (Provided by `catch` on debian-based distributions). Catch is a +single-header test framework - as such you may also download it directly +[here](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp); +- Python2.7 (Provided by `python2.7` on debian-based distribution - it is +preinstalled on most distributions). + +If you want to *build the code documentation* (`DOXYGEN=OFF` by default), you'll +need `doxygen` and `graphviz`. This doc is already available to you - see the +wiki. + +**To list all available configuration options, try** `cmake -L` (you may also +filter-out lines starting with `CMAKE_`). + +### How-To + +If you are already familiar with CMake, you know what to do. + Run `cmake .` then `make`. You may then install libraries, headers and binaries with `make install`. By default, they are installed under `/usr/local` on unix OSes; if you want to install them under a custom directory, you may do so by passing it to the `cmake .` command; e.g. + # Always use absolute paths in CMake "-D" options: you don't know where + # relative paths will be evaluated from. cmake -DCMAKE_INSTALL_PREFIX=/path/to/custom/install . +If you want to provide your own dependencies (e.g. your own version of +libxml2), you should pass the base paths as the `CMAKE_PREFIX_PATH` variable, +e.g.: + + cmake -DCMAKE_PREFIX_PATH='/path/to/dependency1/;/path/to/dependency2/' + +For more information on how to use `CMAKE_PREFIX_PATH`, see CMake's +documentation. + Also, CMake can build a project out-of-tree, which is the recommended method: mkdir /path/to/build/directory cd /path/to/build/directory - cmake /path/to/parameter-framework/sources + cmake /path/to/sources/of/parameter-framework make -After an install you may want to run the parameter-framework tests with -`make test`. +After a build you may want to run the parameter-framework tests with +`make test` or `ctest`. + +### Compiling on Windows + +The only supported compiler on Windows in Visual Studio 14 2015. The 2013 +version does not support some C++11 features. When running CMake's +configuration step (the first call to CMake) you must specify the build system +you want to use, i.e. `-G Visual Studio 14 2015 Win64`. Again, you may refer to +`appveyor.yml`. + +If you don't already have libxml2 headers/libraries and don't want to build them +by yourself, we have a precompiled version for x86-64. *These are provided for +reference and as a convenience for development purpose only; when making a +final product, you should recompile the latest libxml2 release yourself.* + +Compiled with Visual Studio 12 2013: +- [in debug configuration](https://01.org/sites/default/files/libxml2-x86_64-debug-3eaedba1b64180668fdab7ad2eba549586017bf3.zip) +- [in release configuration](https://01.org/sites/default/files/libxml2-x86_64-3eaedba1b64180668fdab7ad2eba549586017bf3.zip) + +We have mirrored ASIO 1.10.6 [here](https://01.org/sites/default/files/asio-1.10.6.tar.gz). + +Once you have downloaded and uncompressed these two dependencies, add the +following two entries to `CMAKE_PREFIX_PATH`: + + /path/to/libxml2-x86_64/ + /path/to/asio-1.10.6/ diff --git a/Schemas/Android.mk b/Schemas/Android.mk deleted file mode 100644 index 003bf3b..0000000 --- a/Schemas/Android.mk +++ /dev/null @@ -1,140 +0,0 @@ -# INTEL CONFIDENTIAL -# Copyright (c) 2014 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. - -LOCAL_PATH := $(call my-dir) - -# Resources are not compiled so the prebuild mechanism is used to export them. -# Schemas are only used by host, in order to validate xml files -################################################## - -include $(CLEAR_VARS) -LOCAL_MODULE := ParameterFrameworkConfiguration.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := ConfigurableDomain.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - ParameterSettings.xsd -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := ConfigurableDomains.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - ConfigurableDomain.xsd -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := SystemClass.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - FileIncluder.xsd \ - Subsystem.xsd -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := ParameterSettings.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := FileIncluder.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := Subsystem.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - ComponentLibrary.xsd -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := ComponentLibrary.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - ComponentTypeSet.xsd \ - W3cXmlAttributes.xsd -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := ComponentTypeSet.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - Parameter.xsd \ - W3cXmlAttributes.xsd -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := W3cXmlAttributes.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := Parameter.xsd -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS = ETC -LOCAL_MODULE_PATH := $(HOST_OUT)/etc/parameter-framework/Schemas -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) -################################################## diff --git a/SetVersion.cmake b/SetVersion.cmake new file mode 100644 index 0000000..3adeec1 --- /dev/null +++ b/SetVersion.cmake @@ -0,0 +1,78 @@ +# Copyright (c) 2016, 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. + +# Fallback values: +set(PF_VERSION_MAJOR 0) +set(PF_VERSION_MINOR 0) +set(PF_VERSION_PATCH 0) +set(PF_VERSION_TWEAK 0) +set(PF_VERSION_SHA1 "g0000000000") +set(PF_VERSION_DIRTY "") + +# Find and set the Parameter Framework's version +# First, let's see if the user forced a version (i.e. "vX.Y.Z-N") +if(NOT DEFINED PF_VERSION) + # Else, try to get it from git + execute_process(COMMAND git describe --tags --long --dirty --abbrev=12 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE PF_VERSION + RESULT_VARIABLE GIT_DESCRIBE_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + + if(GIT_DESCRIBE_RESULT GREATER 0) + # Or fall back to reading it from .version (this will happen when + # building from an archive) + file(READ "${PROJECT_SOURCE_DIR}/.version" PF_VERSION_FILE_CONTENT) + + set(REGEX "tag: (v[0-9.]+)") + if(PF_VERSION_FILE_CONTENT MATCHES ${REGEX}) + set(PF_VERSION "${CMAKE_MATCH_1}-0") + endif() + endif() +else() + # Set the "nice version string" to the one forced by the user + set(NICE_PF_VERSION "${PF_VERSION}") +endif() + +# Parse the version number to extract the various fields +set(REGEX "([0-9]+).([0-9]+).([0-9]+).([0-9]+)(-(g[0-9a-f]+)?)?(-(dirty)?)?") +if(PF_VERSION MATCHES ${REGEX}) + set(PF_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(PF_VERSION_MINOR ${CMAKE_MATCH_2}) + set(PF_VERSION_PATCH ${CMAKE_MATCH_3}) + set(PF_VERSION_TWEAK ${CMAKE_MATCH_4}) + set(PF_VERSION_SHA1 ${CMAKE_MATCH_6}) # Skip the 5th: it is a superset of the 6th + set(PF_VERSION_DIRTY ${CMAKE_MATCH_8}) # Skip the 7th: it is a superset of the 8th +endif() + +# If we are precisely on a tag, make a nicer version string (unless otherwise +# forced by the user - see above) +if((NOT DEFINED NICE_PF_VERSION) AND (PF_VERSION_TWEAK EQUAL 0) AND (NOT PF_VERSION_DIRTY)) + set(NICE_PF_VERSION "v${PF_VERSION_MAJOR}.${PF_VERSION_MINOR}.${PF_VERSION_PATCH}") +endif() diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..f1e38dc --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,97 @@ +version: 3.0.0-{build} + +# Only download the 50 first commits like travis to speedup clone +clone_depth: 50 + +os: Visual Studio 2015 + +init: + # Disable popups as they hang the build as there is nobody to click on the OK button... + # Hanging the build is a lot less user friendly than reporting a build failure. + # + # Disable of system hard error popup + # See: https://msdn.microsoft.com/en-us/library/bb513638%28VS.85%29.aspx + - reg add "HKLM\SYSTEM\CurrentControlSet\Control\Windows" /f /v ErrorMode /d 2 + # Disable the following popup on program failure: + # | ** <program name> has stopped working ** | + # | Windows can check online for a solution to the problem| + # | - Check online for a solution and close the program | + # | - Close the program | + # See: https://msdn.microsoft.com/en-us/library/bb513638%28VS.85%29.aspx + - reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting" /f /v DontShowUI /d 1 + + # Instruct cmake were to find external dependencies + - set PREFIX_PATH=%APPVEYOR_BUILD_FOLDER%\asio-1.10.6;%APPVEYOR_BUILD_FOLDER%\catch + # Tell CMake where to install + - set INSTALL=%HOMEPATH%\install + # legacy functional tests are bash specific + - set CTEST_PARAMS=--output-on-failure + +install: + - cinst cmake.portable wget 7zip.commandline + # Install Windows Installer XML (WiX) to create installer with cpack + - cinst wixtoolset + + # Download and install external dependancy if they are not in the cache + - if not exist libxml2-x86_64 ( + wget --no-check-certificate https://01.org/sites/default/files/libxml2-x86_64-3eaedba1b64180668fdab7ad2eba549586017bf3.zip && + 7z x libxml2-x86_64-3eaedba1b64180668fdab7ad2eba549586017bf3.zip) + - if not exist libxml2-x86_64-debug ( + wget --no-check-certificate https://01.org/sites/default/files/libxml2-x86_64-debug-3eaedba1b64180668fdab7ad2eba549586017bf3.zip && + 7z x libxml2-x86_64-debug-3eaedba1b64180668fdab7ad2eba549586017bf3.zip) + - if not exist asio-1.10.6 ( + wget --no-check-certificate https://01.org/sites/default/files/asio-1.10.6.tar.gz && + 7z x asio-1.10.6.tar.gz && + 7z x -i"!asio*/include" asio-1.10.6.tar) + # This version of catch is known to work. + - if not exist catch ( + wget --no-check-certificate https://raw.github.com/philsquared/Catch/v1.2.1/single_include/catch.hpp --directory-prefix catch ) + - set DEBUG_LIBXML2_PATH=%APPVEYOR_BUILD_FOLDER%\libxml2-x86_64-debug + - set RELEASE_LIBXML2_PATH=%APPVEYOR_BUILD_FOLDER%\libxml2-x86_64 + + # Setup Visual studio build environement + - '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64' + +cache: + - C:\ProgramData\chocolatey\bin -> appveyor.yml + - C:\ProgramData\chocolatey\lib -> appveyor.yml + - libxml2-x86_64 -> appveyor.yml + - libxml2-x86_64-debug -> appveyor.yml + - asio-1.10.6 -> appveyor.yml + - catch -> appveyor.yml + +build_script: + - mkdir build && cd build + + - mkdir 64bits-debug && cd 64bits-debug + # Add debug libxml2.dll in the path so that tests can find it + - set TEST_PATH=%DEBUG_LIBXML2_PATH%\bin + - cmake -G "NMake Makefiles" -DPYTHON_BINDINGS=OFF -DCMAKE_PREFIX_PATH="%PREFIX_PATH%;%DEBUG_LIBXML2_PATH%" ..\.. + - cmake --build . --config debug + - ctest --build-config debug %CTEST_PARAMS% + - cd .. + + - mkdir 64bits-release & cd 64bits-release + # Add debug libxml2.dll in the path so that tests can find it + - set TEST_PATH=%RELEASE_LIBXML2_PATH%\bin + - cmake -G "Visual Studio 14 2015 Win64" -DPYTHON_BINDINGS=OFF -DCMAKE_PREFIX_PATH="%PREFIX_PATH%;%RELEASE_LIBXML2_PATH%" -DCMAKE_INSTALL_PREFIX=%INSTALL% ..\.. + # Build, test and install + - cmake --build . --config release + - ctest --build-config release %CTEST_PARAMS% + - cmake --build . --config release --target install + - cpack --verbose -G WIX + - cd .. + + # build and test the skeleton plugin against the previously-installed build; this serves as a smoke test of the whole stack + - mkdir skeleton && cd skeleton + # %INSTALL%\lib is where the skeleton plugin is installed (see comment below) + # %INSTALL%\bin is where parameter.dll is installed + # Also add the path where the release libxml2.dll has been extracted + - set TEST_PATH=%RELEASE_LIBXML2_PATH%\bin;%INSTALL%\lib;%INSTALL%\bin + - cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_INSTALL_PREFIX=%INSTALL% -DCMAKE_PREFIX_PATH=%INSTALL% %APPVEYOR_BUILD_FOLDER%\skeleton-subsystem + # Unfortunately, the skeleton test currently doesn't work on + # multi-configuration build systems (Visual Studio is one of those) without + # installing the plugin + - cmake --build . --config release --target install + - ctest --build-config release %CTEST_PARAMS% + - cd .. diff --git a/asio/CMakeLists.txt b/asio/CMakeLists.txt new file mode 100644 index 0000000..9c0ef11 --- /dev/null +++ b/asio/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) 2016, 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. + +add_library(asio INTERFACE) + +if (NETWORKING) + # Find ASIO (the standalone version, not Boost) If asio isn't installed in + # a standard directory, add the correct directory to CMAKE_PREFIX_PATH (see + # the main README for more information). + find_path(ASIO_DIR NAMES asio.hpp) + # Hide this variable from CMake GUIs and `cmake -L` + set_property(CACHE ASIO_DIR PROPERTY ADVANCED TRUE) + if (NOT ASIO_DIR) + message(SEND_ERROR + " ASIO header (asio.hpp) could not be found. + ASIO is used for networking. On Linux, you should install it using your + package manager. On Windows, please refer to the main README.") + endif() + + # Ubuntu 14.04 packages asio 1.10.1 and clang 3.4.1. + # In this environment, asio stand alone (set ASIO_STANDALONE) + # does not correcly detect that the stl has CHRONO support (c++11). + # Force the use of std::chrono by setting ASIO_HAS_STD_CHRONO + target_include_directories(asio SYSTEM INTERFACE "${ASIO_DIR}") + target_link_libraries(asio INTERFACE "${CMAKE_THREAD_LIBS_INIT}") + target_compile_definitions(asio + INTERFACE ASIO_STANDALONE + INTERFACE ASIO_HAS_STD_CHRONO) +else() + # Stubbed version + target_include_directories(asio INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/stub") +endif() diff --git a/asio/stub/asio.hpp b/asio/stub/asio.hpp new file mode 100644 index 0000000..84a0ea4 --- /dev/null +++ b/asio/stub/asio.hpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016, 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. + */ +#pragma once + +/** @file + * + * Stubs ASIO interfaces called by libremote-processor. This is used when + * the user asks for networking support to be compiled out. + */ + +#include <system_error> + +namespace asio +{ +struct dummy_base +{ + template <class... Args> + dummy_base(Args &&...) + { + } + void set_option(const dummy_base &) const {}; +}; +inline bool write(const dummy_base &, const dummy_base &, const dummy_base &) +{ + return true; +} +inline bool read(const dummy_base &, const dummy_base &, const dummy_base &) +{ + return true; +} +using buffer = dummy_base; +struct io_service : dummy_base +{ + template <class... Args> + io_service(Args &&...) + { + throw std::runtime_error("Stub constructor called. Did you forget to set the " + "'TuningAllowed' attribute to 'false' in the Parameter " + "Framework's toplevel configuration file?"); + } + + void run(const dummy_base &) const {}; + void stop() const {}; +}; +struct socket_base : dummy_base +{ + using dummy_base::dummy_base; + + using linger = dummy_base; + using enable_connection_aborted = dummy_base; + void close() const {}; +}; + +bool write(const dummy_base &, const dummy_base &, const dummy_base &); +bool read(const dummy_base &, const dummy_base &, const dummy_base &); + +struct error_code : dummy_base, std::error_code +{ +}; +namespace error +{ +static const error_code eof{}; +} + +namespace ip +{ +namespace tcp +{ +using v6 = dummy_base; +using no_delay = dummy_base; +using socket = socket_base; +struct endpoint : dummy_base +{ + using dummy_base::dummy_base; + + dummy_base protocol() const { return {}; }; +}; +struct acceptor : dummy_base +{ + using dummy_base::dummy_base; + + using reuse_address = dummy_base; + void open(const dummy_base &) const {}; + void bind(const dummy_base &) const {}; + void listen() const {}; + void async_accept(const dummy_base &, const dummy_base &) const {}; +}; +} +} +} diff --git a/bindings/Android.mk b/bindings/Android.mk deleted file mode 100644 index f5f1064..0000000 --- a/bindings/Android.mk +++ /dev/null @@ -1,5 +0,0 @@ -# Recursive call sub-folder Android.mk -# - -include $(call all-subdir-makefiles) - diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index 446b52f..bdeab7f 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -26,12 +26,10 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -option(PYTHON_BINDINGS "Python library to use the pfw from python" ON) if(PYTHON_BINDINGS) add_subdirectory(python) endif() -option(C_BINDINGS "Python library to use the pfw from python" ON) if(C_BINDINGS) add_subdirectory(c) endif() diff --git a/bindings/c/CMakeLists.txt b/bindings/c/CMakeLists.txt index 3f00434..0c88412 100644 --- a/bindings/c/CMakeLists.txt +++ b/bindings/c/CMakeLists.txt @@ -28,37 +28,29 @@ add_library(cparameter SHARED ParameterFramework.cpp) -include_directories("${PROJECT_SOURCE_DIR}/parameter/include") +include(GenerateExportHeader) +generate_export_header(cparameter) install(FILES ParameterFramework.h + "${CMAKE_CURRENT_BINARY_DIR}/cparameter_export.h" DESTINATION "include/parameter/c") -target_link_libraries(cparameter parameter) +target_link_libraries(cparameter PRIVATE parameter pfw_utility) -install(TARGETS cparameter LIBRARY DESTINATION lib) +target_include_directories(cparameter + # Fixme use an include folder + PUBLIC . + # Export symbol macro header + PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") -if(BUILD_TESTING) - # Add catch unit test framework - # TODO Use gtest as it is the team recommendation - # Unfortunately gtest is very hard to setup as not binary distributed - # catch is only one header so it is very easy - # Catch can be downloaded from: - # https://raw.github.com/philsquared/Catch/master/single_include/catch.hpp - # Then append the download folder to the CMAKE_INCLUDE_PATH variable or - # copy it in a standard location (/usr/include on most linux distribution). - find_path(CATCH_HEADER catch.hpp) - include_directories(${CATCH_HEADER}) - include_directories("${PROJECT_SOURCE_DIR}/utility") +install(TARGETS cparameter LIBRARY DESTINATION lib RUNTIME DESTINATION bin) +if(BUILD_TESTING) # Add unit test add_executable(cparameterUnitTest Test.cpp) - # Do not warn about passing a null pointer for arguments marked as requiring - # a non-null value by the "nonnull" function attribute. - # This is done as the unit tests check that invalid api use result in - # proper failure. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nonnull") - target_link_libraries(cparameterUnitTest cparameter pfw_utility) + target_link_libraries(cparameterUnitTest PRIVATE catch cparameter tmpfile) + add_test(NAME cparameterUnitTest COMMAND cparameterUnitTest) diff --git a/bindings/c/ParameterFramework.cpp b/bindings/c/ParameterFramework.cpp index efc7d99..53f7a66 100644 --- a/bindings/c/ParameterFramework.cpp +++ b/bindings/c/ParameterFramework.cpp @@ -31,6 +31,8 @@ #include "ParameterFramework.h" #include <ParameterMgrPlatformConnector.h> +#include <NonCopyable.hpp> + #include <iostream> #include <limits> #include <string> @@ -45,9 +47,9 @@ 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; +typedef ISelectionCriterionInterface Criterion; +typedef std::map<string, Criterion *> Criteria; +typedef CParameterMgrPlatformConnector Pfw; } /** Class to abstract the boolean+string status api. */ @@ -57,16 +59,27 @@ 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; } + bool failure(const string &msg) + { + mMsg = msg; + return false; + } /** Success (no error message). */ - bool success() { mMsg.clear(); return true; } + bool success() + { + mMsg.clear(); + return true; + } /** Forward a status operation. - * @param success[in] the operaton status to forward + * @param[in] success the operaton status to forward * or forward a previous failure if omitted */ - bool forward(bool success = false) { - if (success) { mMsg.clear(); } + bool forward(bool success = false) + { + if (success) { + mMsg.clear(); + } return success; } /** Error message accessors. @@ -85,7 +98,8 @@ private: /////////////////////////////// /** Default log callback. Log to cout or cerr depending on level. */ -static void defaultLogCb(void *, PfwLogLevel level, const char *logLine) { +static void defaultLogCb(void *, PfwLogLevel level, const char *logLine) +{ switch (level) { case pfwLogInfo: std::cout << logLine << std::endl; @@ -96,7 +110,7 @@ static void defaultLogCb(void *, PfwLogLevel level, const char *logLine) { }; } -static PfwLogger defaultLogger = { NULL, &defaultLogCb }; +static PfwLogger defaultLogger = {NULL, &defaultLogCb}; class LogWrapper : public CParameterMgrPlatformConnector::ILogger { @@ -105,15 +119,18 @@ public: LogWrapper() : mLogger() {} virtual ~LogWrapper() {} private: - virtual void log(bool bIsWarning, const string &strLog) + void info(const string &msg) override { log(pfwLogInfo, msg); } + + void warning(const string &msg) override { log(pfwLogWarning, msg); } + + void log(PfwLogLevel level, 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()); + mLogger.logCb(mLogger.userCtx, level, strLog.c_str()); } + PfwLogger mLogger; }; @@ -121,22 +138,22 @@ private: ///////////// Core //////////// /////////////////////////////// -struct PfwHandler_ +struct PfwHandler_ : private utility::NonCopyable { void setLogger(const PfwLogger *logger); bool createCriteria(const PfwCriterion criteria[], size_t criterionNb); pfw::Criteria criteria; - pfw::Pfw *pfw; + pfw::Pfw *pfw = nullptr; /** 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(); @@ -144,9 +161,7 @@ PfwHandler *pfwCreate() void pfwDestroy(PfwHandler *handle) { - if(handle != NULL and handle->pfw != NULL) { - delete handle->pfw; - } + delete handle->pfw; delete handle; } @@ -159,7 +174,6 @@ void PfwHandler::setLogger(const PfwLogger *logger) pfw->setLogger(&mLogger); } - bool PfwHandler::createCriteria(const PfwCriterion criteriaArray[], size_t criterionNb) { Status &status = lastStatus; @@ -174,8 +188,7 @@ bool PfwHandler::createCriteria(const PfwCriterion criteriaArray[], size_t crite } // Check that the criterion does not exist if (criteria.find(criterion.name) != criteria.end()) { - return status.failure("Criterion \"" + string(criterion.name) + - "\" already exist"); + return status.failure("Criterion \"" + string(criterion.name) + "\" already exist"); } // Create criterion type @@ -187,18 +200,19 @@ bool PfwHandler::createCriteria(const PfwCriterion criteriaArray[], size_t crite int value; if (criterion.inclusive) { // Check that (int)1 << valueIndex would not overflow (UB) - if(std::numeric_limits<int>::max() >> valueIndex == 0) { + 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; + value = static_cast<int>(valueIndex); } - const char * valueName = criterion.values[valueIndex]; - if(not type->addValuePair(value, valueName)) { + const char *valueName = criterion.values[valueIndex]; + string error; + if (not type->addValuePair(value, valueName, error)) { return status.failure("Could not add value " + string(valueName) + - " to criterion " + criterion.name); + " to criterion " + criterion.name + ": " + error); } } // Create criterion and add it to the pfw @@ -207,27 +221,15 @@ bool PfwHandler::createCriteria(const PfwCriterion criteriaArray[], size_t crite return status.success(); } - -bool pfwStart(PfwHandler *handle, const char *configPath, - const PfwCriterion criteria[], size_t criterionNb, - const PfwLogger *logger) +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); @@ -242,11 +244,10 @@ bool pfwStart(PfwHandler *handle, const char *configPath, const char *pfwGetLastError(const PfwHandler *handle) { - return handle == NULL ? NULL : handle->lastStatus.msg().c_str(); + return handle->lastStatus.msg().c_str(); } -static pfw::Criterion *getCriterion(const pfw::Criteria &criteria, - const string &name) +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; @@ -254,12 +255,7 @@ static pfw::Criterion *getCriterion(const pfw::Criteria &criteria, 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."); @@ -273,20 +269,11 @@ bool pfwSetCriterion(PfwHandler *handle, const char name[], int value) } 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"); @@ -297,7 +284,6 @@ bool pfwGetCriterion(const PfwHandler *handle, const char name[], int *value) 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 " @@ -319,15 +305,11 @@ struct PfwParameterHandler_ 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) + "\")"); + "while trying to bind parameter \"" + + string(path) + "\")"); return NULL; } @@ -344,43 +326,30 @@ PfwParameterHandler *pfwBindParameter(PfwHandler *handle, const char path[]) 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[]) +bool pfwGetStringParameter(const PfwParameterHandler *handle, 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(); } + if (not success) { + return status.forward(); + } *value = strdup(retValue.c_str()); return status.success(); @@ -388,10 +357,11 @@ bool pfwGetStringParameter(const PfwParameterHandler *handle, const char *value[ 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); } - +void pfwFree(void *ptr) +{ + std::free(ptr); +} diff --git a/bindings/c/ParameterFramework.h b/bindings/c/ParameterFramework.h index 20cc820..c136845 100644 --- a/bindings/c/ParameterFramework.h +++ b/bindings/c/ParameterFramework.h @@ -28,13 +28,14 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** @file Simplified parameter framework C API. - * This API does not target a perfect one/one mapping with the c++ one, - * but rather aim ease of use and type safety (as far as possible in c). - * All function are reentrant and function call on a pfw (PfwHandle) - * does not impact any other pfw. - * Ie. There is no shared resources between pfw instances. - */ +/** @file + * + * Simplified parameter framework C API. This API does not target a perfect + * one/one mapping with the c++ one, but rather aim ease of use and type safety + * (as far as possible in c). All function are reentrant and function call on + * a pfw (PfwHandle) does not impact any other pfw. Ie. There is no shared + * resources between pfw instances. + */ #pragma once @@ -42,6 +43,8 @@ extern "C" { #endif +#include "cparameter_export.h" + #include <stdbool.h> #include <stdint.h> #include <stddef.h> @@ -49,9 +52,19 @@ extern "C" { /** Lots of function in this API require non null pointer parameter. * Such arguments are marked NONNULL. */ -#define NONNULL __attribute__((nonnull)) -#define NONNULL_(...) __attribute__((nonnull (__VA_ARGS__))) +#if defined(__clang__) || defined(__GNUC__) +#define NONNULL __attribute__((nonnull)) +#define NONNULL_(...) __attribute__((nonnull(__VA_ARGS__))) #define USERESULT __attribute__((warn_unused_result)) +#elif defined(_MSC_VER) +// In visual studio's cl there is no +// equivalent of nonnull +#define NONNULL +#define NONNULL_(...) +#define USERESULT _Check_return_ +#else +#error "Unknown compilator" +#endif /** Private handle to a parameter framework. * A PfwHandler* is valid if: @@ -77,16 +90,17 @@ typedef enum { } PfwLogLevel; /** Type of the parameter framework log callback. - * @param userCtx[in] Arbitrary context provided during callback registration. - * @param level[in] Log level of the log line. - * @param logLine[in] Log line (without end line control character like '\n') + * @param[in] userCtx Arbitrary context provided during callback registration. + * @param[in] level Log level of the log line. + * @param[in] logLine Log line (without end line control character like '\n') * to be logged. The pointer is invalidate after function * return or if any pfw function is called. */ typedef void PfwLogCb(void *userCtx, PfwLogLevel level, const char *logLine); /** Logger containing a callback method and its context. */ -typedef struct { +typedef struct +{ /** User defined arbitrary value that will be provided to all logCb call. */ void *userCtx; /** Callback that will be called. @@ -100,12 +114,18 @@ typedef struct { /////////////////////////////// /** Structure of a parameter framework criterion. */ -typedef struct { +typedef struct +{ /** Name of the criterion in the pfw configuration rules. */ const char *name; //< Must not be null. - bool inclusive; //< True if the criterion is inclusive, false if exclusive. + bool inclusive; //< True if the criterion is inclusive, false if exclusive. + /** Null terminated list of criterion value names. - * @example { "Red", "Green", "Blue", NULL } + * + * Example: + * @verbatim + * { "Red", "Green", "Blue", NULL } + * @endverbatim * * For an exclusive criterion, the list must not contain more elements then * INT_MAX. @@ -118,28 +138,29 @@ typedef struct { const char **values; //< Must not be null. } PfwCriterion; - /** Create a parameter framework instance. * Can not fail except for memory allocation. */ +CPARAMETER_EXPORT PfwHandler *pfwCreate() USERESULT; /** Destroy a parameter framework. Can not fail. */ +CPARAMETER_EXPORT void pfwDestroy(PfwHandler *handle) NONNULL; /** Start a parameter framework. - * @param handle[in] @see PfwHandler - * @param configPath[in] Path to the file containing the pfw configuration. - * @param criteria[in] An array of PfwCriterion. - * @param criterionNb[in] The number of PfwCriterion in criteria. - * @param logger[in] the logger to use for all operation. + * @param[in] handle @see PfwHandler + * @param[in] configPath Path to the file containing the pfw configuration. + * @param[in] criteria An array of PfwCriterion. + * @param[in] criterionNb The number of PfwCriterion in criteria. + * @param[in] logger the logger to use for all operation. * If NULL, log infos to standard output and * errors to standard error. * @return true on success, false on failure. */ -bool pfwStart(PfwHandler *handle, const char *configPath, - const PfwCriterion criteria[], size_t criterionNb, - const PfwLogger *loggger) NONNULL_(1, 2, 3) USERESULT; +CPARAMETER_EXPORT +bool pfwStart(PfwHandler *handle, const char *configPath, const PfwCriterion criteria[], + size_t criterionNb, const PfwLogger *logger) NONNULL_(1, 2, 3) USERESULT; /** @return a string describing the last call result. * If the last pfw function call succeeded, return an empty string. @@ -151,12 +172,13 @@ bool pfwStart(PfwHandler *handle, const char *configPath, * As a result, calling a pfw function with a NULL PfwHandler will result in a * failure WITHOUT updating the last error. */ +CPARAMETER_EXPORT const char *pfwGetLastError(const PfwHandler *handle) NONNULL; /** Set a criterion value given its name and value. - * @param handle[in] @see PfwHandler - * @param name[in] The name of the criterion that need to be changed. - * @param value If the criterion is exclusive, the index of the new value. + * @param[in] handle @see PfwHandler + * @param[in] name The name of the criterion that need to be changed. + * @param[in] value If the criterion is exclusive, the index of the new value. * If the criterion is inclusive, a bit field where each bit * correspond to the value index. * For an inclusive criterion defined as such: { "Red", "Green", "Blue", NULL } @@ -169,11 +191,14 @@ const char *pfwGetLastError(const PfwHandler *handle) NONNULL; * * @return true on success and false on failure. */ +CPARAMETER_EXPORT bool pfwSetCriterion(PfwHandler *handle, const char name[], int value) NONNULL USERESULT; /** Get a criterion value given its name. * Same usage as pfwSetCriterion except that value is an out param. - * Get criterion will return the last value setted with pfwSetCriterion independantly of pfwCommitCritenio. + * Get criterion will return the last value setted with pfwSetCriterion independantly of + * pfwCommitCritenio. */ +CPARAMETER_EXPORT bool pfwGetCriterion(const PfwHandler *handle, const char name[], int *value) NONNULL USERESULT; /** Commit criteria change and change parameters according to the configurations. @@ -182,9 +207,10 @@ bool pfwGetCriterion(const PfwHandler *handle, const char name[], int *value) NO * (who then impact parameter values according to the configuration) when * committed with this function. * - * @param handle[in] @see PfwHandler + * @param[in] handle @see PfwHandler * @return true on success and false on failure. */ +CPARAMETER_EXPORT bool pfwApplyConfigurations(const PfwHandler *handle) NONNULL USERESULT; /////////////////////////////// @@ -211,49 +237,56 @@ typedef struct PfwParameterHandler_ PfwParameterHandler; * @return a PfwParameterHandler on success, NULL on error. * @see pfwGetLastError for error detail. */ +CPARAMETER_EXPORT PfwParameterHandler *pfwBindParameter(PfwHandler *handle, const char path[]) NONNULL; /** Destroy a parameter handle. Can not fail. */ +CPARAMETER_EXPORT void pfwUnbindParameter(PfwParameterHandler *handle) NONNULL; /** Access the value of a previously bind int parameter. - * @param handle[in] Handler to a valid parameter. - * @param value[in] Non null pointer to an integer that will + * @param[in] handle Handler to a valid parameter. + * @param[in] value Non null pointer to an integer that will * hold the parameter value on success, undefined otherwise. * return true of success, false on failure. */ -bool pfwGetIntParameter(const PfwParameterHandler *handle, int32_t *value ) NONNULL USERESULT; +CPARAMETER_EXPORT +bool pfwGetIntParameter(const PfwParameterHandler *handle, int32_t *value) NONNULL USERESULT; /** Set the value of a previously bind int parameter. - * @param handle[in] Handler to a valid parameter. - * @param value[in] The parameter value to set. + * @param[in] handle Handler to a valid parameter. + * @param[in] value The parameter value to set. * return true of success, false on failure. */ +CPARAMETER_EXPORT bool pfwSetIntParameter(PfwParameterHandler *handle, int32_t value) NONNULL USERESULT; /** Access the value of a previously bind string parameter. - * @param handle[in] Handler to a valid parameter. - * @param value[out] Non null pointer on a string. + * @param[in] handle Handler to a valid parameter. + * @param[out] value Non null pointer on a string. * Will point on the parameter value string on success, * NULL on failure. * The callee MUST free the returned string using pfwFree after use. * @return true on success, false on failure. */ -bool pfwGetStringParameter(const PfwParameterHandler *handle, const char *value[]) NONNULL; +CPARAMETER_EXPORT +bool pfwGetStringParameter(const PfwParameterHandler *handle, char *value[]) NONNULL; /** Set the value of a previously bind string parameter. - * @param handle[in] Handler to a valid parameter - * @param value[in] Non null pointer to a null terminated string to set. + * @param[in] handle Handler to a valid parameter + * @param[in] value Non null pointer to a null terminated string to set. */ +CPARAMETER_EXPORT bool pfwSetStringParameter(PfwParameterHandler *handle, const char value[]) NONNULL USERESULT; /** Frees the memory space pointed to by ptr, * which must have been returned by a previous call to the pfw. * - * @param ptr[in] pointer to the memory to free. + * @param[in] ptr pointer to the memory to free. * @see man 3 free for usage. * @note Wrapper around the standard free to avoid problems * in case of a different pfw and client allocator. */ +CPARAMETER_EXPORT void pfwFree(void *ptr); #undef NONNULL diff --git a/bindings/c/Test.cpp b/bindings/c/Test.cpp index 8cbaa90..39f5df6 100644 --- a/bindings/c/Test.cpp +++ b/bindings/c/Test.cpp @@ -29,22 +29,20 @@ */ #include "ParameterFramework.h" -#include "FullIo.hpp" -#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() +#include "TmpFile.hpp" + +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() #include <catch.hpp> #include <string> #include <memory> #include <vector> +#include <array> #include <cstring> #include <cerrno> #include <climits> -extern "C" -{ -#include <unistd.h> -} struct Test { @@ -57,7 +55,7 @@ struct Test void REQUIRE_FAILURE(bool success) { - THEN("It should be an error") { + THEN ("It should be an error") { INFO("Previous pfw log: \n" + logLines); CAPTURE(pfwGetLastError(pfw)); CHECK(not success); @@ -67,7 +65,7 @@ struct Test void REQUIRE_SUCCESS(bool success) { - THEN("It should be a success") { + THEN ("It should be a success") { INFO("Previous pfw log: \n" + logLines); CAPTURE(pfwGetLastError(pfw)); CHECK(success); @@ -75,34 +73,27 @@ struct Test } } - /** Class to create a temporary file */ - class TmpFile + /** Wrap utility::TmpFile to add an implicit convertion to the temporary file. + * + * This avoids dozens of .getPath() in the following tests. */ + class TmpFile : private parameterFramework::utility::TmpFile { - public: - TmpFile(const std::string &content) { - char tmpName[] = "./tmpPfwUnitTestXXXXXX"; - mFd = mkstemp(tmpName); - CAPTURE(errno); - REQUIRE(mFd != -1); - mPath = tmpName; - REQUIRE(utility::fullWrite(mFd, content.c_str(), content.length())); - } - ~TmpFile() { - CHECK(close(mFd) != -1); - unlink(mPath.c_str()); - } - operator const char *() const { return mPath.c_str(); } - const std::string &path() const { return mPath; } private: - std::string mPath; - int mFd; + using Base = parameterFramework::utility::TmpFile; + + public: + using Base::TmpFile; + + using Base::getPath; + /** Implicitly convert to the path of the temporary file. */ + operator const char *() const { return getPath().c_str(); } }; /** Log in logLines. */ static void logCb(void *voidLogLines, PfwLogLevel level, const char *logLine) { std::string &logLines = *reinterpret_cast<std::string *>(voidLogLines); - switch(level) { + switch (level) { case pfwLogWarning: logLines += "Warning: "; break; @@ -118,25 +109,24 @@ struct Test /** Pfw handler used in the tests. */ PfwHandler *pfw; - }; -TEST_CASE_METHOD(Test, "Parameter-framework c api use") { +TEST_CASE_METHOD(Test, "Parameter-framework c api use") +{ // Create criteria const char *letterList[] = {"a", "b", "c", NULL}; const char *numberList[] = {"1", "2", "3", NULL}; const PfwCriterion criteria[] = { - {"inclusiveCrit", true, letterList}, - {"exclusiveCrit", false, numberList}, + {"inclusiveCrit", true, letterList}, {"exclusiveCrit", false, numberList}, }; - size_t criterionNb = sizeof(criteria)/sizeof(criteria[0]); + size_t criterionNb = sizeof(criteria) / sizeof(criteria[0]); PfwLogger logger = {&logLines, logCb}; // Create valid pfw config file const char *intParameterPath = "/test/system/integer"; const char *stringParameterPath = "/test/system/string"; TmpFile system("<?xml version='1.0' encoding='UTF-8'?>\ - <Subsystem Name='system' Type='Virtual' Endianness='Little'>\ + <Subsystem Name='system' Type='Virtual'>\ <ComponentLibrary/>\ <InstanceDefinition>\ <IntegerParameter Name='integer' Size='32' Signed='true' Max='100'/>\ @@ -145,70 +135,61 @@ TEST_CASE_METHOD(Test, "Parameter-framework c api use") { </Subsystem>"); TmpFile libraries("<?xml version='1.0' encoding='UTF-8'?>\ <SystemClass Name='test'>\ - <SubsystemInclude Path='" + system.path() + "'/>\ + <SubsystemInclude Path='" + + system.getPath() + "'/>\ </SystemClass>"); TmpFile config("<?xml version='1.0' encoding='UTF-8'?>\ <ParameterFrameworkConfiguration\ SystemClassName='test' TuningAllowed='false'>\ <SubsystemPlugins/>\ - <StructureDescriptionFileLocation Path='" + libraries.path() + "'/>\ + <StructureDescriptionFileLocation Path='" + + libraries.getPath() + "'/>\ </ParameterFrameworkConfiguration>"); - GIVEN("A created parameter framework") { + GIVEN ("A created parameter framework") { pfw = pfwCreate(); REQUIRE(pfw != NULL); - THEN("Error message should be empty") { + THEN ("Error message should be empty") { CHECK(empty(pfwGetLastError(pfw))); } - WHEN("The pfw is started without an handler") { - CHECK(not pfwStart(NULL, config, criteria, criterionNb, &logger)); - } - WHEN("The pfw is started without a config path") { - REQUIRE_FAILURE(pfwStart(pfw, NULL, criteria, criterionNb, &logger)); - } - WHEN("The pfw is started without an existent file") { + WHEN ("The pfw is started without an existent file") { REQUIRE_FAILURE(pfwStart(pfw, "/doNotExist", criteria, criterionNb, &logger)); } - WHEN("The pfw is started without a criteria list") { - REQUIRE_FAILURE(pfwStart(pfw, config, NULL, criterionNb, &logger)); - } - WHEN("The pfw is started with duplicated criterion value") { + WHEN ("The pfw is started with duplicated criterion value") { const PfwCriterion duplicatedCriteria[] = { - {"duplicated name", true, letterList}, - {"duplicated name", false, numberList}, + {"duplicated name", true, letterList}, {"duplicated name", false, numberList}, }; REQUIRE_FAILURE(pfwStart(pfw, config, duplicatedCriteria, 2, &logger)); } - WHEN("The pfw is started with duplicated criterion value state") { - const char * values[] = {"a", "a", NULL}; + WHEN ("The pfw is started with duplicated criterion value state") { + const char *values[] = {"a", "a", NULL}; const PfwCriterion duplicatedCriteria[] = {{"name", true, values}}; - WHEN("Using test logger") { + WHEN ("Using test logger") { REQUIRE_FAILURE(pfwStart(pfw, config, duplicatedCriteria, 1, &logger)); } - WHEN("Using default logger") { + WHEN ("Using default logger") { // Test coverage of default logger warning REQUIRE_FAILURE(pfwStart(pfw, config, duplicatedCriteria, 1, NULL)); } } - WHEN("The pfw is started with NULL name criterion") { + WHEN ("The pfw is started with NULL name criterion") { const PfwCriterion duplicatedCriteria[] = {{NULL, true, letterList}}; REQUIRE_FAILURE(pfwStart(pfw, config, duplicatedCriteria, 1, &logger)); } - WHEN("The pfw is started with NULL criterion state list") { + WHEN ("The pfw is started with NULL criterion state list") { const PfwCriterion duplicatedCriteria[] = {{"name", true, NULL}}; REQUIRE_FAILURE(pfwStart(pfw, config, duplicatedCriteria, 1, &logger)); } - GIVEN("A criteria with lots of values") - { + GIVEN ("A criteria with lots of values") { // Build a criterion with as many value as there is bits in int. std::vector<char> names(sizeof(int) * CHAR_BIT + 1, 'a'); names.back() = '\0'; std::vector<const char *> values(names.size()); - for(size_t i = 0; i < values.size(); ++i) { + for (size_t i = 0; i < values.size(); ++i) { values[i] = &names[i]; } values.back() = NULL; @@ -240,66 +221,56 @@ TEST_CASE_METHOD(Test, "Parameter-framework c api use") { */ const PfwCriterion duplicatedCriteria[] = {{"name", true, &values[0]}}; - WHEN("The pfw is started with a too long criterion state list") { + WHEN ("The pfw is started with a too long criterion state list") { REQUIRE_FAILURE(pfwStart(pfw, config, duplicatedCriteria, 1, &logger)); } - WHEN("The pfw is started with max length criterion state list") { + WHEN ("The pfw is started with max length criterion state list") { values[values.size() - 2] = NULL; // Hide last value REQUIRE_SUCCESS(pfwStart(pfw, config, duplicatedCriteria, 1, &logger)); } } - WHEN("The pfw is started with zero criteria") { + WHEN ("The pfw is started with zero criteria") { REQUIRE_SUCCESS(pfwStart(pfw, config, criteria, 0, &logger)); } - WHEN("The pfw is started twice a pfw") { + WHEN ("The pfw is started twice a pfw") { REQUIRE_SUCCESS(pfwStart(pfw, config, criteria, criterionNb, &logger)); REQUIRE_FAILURE(pfwStart(pfw, config, criteria, criterionNb, &logger)); } - WHEN("The pfw is started without a logger callback") { - PfwLogger noLog = { NULL, NULL }; + WHEN ("The pfw is started without a logger callback") { + PfwLogger noLog = {NULL, NULL}; REQUIRE_SUCCESS(pfwStart(pfw, config, criteria, criterionNb, &noLog)); } - WHEN("The pfw is started with default logger") { + WHEN ("The pfw is started with default logger") { REQUIRE_SUCCESS(pfwStart(pfw, config, criteria, criterionNb, NULL)); } - WHEN("Get criterion of a stopped pfw") { + WHEN ("Get criterion of a stopped pfw") { int value; REQUIRE_FAILURE(pfwGetCriterion(pfw, criteria[0].name, &value)); } - WHEN("Set criterion of a stopped pfw") { + WHEN ("Set criterion of a stopped pfw") { REQUIRE_FAILURE(pfwSetCriterion(pfw, criteria[0].name, 1)); } - WHEN("Commit criteria of a stopped pfw") { + WHEN ("Commit criteria of a stopped pfw") { REQUIRE_FAILURE(pfwApplyConfigurations(pfw)); } - WHEN("Bind parameter with a stopped pfw") { + WHEN ("Bind parameter with a stopped pfw") { REQUIRE(pfwBindParameter(pfw, intParameterPath) == NULL); } - WHEN("The pfw is started correctly") - { + WHEN ("The pfw is started correctly") { REQUIRE_SUCCESS(pfwStart(pfw, config, criteria, criterionNb, &logger)); int value; - WHEN("Get criterion without an handle") { - REQUIRE(not pfwGetCriterion(NULL, criteria[0].name, &value)); - } - WHEN("Get criterion without a name") { - REQUIRE_FAILURE(pfwGetCriterion(pfw, NULL, &value)); - } - WHEN("Get criterion without an output value") { - REQUIRE_FAILURE(pfwGetCriterion(pfw, criteria[0].name, NULL)); - } - WHEN("Get not existing criterion") { + WHEN ("Get not existing criterion") { REQUIRE_FAILURE(pfwGetCriterion(pfw, "Do not exist", &value)); } - THEN("All criterion should value 0") { - for(size_t i = 0; i < criterionNb; ++i) { + THEN ("All criterion should value 0") { + for (size_t i = 0; i < criterionNb; ++i) { const char *criterionName = criteria[i].name; CAPTURE(criterionName); REQUIRE_SUCCESS(pfwGetCriterion(pfw, criterionName, &value)); @@ -307,69 +278,53 @@ TEST_CASE_METHOD(Test, "Parameter-framework c api use") { } } - WHEN("Set criterion without an handle") { - REQUIRE(not pfwSetCriterion(NULL, criteria[0].name, 1)); - } - WHEN("Set criterion without a name") { - REQUIRE_FAILURE(pfwSetCriterion(pfw, NULL, 2)); - } - WHEN("Set not existing criterion") { + WHEN ("Set not existing criterion") { REQUIRE_FAILURE(pfwSetCriterion(pfw, "Do not exist", 3)); } - WHEN("Set criterion value") { - for(size_t i = 0; i < criterionNb; ++i) { + WHEN ("Set criterion value") { + for (size_t i = 0; i < criterionNb; ++i) { const char *criterionName = criteria[i].name; CAPTURE(criterionName); REQUIRE_SUCCESS(pfwSetCriterion(pfw, criterionName, 3)); } - THEN("Get criterion value should return what was set") { - for(size_t i = 0; i < criterionNb; ++i) { + THEN ("Get criterion value should return what was set") { + for (size_t i = 0; i < criterionNb; ++i) { const char *criterionName = criteria[i].name; CAPTURE(criterionName); REQUIRE_SUCCESS(pfwGetCriterion(pfw, criterionName, &value)); REQUIRE(value == 3); } } + WHEN ("Set a new value to a criterion without committing first") { + const char *criterionName = criteria[0].name; + REQUIRE_SUCCESS(pfwSetCriterion(pfw, criterionName, 0)); + THEN ("A warning message should have been displayed") { + INFO("Previous pfw log: \n" + logLines); + size_t logPos = logLines.find("Warning: Selection criterion " + "'inclusiveCrit' has been modified 1 time(s)" + " without any configuration application"); + CHECK(logPos != std::string::npos); + } + } } - WHEN("Commit criteria without a pfw") { - REQUIRE(not pfwApplyConfigurations(NULL)); - } - WHEN("Commit criteria of a started pfw") { + WHEN ("Commit criteria of a started pfw") { REQUIRE_SUCCESS(pfwApplyConfigurations(pfw)); } - - WHEN("Bind parameter without a pfw") { - REQUIRE(pfwBindParameter(NULL, intParameterPath) == NULL); - } - WHEN("Bind parameter without a path") { - REQUIRE_FAILURE(pfwBindParameter(pfw, NULL) != NULL); - } - WHEN("Bind a non existing parameter") { + WHEN ("Bind a non existing parameter") { REQUIRE_FAILURE(pfwBindParameter(pfw, "do/not/exist") != NULL); } - WHEN("Set an int parameter without a parameter handle") { - REQUIRE(not pfwSetIntParameter(NULL, value)); - } - WHEN("Get an int parameter without a parameter handle") { - REQUIRE(not pfwGetIntParameter(NULL, &value)); - } - - GIVEN("An integer parameter handle") { + GIVEN ("An integer parameter handle") { PfwParameterHandler *param = pfwBindParameter(pfw, intParameterPath); REQUIRE_SUCCESS(param != NULL); - WHEN("Get an int parameter without an output value") { - REQUIRE_FAILURE(pfwGetIntParameter(param, NULL)); - } - - WHEN("Set parameter out of range") { + WHEN ("Set parameter out of range") { REQUIRE_FAILURE(pfwSetIntParameter(param, 101)); } - WHEN("Set parameter") { + WHEN ("Set parameter") { REQUIRE_SUCCESS(pfwSetIntParameter(param, 11)); - THEN("Get parameter should return what was set") { + THEN ("Get parameter should return what was set") { REQUIRE_SUCCESS(pfwGetIntParameter(param, &value)); REQUIRE(value == 11); } @@ -378,25 +333,21 @@ TEST_CASE_METHOD(Test, "Parameter-framework c api use") { pfwUnbindParameter(param); } - GIVEN("An string parameter handle") { + GIVEN ("An string parameter handle") { PfwParameterHandler *param = pfwBindParameter(pfw, stringParameterPath); REQUIRE_SUCCESS(param != NULL); - WHEN("Get an int parameter without an output value") { - REQUIRE_FAILURE(pfwGetStringParameter(param, NULL)); - } - - WHEN("Set parameter out of range") { + WHEN ("Set parameter out of range") { REQUIRE_FAILURE(pfwSetStringParameter(param, "ko_1234567")); } - WHEN("Set parameter") { - const char *value; + WHEN ("Set parameter") { + char *value; REQUIRE_SUCCESS(pfwSetStringParameter(param, "ok")); - THEN("Get parameter should return what was set") { + THEN ("Get parameter should return what was set") { REQUIRE_SUCCESS(pfwGetStringParameter(param, &value)); REQUIRE(value == std::string("ok")); - pfwFree((void *)value); + pfwFree(value); } } @@ -407,9 +358,3 @@ TEST_CASE_METHOD(Test, "Parameter-framework c api use") { pfwDestroy(pfw); } } - -SCENARIO("Get last error without a pfw") { - THEN("Should return NULL") { - CHECK(pfwGetLastError(NULL) == NULL); - } -} diff --git a/bindings/python/Android.mk b/bindings/python/Android.mk deleted file mode 100644 index b4b6277..0000000 --- a/bindings/python/Android.mk +++ /dev/null @@ -1,110 +0,0 @@ -# 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. - -LOCAL_PATH := $(call my-dir) - -# Low-level python wrapper -include $(CLEAR_VARS) -# When importing a python module from a shared library, the name of the lib has -# to be exactly the same as the module name it contains. SWIG generates a -# python module called "PyPfw" that relies on the one that we are building as a -# shared library here, and that is named "_PyPfw" -# See https://docs.python.org/2/extending/extending.html#the-module-s-method-table-and-initialization-function -LOCAL_MODULE := _PyPfw - -LOCAL_CPP_EXTENSION := .cxx -# Android only provides a 32bit version of python. -LOCAL_32_BIT_ONLY := true - -LOCAL_SHARED_LIBRARIES := libxmlserializer_host libparameter_host - -# python is only available in 32bits for now, thus arch is forced to 32bits -PYTHON_INSTALL_PATH := prebuilts/python/$(HOST_OS)-x86/2.7.5/ -PYTHON_INCLUDES_PATH := $(PYTHON_INSTALL_PATH)/include/python2.7 -PYTHON_BIN_PATH := $(PYTHON_INSTALL_PATH)/bin - -LOCAL_C_INCLUDES := \ - $(PYTHON_INCLUDES_PATH) \ - $(HOST_OUT_HEADERS)/parameter - -# '-DSWIG_PYTHON_SILENT_MEMLEAK' is needed because the "memleak" warning -# pollutes the standard output. At the time of writing, the only warning is -# spurious anyway, as it relates to "ILogger *" which is an abstract -# class/interface class and as such cannot be destroyed. -LOCAL_CFLAGS := -fexceptions -DSWIG_PYTHON_SILENT_MEMLEAK - -# Undefined symbols will be resolved at runtime -LOCAL_ALLOW_UNDEFINED_SYMBOLS := true - -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_OWNER := intel - -LOCAL_MODULE_CLASS := SHARED_LIBRARIES -LOCAL_IS_HOST_MODULE := true - -generated-sources-dir := $(call local-generated-sources-dir) - -LOCAL_GENERATED_SOURCES := $(generated-sources-dir)/pfw_wrap.cxx $(generated-sources-dir)/pfw_wrap.h - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(generated-sources-dir) - -# Get the interpreter ld options. -ifeq ($(HOST_OS), darwin) - # Contrary to linux, on darwin, a python 64 bit executable is installed - # in the x86 prebuild directory, - # As all host libraries are 32 bit in android. We can not link and host - # python module against the prebuild python library. - # - # As a *dirty* workaround, use the system's python configuration and hope - # it will be compatible with the prebuild python interpreter used at runtime. - # To summarize the prebuild python (64 bit?) interpreter will load a - # python native module (32bit) linked with the host (32 bit ?) python library. - LOCAL_LDLIBS += $(shell python-config --ldflags) -else - # Careful, we need to invoke the android python config not the host's one. - # Unfortunately, the internal install directory of python is hardcoded to a dummy value, - # As a workaround, we need to manually add the correct path to libs to the library list. - LOCAL_LDLIBS += $(shell $(PYTHON_BIN_PATH)/python $(PYTHON_BIN_PATH)/python-config --ldflags) \ - -L $(PYTHON_INSTALL_PATH)/lib/ -endif - -$(generated-sources-dir)/pfw_wrap.h: $(generated-sources-dir)/pfw_wrap.cxx - -# The PyPfw.py file is generated in the directory given by -outdir switch, thus -# this directory must be put in the python path to be reachable -$(generated-sources-dir)/pfw_wrap.cxx: $(LOCAL_PATH)/pfw.i - @echo "Generating Python binding files" - mkdir -p $(dir $@) # surprisingly, path is not generated by build system - mkdir -p $(HOST_LIBRARY_PATH) - prebuilts/misc/$(HOST_OS)-$(HOST_ARCH)/swig/swig \ - -Iprebuilts/misc/common/swig/include/2.0.11/python/ \ - -Iprebuilts/misc/common/swig/include/2.0.11/ \ - -Wall -Werror -v -python -c++ -outdir $(HOST_LIBRARY_PATH)/ -o $@ $^ - -include $(BUILD_HOST_SHARED_LIBRARY) - diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 5663301..5807633 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -26,7 +26,20 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -find_package(SWIG REQUIRED) +find_package(SWIG) +# Hide these variables from CMake GUIs and `cmake -L` +set_property(CACHE + SWIG_DIR SWIG_EXECUTABLE SWIG_VERSION + PROPERTY ADVANCED TRUE) +if(NOT SWIG_FOUND) + message(FATAL_ERROR + "Swig is needed to compile the Python bindings but was not found." + "Please either install swig2.0 or disable Python bindings by setting" + "PYTHON_BINDINGS to OFF (e.g. '-DPYTHON_BINDINGS=OFF' in the" + "invocation of CMake.). See the 'Compilation' section of README.md" + "for more details.") +endif() + include(${SWIG_USE_FILE}) # Force usage of Python 2.7.x ... @@ -36,21 +49,22 @@ find_package(PythonInterp 2.7 REQUIRED) find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS}) -include_directories(${PROJECT_SOURCE_DIR}/parameter/include) - set_property(SOURCE pfw.i PROPERTY CPLUSPLUS ON) -set_property(SOURCE pfw.i PROPERTY SWIG_FLAGS "-Wall" "-Werror") +set_property(SOURCE pfw.i PROPERTY SWIG_FLAGS "-Wall") +if(FATAL_WARNINGS) + set_property(SOURCE pfw.i APPEND PROPERTY SWIG_FLAGS "-Werror") +endif() swig_add_module(PyPfw python pfw.i) swig_link_libraries(PyPfw parameter ${PYTHON_LIBRARIES}) # For convenience, the global library output directory -# (CMAKE_LIBRARY_OUTPUT_DIRECTORY) is set to ${CMAKE_BINARY_DIR}/lib, so that +# (CMAKE_LIBRARY_OUTPUT_DIRECTORY) is set to ${PROJECT_BINARY_DIR}/lib, so that # all libs are generated in the same folder. This help writing test targets # (add_test) that do not need "make install" to be run. # However, putting _PyPfw.so in that folder defeats the purpose described # above because when running tests using the python bindings, the PYTHONPATH # needs to contain both _PyPfw.so and PyPfw.py. Without the line below, -# _PyPfw.so would be put in ${CMAKE_BINARY_DIR}/lib while PyPfw.py is put in +# _PyPfw.so would be put in ${PROJECT_BINARY_DIR}/lib while PyPfw.py is put in # ${CMAKE_CURRENT_BINARY_DIR}. set_property(TARGET _PyPfw PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) @@ -59,8 +73,10 @@ set_property(TARGET _PyPfw PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BIN # spurious anyway, as it relates to "ILogger *" which is an abstract # class/interface class and as such cannot be destroyed. # -Wno-error is set to prevent compilation failure in case of the code -# generated by swig generates warnings -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSWIG_PYTHON_SILENT_MEMLEAK -Wno-error") +# generated by swig generates warnings. We don't apply the FATAL_WARNING policy +# here, since we consider this generated code as external. +target_compile_definitions(_PyPfw PRIVATE SWIG_PYTHON_SILENT_MEMLEAK) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error") # Find the python modules install path. diff --git a/bindings/python/pfw.i b/bindings/python/pfw.i index bf1330b..a1bfe62 100644 --- a/bindings/python/pfw.i +++ b/bindings/python/pfw.i @@ -91,14 +91,16 @@ public: bool getForceNoRemoteInterface() const; void setForceNoRemoteInterface(bool bForceNoRemoteInterface); - void setFailureOnMissingSubsystem(bool bFail); + bool setFailureOnMissingSubsystem(bool bFail, std::string& strError); bool getFailureOnMissingSubsystem() const; - void setFailureOnFailedSettingsLoad(bool bFail); - bool getFailureOnFailedSettingsLoad(); + bool setFailureOnFailedSettingsLoad(bool bFail, std::string& strError); + bool getFailureOnFailedSettingsLoad() const; - void setSchemaFolderLocation(const std::string& strSchemaFolderLocation); - void setValidateSchemasOnStart(bool bValidate); + void setSchemaUri(const std::string& schemaUri); + const std::string& getSchemaUri() const; + + bool setValidateSchemasOnStart(bool bValidate, std::string &strError); bool getValidateSchemasOnStart() const; // Tuning mode @@ -180,11 +182,16 @@ public: // CParameterMgrFullConnector // Logger interface %feature("director") ILogger; -%nestedworkaround CParameterMgrFullConnector::ILogger; +// The nested workaround is used to tell swig to ignore the +// inner class definition that would be redundant with the fake outer class. +// It would have been useful if ParameterMgrFullConnector.h was included +// (as opposed to copying the class definition in this .i). +// As their is no conflicting ILogger definition, this workaround is useless. class ILogger { public: - virtual void log(bool bIsWarning, const std::string& strLog) = 0; + virtual void info(const std::string& log) = 0; + virtual void warning(const std::string& log) = 0; protected: virtual ~ILogger() {} }; @@ -199,7 +206,7 @@ class ISelectionCriterionTypeInterface %} public: - virtual bool addValuePair(int iValue, const std::string& strValue) = 0; + virtual bool addValuePair(int iValue, const std::string& strValue, std::string& strError) = 0; virtual bool getNumericalValue(const std::string& strValue, int& iValue) const = 0; virtual bool getLiteralValue(int iValue, std::string& strValue) const = 0; virtual bool isTypeInclusive() const = 0; diff --git a/bindings/python/sample.py b/bindings/python/sample.py index 1208fc9..7e8ece6 100755 --- a/bindings/python/sample.py +++ b/bindings/python/sample.py @@ -37,9 +37,10 @@ class MyLogger(PyPfw.ILogger): # won't be recognised as a derived class of PyPfw.ILogger super(MyLogger, self).__init__() - def log(self, is_warning, log): - log_func = logging.warning if is_warning else logging.info - log_func(log) + def info(self, msg): + logging.info(msg) + def warning(self, msg): + logging.warning(msg) logging.root.setLevel(logging.INFO) @@ -59,6 +60,6 @@ mood = pfw.createSelectionCriterion("Mood", moodType) ok, error = pfw.start() if not ok: - print("Error while starting the pfw: {}".format(error)) + print("Error while starting the pfw: '{}'".format(error)) raw_input("[Press enter to exit]") diff --git a/cmake/FindLibXml2.cmake b/cmake/FindLibXml2.cmake new file mode 100644 index 0000000..ccd0b4b --- /dev/null +++ b/cmake/FindLibXml2.cmake @@ -0,0 +1,56 @@ +# 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. + +# Wrapper around the official FindLibXml2.cmake in order to provide imported targets. +# This has the advantage of propagating Transitive Usage Requirements to consumers. +# See: https://cmake.org/cmake/help/git-master/manual/cmake-developer.7.html#find-modules +# See: https://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/FindGLUT.cmake +# for a modern Find<package>.cmake example +# TODO: make a real FindLibXml2.cmake in order to upstream it. + +# More info on how to write Find*.cmake on: +# https://cmake.org/cmake/help/git-master/manual/cmake-developer.7.html#find-modules + +# Remove this directory from CMAKE_MODULE_PATH for the call to the original FindLibXml2.cmake +set(CMAKE_MODULE_PATH_BACKUP "${CMAKE_MODULE_PATH}") +list(REMOVE_ITEM CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") +find_package(LibXml2) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH_BACKUP}") +unset(CMAKE_MODULE_PATH_BACKUP) + +add_library(LibXml2::libxml2 UNKNOWN IMPORTED) + +set_target_properties(LibXml2::libxml2 PROPERTIES + IMPORTED_LOCATION "${LIBXML2_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${LIBXML2_LIBRARIES}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_COMPILE_DEFINITIONS "${LIBXML2_DEFINITIONS}") + +# Do not call find_package_handle_standard_args as this has already been done +# in find_package(LibXml2) diff --git a/test/test-platform/Android.mk b/cpack/CMakeLists.txt index eca285a..516ce4d 100644 --- a/test/test-platform/Android.mk +++ b/cpack/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2011-2014, Intel Corporation +# Copyright (c) 2014-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,63 +26,32 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +set(CPACK_PACKAGE_VERSION + "${PF_VERSION_MAJOR}.${PF_VERSION_MINOR}.${PF_VERSION_PATCH}.${PF_VERSION_TWEAK}") -LOCAL_PATH:= $(call my-dir) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Plugin-based and rule-based framework for describing and controlling parameters.") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") +set(CPACK_PACKAGE_FILE_README "${PROJECT_SOURCE_DIR}/README.md") +set(CPACK_PACKAGE_VENDOR "Intel") +set(CPACK_PACKAGE_CONTACT "parameter-framework@lists.01.org") +set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING.txt") +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://01.org/parameter-framework") -#################### -# Common definitions +# Arbitrary GUID needed by the installer on windows to abort +# if it detects a pre-existing installation that uses the same GUID. +set(CPACK_WIX_PRODUCT_GUID "5CB589A1-8AE6-4CD2-AF46-15272B93B462") -common_src_files := \ - main.cpp \ - TestPlatform.cpp +# Arbitrary GUID needed by the installer on windows to replace +# existing installations that use the same GUID. +set(CPACK_WIX_UPGRADE_GUID "47E60D10-B344-445D-A2F6-5684CC8B1D47") -common_module := test-platform -common_module_tags := optional +if (WIN32) + # On windows, pack compiler provided libraries (MSVC redistributable) with the project + include(InstallRequiredSystemLibraries) + # TODO: pack libxml2.dll with the project +endif() -common_c_includes := \ - $(LOCAL_PATH)/../../parameter/include \ - $(LOCAL_PATH)/../../remote-processor/ +# Use dpkg-shlibdeps (debian generator only) to generate better package dependency list. +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) -common_shared_libraries := libparameter libremote-processor -############################# -# Target build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= $(common_src_files) - -LOCAL_MODULE:= $(common_module) -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_C_INCLUDES := $(common_c_includes) - -LOCAL_STATIC_LIBRARIES := libpfw_utility -LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) - -ifeq ($(INCLUDE_STLPORT), true) -include external/stlport/libstlport.mk -endif - -include $(BUILD_EXECUTABLE) - -############################## -# Host build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= $(common_src_files) - -LOCAL_MODULE:= $(common_module)_host -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_C_INCLUDES += $(common_c_includes) -LOCAL_CFLAGS := -pthread -LOCAL_LDLIBS := -lpthread - -LOCAL_STATIC_LIBRARIES := libpfw_utility_host -LOCAL_SHARED_LIBRARIES := $(foreach shared_library, $(common_shared_libraries), \ - $(shared_library)_host) - -include $(BUILD_HOST_EXECUTABLE) +include(CPack) diff --git a/ctest/CMakeLists.txt b/ctest/CMakeLists.txt index bc74a93..d56c9a1 100644 --- a/ctest/CMakeLists.txt +++ b/ctest/CMakeLists.txt @@ -45,14 +45,51 @@ set(MEMORYCHECK_COMMAND_OPTIONS include(CTest) # Ctest requires its configuration to be placed at the build root -configure_file(${CMAKE_CURRENT_LIST_DIR}/CTestCustom.cmake ${CMAKE_BINARY_DIR} COPYONLY) +configure_file(${CMAKE_CURRENT_LIST_DIR}/CTestCustom.cmake ${PROJECT_BINARY_DIR} COPYONLY) # Set environement variables so that executables and libraries can be find by tests. # (avoids a make install before make test) function(set_test_env TestName) + # A cmake PROPERTY value is just a string. + # The ENVIRONMENT PROPERTY is implemented as a semicolon separated + # list of value pair. Each value pair being separated by `=` + # Eg: the python env equivalent of `{"A":"1", "B":"/;/bin"}` is `A=1;B=/\;/bin` + # + # As a consequences cmake can not differentiate between a `;` that separates + # two environment variable and a `;` contained in a variable. + # + # Thus all `;` in environment variables must be escaped + # before inserting them in the ENVIRONMENT PROPERTY. + string(REPLACE ";" "\\;" TEST_PATH "$ENV{PATH};$ENV{TEST_PATH}") + string(REPLACE ";" "\\;" TEST_LD_LIBRARY_PATH "$ENV{LD_LIBRARY_PATH}") + string(REPLACE ";" "\\;" TEST_PYTHONPATH "$ENV{PYTHONPATH}") + + if(WIN32) + set(SEP "\\;") + else() + set(SEP ":") + endif() + + + # With nmake and nmake, executables are build in: + # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} => `bin/` + # + # Nevertheless Visual studio (and xcode) can build for debug and release + # from the same build tree. As a result those multi-configuration + # build systems build executables in: + # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIGURATION> => + # - `bin/Debug` for debug + # - `bin/Release` for release. + # + # In order to support both build system types add + # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} *and* ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIGURATION> + # in the path. + # + # Note: Quotes are necessary. Otherwise `;` escapes are discarded + # TODO: when cmake 3 will be used, split long lines with trailing backslash set_property(TEST ${TestName} PROPERTY ENVIRONMENT - PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}:$ENV{PATH} - LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}:$ENV{LD_LIBRARY_PATH} - PYTHONPATH=${CMAKE_BINARY_DIR}/bindings/python:$ENV{PYTHONPATH}) + "PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}${SEP}${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIGURATION>${SEP}${TEST_PATH}" + "LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}${SEP}${TEST_LD_LIBRARY_PATH}" + "PYTHONPATH=${PROJECT_BINARY_DIR}/bindings/python${SEP}${TEST_PYTHONPATH}") endfunction() diff --git a/ctest/CTestCustom.cmake b/ctest/CTestCustom.cmake index c0381a4..0c0aa72 100644 --- a/ctest/CTestCustom.cmake +++ b/ctest/CTestCustom.cmake @@ -3,5 +3,6 @@ SET(CTEST_CUSTOM_MEMCHECK_IGNORE # Python generates too many valgrind errors, # runing python based tests would be long and useless. fix_point_parameter - functional-test + functional-test-legacy + xml-generator ) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 06804bd..b6e1108 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -26,12 +26,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -option(DOXYGEN - "Enable doxygen generation (you still have to run 'make doc')" - OFF) - -include(CMakeDependentOption) # Only present DOXYGEN_GRAPHS if DOXYGEN is ON and if so, default to ON. # Else, set to OFF. cmake_dependent_option(DOXYGEN_GRAPHS @@ -58,3 +52,5 @@ if(DOXYGEN) COMMENT "Generating documentation with Doxygen" VERBATIM) endif() + +add_subdirectory(requirements) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 34b80a5..33499b8 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1,4 +1,4 @@ -# Doxyfile 1.8.7 +# Doxyfile 1.8.9.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -38,7 +38,7 @@ PROJECT_NAME = "parameter-framework" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = @PARAMETER_FRAMEWORK_VERSION@ +PROJECT_NUMBER = @NICE_PF_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -46,10 +46,10 @@ PROJECT_NUMBER = @PARAMETER_FRAMEWORK_VERSION@ PROJECT_BRIEF = "Plugin-based and rule-based framework for describing and controlling parameters" -# With the PROJECT_LOGO tag one can specify an logo or icon that is included in -# the documentation. The maximum height of the logo should not exceed 55 pixels -# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo -# to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = @@ -60,7 +60,7 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = doxygen -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where @@ -93,14 +93,14 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -135,7 +135,7 @@ ALWAYS_DETAILED_SEC = YES INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -205,9 +205,9 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a -# new page for each member. If set to NO, the documentation of a member will be -# part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO @@ -276,7 +276,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # -# Note For files without extension you can use no_extension as a placeholder. +# Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. @@ -295,8 +295,8 @@ MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES @@ -336,7 +336,7 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. @@ -401,7 +401,7 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -411,35 +411,35 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local methods, +# This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO only methods in the interface are +# included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. @@ -464,21 +464,21 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set -# to NO these classes will be included in the various overviews. This option has -# no effect if EXTRACT_ALL is enabled. +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO these declarations will be +# (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO these +# documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -492,7 +492,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES upper-case letters are also +# names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. @@ -501,12 +501,19 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES the +# their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -534,14 +541,14 @@ INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. Note that +# name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. @@ -586,27 +593,25 @@ SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the -# todo list. This list is created by putting \todo commands in the -# documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the -# test list. This list is created by putting \test commands in the -# documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. @@ -631,8 +636,8 @@ ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES the list -# will mention the files that were used to generate the documentation. +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES @@ -680,8 +685,7 @@ LAYOUT_FILE = # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. +# search path. See also \cite for info how to create references. CITE_BIB_FILES = @@ -697,7 +701,7 @@ CITE_BIB_FILES = QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -705,7 +709,7 @@ QUIET = NO WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. @@ -722,8 +726,8 @@ WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO doxygen will only warn about wrong or incomplete parameter -# documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO @@ -754,15 +758,16 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = @PROJECT_SOURCE_DIR@ \ - @PROJECT_SOURCE_DIR@/bindings \ +INPUT = @PROJECT_SOURCE_DIR@/README.md \ + @PROJECT_SOURCE_DIR@/bindings/c \ @PROJECT_SOURCE_DIR@/parameter \ + @PROJECT_SOURCE_DIR@/parameter/include \ @PROJECT_SOURCE_DIR@/remote-process \ @PROJECT_SOURCE_DIR@/remote-processor \ - @PROJECT_SOURCE_DIR@/Schemas + @PROJECT_SOURCE_DIR@/schemas \ @PROJECT_SOURCE_DIR@/test/test-platform \ @PROJECT_SOURCE_DIR@/utility \ - @PROJECT_SOURCE_DIR@/xmlserializer \ + @PROJECT_SOURCE_DIR@/xmlserializer # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -788,7 +793,7 @@ FILE_PATTERNS = # be searched for input files as well. # The default value is: NO. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -824,7 +829,7 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = details # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include @@ -879,7 +884,7 @@ INPUT_FILTER = FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER ) will also be used to filter the input files that are used for +# INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. @@ -939,7 +944,7 @@ REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. @@ -986,6 +991,28 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# compiled with the --with-libclang option. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = -std=c++11 \ + -I @PROJECT_BINARY_DIR@/parameter \ + -I @PROJECT_BINARY_DIR@/remote-processor \ + -I @PROJECT_BINARY_DIR@/bindings/c + #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1016,7 +1043,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES @@ -1078,13 +1105,15 @@ HTML_FOOTER = HTML_STYLESHEET = -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1100,7 +1129,7 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the stylesheet and background images according to +# will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 @@ -1131,8 +1160,9 @@ HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO @@ -1228,28 +1258,28 @@ GENERATE_HTMLHELP = NO CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# The GENERATE_CHI flag controls if a separate .chi index file is generated ( -# YES) or that it should be included in the master .chm file ( NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1363,7 +1393,7 @@ DISABLE_INDEX = NO # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has @@ -1391,7 +1421,7 @@ ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1420,7 +1450,7 @@ FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. @@ -1506,7 +1536,7 @@ SERVER_BASED_SEARCH = NO # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # @@ -1519,7 +1549,7 @@ EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. @@ -1557,7 +1587,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1588,7 +1618,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1622,23 +1652,36 @@ EXTRA_PACKAGES = # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or @@ -1656,8 +1699,8 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1702,7 +1745,7 @@ LATEX_BIB_STYLE = plain # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -1717,7 +1760,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1754,11 +1797,21 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -1802,7 +1855,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -1816,7 +1869,7 @@ GENERATE_XML = NO XML_OUTPUT = xml -# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -1829,7 +1882,7 @@ XML_PROGRAMLISTING = YES # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -1843,14 +1896,23 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen -# Definitions (see http://autogen.sf.net) file that captures the structure of -# the code including all documentation. Note that this feature is still -# experimental and incomplete at the moment. +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -1859,7 +1921,7 @@ GENERATE_AUTOGEN_DEF = NO # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -1867,7 +1929,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -1875,9 +1937,9 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO the +# understand what is going on. On the other hand, if this tag is set to NO, the # size of the Perl module output will be much smaller and Perl will parse it # just the same. # The default value is: YES. @@ -1897,14 +1959,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names -# in the source code. If set to NO only conditional compilation will be +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. @@ -1920,7 +1982,7 @@ MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1996,20 +2058,21 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external class will be listed in the -# class index. If set to NO only the inherited external classes will be listed. +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. # The default value is: NO. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in -# the modules index. If set to NO, only the current project's groups will be +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. EXTERNAL_GROUPS = YES -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. @@ -2026,7 +2089,7 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more @@ -2051,7 +2114,7 @@ MSCGEN_PATH = DIA_PATH = -# If set to YES, the inheritance and collaboration graphs will hide inheritance +# If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2076,7 +2139,7 @@ HAVE_DOT = @DOXYGEN_DOT_FOUND@ DOT_NUM_THREADS = 0 -# When you want a differently looking font n the dot files that doxygen +# When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by @@ -2124,7 +2187,7 @@ COLLABORATION_GRAPH = NO GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2259,6 +2322,19 @@ MSCFILE_DIRS = DIAFILE_DIRS = +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized @@ -2295,7 +2371,7 @@ MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support # this, this feature is disabled by default. @@ -2312,7 +2388,7 @@ DOT_MULTI_TARGETS = YES GENERATE_LEGEND = NO -# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. diff --git a/doc/requirements/APIs.md b/doc/requirements/APIs.md new file mode 100644 index 0000000..a49e2a6 --- /dev/null +++ b/doc/requirements/APIs.md @@ -0,0 +1,240 @@ +<article class="markdown-body"> + +Link from APIs to requirements +============================== + +# `ParameterMgrPlatformConnector` + +This class is the main client interface. + +See +<http://01org.github.io/parameter-framework/doc/classCParameterMgrPlatformConnector.html> +for the complete documentation of each API. + +## `createSelectionCriterionType` and `createSelectionCriterion` + +Implement the **Selection Criterion** creation requirements. See section **5.4** +of the requirements documentation. + +## `getSelectionCriterion` + +There is no requirement to retreive a criterion by it's name. + +## `setLogger` + +Implement [req-post-mortem-debug]. + +Implements a way for the user to provide a log backend. +This is not a requirentment currently. +Maybe it is a miss? + +## `start` and `isStarted` + +**???** + +There is no "two-step-creation" requirement. This is an implementation detail. + +## `applyConfigurations` + +Deffered application requirement; see [req-multiple-criterion-change-atomicity] +See also the Selection Criterion APIs below. + +## `createParameterHandle` + +Introspection and direct parameter read/write access; +see [req-introspection] especialy the point about parameter properties. +See also the Parameter Handle APIs below. + +## `setForceNoRemoteInterface` and `getForceNoRemoteInterface` + +Tuning capability activation control; see section [req-disabling] in [req-tuning]. + +## `setFailureOnMissingSubsystem` and `getFailureOnMissingSubsystem` + +**???** + +Currently only used for XML generation. There is no requirement associated. + +## `setFailureOnFailedSettingsLoad` and `getFailureOnFailedSettingsLoad` + +**???** + +Currently only used for XML generaton. There is no requirement associated. + +## `setSchemaUri` and `getSchemaUri`; `setValidateSchemasOnStart` and `getValidateSchemasOnStart` + +**???** + +Currently only used for XML generation. There is no requirement associated. + +# `ParameterMgrFullConnector` + +This is another client interface that covers the same purposes and APIs than +`ParameterMgrPlatformConnector` and extands them. See this class' description. +Added APIs are described in this chapter. + +## `setTuningMode` and `isTuningModeOn` + +Tuning capability activation control; see section [req-parameter-overwriting]. +It adds another level of flexibility over `setForceNoRemoteInterface`. +The semantic of these two APIs overlap but **neither one fully contains the other**. + +**TODO**: fix the semantics. + +## `setValueSpace` and `isValueSpaceRaw`; `setOutputRawFormat` and `isOutputRawFormatHex` + +Serialization control (FIXME: what about deserialization ?). Seems **UNUSED**. +There is no requirement associated. + +## `setAutoSync`, `isAutoSyncOn` and `sync` + +Synchronization on client request; see section [req-explicit-sync]. + +## `accessParameterValue` + +Parameter value direct access. **This overlaps with ParameterHandle.** +Implements the same requirement: [req-parameter-overwriting] + +## `getParameterMapping` + +Part of the Introspection requirements. See [req-introspection] especialy implement +intropsepction of the mapped syncer. + +## Tuning APIs + +All of the following APIs implement the Tuning requirement; see section [req-tuning] + +- `accessConfigurationValue` + +- `createDomain` +- `deleteDomain` +- `renameDomain` +- `deleteAllDomains` + +- `setSequenceAwareness` +- `getSequenceAwareness` +- `setElementSequence` + +- `createConfiguration` +- `deleteConfiguration` +- `renameConfiguration` +- `restoreConfiguration` +- `saveConfiguration` + +- `addConfigurableElementToDomain` +- `removeConfigurableElementFromDomain` +- `split` + +- `setApplicationRule` +- `getApplicationRule` +- `clearApplicationRule` + +## Persistance APIs + +### `exportDomainsXml` + +Exports the "Domains" (aka "Settings") which is the inference engine's data. +See section [req-serializable]. + +### `importDomainsXml` + +Imports previously-exported data into the inference engine. See [req-deserializable]. + +### `exportSingleDomainXml` + +Exports a given part of the inference engine data. See [Serialization of individual data]. + +### `importSingleDomainXml` + +Imports a partial inference engine data as previously exported. See section +[req-deserialization-of-individual-data]. + +# `ISelectionCriterionTypeInterface` + +Implementation detail of the criterion requirement [req-selection-criterion]. + +## `addValuePair` + +Implementation of [req-criterion-changes]. + +## `getNumericalValue` + +Implementation of [req-criterion-changes]. + +## `getLiteralValue` + +Implementation of [req-criterion-changes]. + +## `isTypeInclusive` + +Get how the criterion possible states were specified, +see [req-state-domain-specification] + +## `getFormattedState` + +Pretty print criterion state [req-pretty-print] + +# `ISelectionCriterionInterface` + +## `setCriterionState` and `getCriterionState` + +Allow Introspection of a criterion; see [req-introspection]. +## `getCriterionName` + +Allow Introspection of a criterion; see [req-introspection]. + +## `getCriterionType` + +Allow Introspection of a criterion; see [req-introspection]. + +# `CParameterHandle` + +This class implements the requirements related to direct read/write access to +parameters. + +## `isRogue` + +Relative to setting rogue parameters; see section [req-introspection]. + +## `isArray` + +Allow Introspection of a parameter metadata; see [req-introspection]. + +## `getArrayLength` + +Allow Introspection of a parameter metadata; see [req-introspection]. + +## `getPath` and `getKind` + +Allow Introspection of a parameter identifier; see [req-introspection]. + +## Setters and getters + +The following APIs allow reading/writing parameters. +Implements [req-introspection] and [req-parameter-overwriting] + +- `setAsBoolean` +- `getAsBoolean` +- `setAsBooleanArray` +- `getAsBooleanArray` +- +- `setAsInteger` +- `getAsInteger` +- `setAsIntegerArray` +- `getAsIntegerArray` +- `setAsSignedInteger` +- `getAsSignedInteger` +- `setAsSignedIntegerArray` +- `getAsSignedIntegerArray` +- +- `setAsDouble` +- `getAsDouble` +- `setAsDoubleArray` +- `getAsDoubleArray` +- +- `setAsString` +- `getAsString` +- `setAsStringArray` +- `getAsStringArray` + +</article> diff --git a/doc/requirements/CMakeLists.txt b/doc/requirements/CMakeLists.txt new file mode 100644 index 0000000..1d8f596 --- /dev/null +++ b/doc/requirements/CMakeLists.txt @@ -0,0 +1,59 @@ +# 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. + +if(REQUIREMENTS) + find_program(PANDOC pandoc) + + if(NOT PANDOC) + message(SEND_ERROR + "'pandoc' executable has not been found." + " Please install it to be able to generate the html version of" + " the 'requirements' documentation.") + endif() + + configure_file(requirements.css + ${CMAKE_CURRENT_BINARY_DIR}/requirements.css + COPYONLY) + + set(REQ_OUT_DOC ${CMAKE_CURRENT_BINARY_DIR}/index.html) + + add_custom_target(requirements-doc DEPENDS ${REQ_OUT_DOC}) + + add_custom_command(OUTPUT ${REQ_OUT_DOC} + DEPENDS requirements.md requirements.css + VERBATIM COMMAND + ${PANDOC} --output ${REQ_OUT_DOC} + --from markdown --to html5 + --number-sections --table-of-contents + --smart # typographic dashes + --variable "pagetitle:Parameter Framework Requirements" + --id-prefix req- # avoid tag name conflicts + --css requirements.css # this path is relative to the html doc + --css http://sindresorhus.com/github-markdown-css/github-markdown.css + ${CMAKE_CURRENT_SOURCE_DIR}/requirements.md) +endif() diff --git a/doc/requirements/requirements.css b/doc/requirements/requirements.css new file mode 100644 index 0000000..77c4e71 --- /dev/null +++ b/doc/requirements/requirements.css @@ -0,0 +1,52 @@ +.title { + text-align: center; + font-weight: bold; + font-size: 2.5em; + line-height: 1.3; + color: #4078C0; +} + +.markdown-body { + min-width: 200px; + max-width: 920px; + margin: 0 auto; + padding: 30px; +} + +note::before,ko::before { + content: "Note: "; + font-style: normal; +} + +why::before, unknown:before { + content: "Why: "; + font-style: normal; +} + +ko::before, unknown:before { + color: red; +} + +note, ko, why, unknown { + font-style: italic; + display: block; + color: grey; +} + +#req-TOC { + display: block; + float: left; + height: 100%; + padding: 5px; + + overflow: hidden; + font-family: "Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif; + font-size: 14px; + line-height: 1.5; + word-wrap: break-word; +} + +nav>ul { + list-style: none; + padding-left: 0; +} diff --git a/doc/requirements/requirements.md b/doc/requirements/requirements.md new file mode 100644 index 0000000..fd57e16 --- /dev/null +++ b/doc/requirements/requirements.md @@ -0,0 +1,1110 @@ +% Parameter Framework \ +High level requirements + +<!-- +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. +--> + +<article class="markdown-body"> + +<note>Some requirements are only motivated by the fact that the reference +implementation implements them. Search for "reference implementation".</note> + +# Introduction + +The Parameter Framework is abreviated as PF in the rest of the document. + +## Philosophy + +The Parameter Framework aims to be a hardware control abstraction layer. +Specificaly the PF contains 3 stacked abstraction layers: + + 1) hardware api abstraction + 2) hardware parameter abstraction + 3) high level hardware independent abstraction + +The fundamental constraint on the underlined hardware is to be representable +by independent parameters. Ie: When changing one parameter it must not change +an other. + +### Hardware api abstraction +The goal of this layer is to abstract the apis of the underline hardwares. +Each abstracted hardware usualy have different apis, this layer responsibility +is to set and get parameters using the underlined native api. + +See the [syncer] chapter. +<!--Fixme why are pandoc auto references not working ? --> + +### Hardware parameter abstraction +The goal if this layer is to name and organize and describing +the hardware parameter properties (domain of validity, size, human representation...). + +See the "Parameters" chapter. + +### High level hardware independent abstraction +The goal of this layer is to abstract the hardware parameters behind abstract parameters +(called criterion in the reference implementation). + +This is done by linking those abstract parameters and the hardware parameters with +arbitrary rules. + +See the "Rule based dynamic abstraction". + +## Requirements + +### Reusability +The PF **SHOULD** be reusable between components. +<why>To be reused in different components.</why> + +### Instances independence +PF instances **MUST NOT** mutate each others. +<note>This may be implemented by not sharing any mutable data between PF instances.</note> +<why>Different PF instances are expected to be completely independent thus accessing one should not impact any others.</why> + +# Parameters + +<note>TODO: add a paragraph/requirement about parameter independences. +Ie parameter set order should not impact the final state. +Need to find justification for this. Maybe it is only a convention? +Maybe it is a consequences of the domains ?</note> + + +## Definitions + +<dl> +<dt>Parameter</dt> +<dd>TODO</dd> +<dt>Hardware</dt> +<dd>System controlled by the PF. Not necessary material system. This term was +chosen because: + + - historically the PF reference implementation was used to abstract hardware + - the subsystem term would arguably fit best is already used. + +(FIXME: choose "subsystem" instead of "hardware" ?) +</dd> +</dl> + +## Requirements +A PF **MUST** be able to handle parameters. +<why>because the PF aims to abstract hardware and model it by parameters.</why> + +## Value + +A parameter **MUST** have a value. +<why>because a parameter without value would not abstract any hardware.</why> + +### Mutability +A PF **MUST** support mutable parameters. +<why>To control the underlined hardware.</why> + +### Set ability +This value **MUST** be settable for a mutable parameter. +<why>By definition, a mutable parameter that can not be mutated it a immutable parameter.</why> + +### Get ability +This value **SHOULD** be gettable for a mutable parameter. +<why>To dump all parameter value, debug a hardware state, +save parameters values, display the current hardware state, +for coherency with the immutable parameter...</why> + +### Data type + +#### Definition + +<dl> +<dt>Data type</dt> +<dd> +All parameters have a data type. A data type designates parameter invariants. + +A data type is the meaning of the data and the way values of that type can be +stored. +</dd> +</dl> + + +#### Philosophy + +A data type defines the value properties: + + - memory layout + - value constrains + +A value type is mostly used to: + + - pretty display parameter values (not just a as an array of bits) + - check for user error when setting it (out of bound, invalid...) + - offer a type safe API + +#### Requirements + +##### Supported types +A PF **SHOULD** support the following types. +If a type is chosen to be supported, it **MUST** respect all MUST clause, +**SHOULD** respect all SHOULD clause, **MAY** respect all MAY clause of the type. +<why>All type are not necessary to use the PF. For example any parameter could +be represented as an array of char (string). But this would not permit to +check parameter validity (invariants) nor a pretty display of the values.</why> + +##### Typed API +Implementation **MAY** add another API to access a parameter value. +<why>For example a C++ implementation may give access to a string as an +std::string object.</why> + +##### Integers + +###### Signed and unsigned support +PF **SHOULD** support signed and unsigned integer parameters +<why>The reference implementation supports it.</why> + +###### Size immutability +PF **MUST** support integer with invariant size. +<why>It is common in C API to expect numbers to have a fixed maximum size.</why> + +###### ABI +The API to access it **MUST** respect C integer ABI. +<why>For easy access from C code.</why> + +###### Supported size +Supported integer size **SHOULD** be at least 8, 16 and 32 bits. +<why>The reference implementation supports it.</why> + +###### Min max support +PF **MAY** support constraining the parameter minimum and maximum value. +<why>To catch user out of valid range errors when changing the parameter +value.</why> + +##### String +###### Support +PF **SHOULD** support array of characters. +<why>Everything that a computer can store fits in an array of characters. It can +be used as a fallback type if no other matches the parameter.</why> + +###### String max size +The array maximum size **MAY** be invariant (immutable). +<unknown>This is what the reference implementation does.</unknown> + +###### API +The API to access the string value **SHOULD** support null terminated character +array. As it is commonly done in C. +<why>For easy access from C code.</why> + +##### Fix point parameter + +###### Support +PF **SHOULD** support fix point parameters. I.e. integers divided by a fixed power +of two. +<unknown>The reference implementation supports it.</unknown> + +###### API +The API to access the values **SHOULD** respect the Qm.n and UQm.n standards. +<why>It is the main standard for fix point parameters.</why> + +###### Size +PF **SHOULD** support at least `0 <= m + n <= 31` for a Signed Qm.n and +`0 <= m + n <= 32` for an Unsigned Qm.n (or "UQm.n"). +<unknown>The reference implementation supports it.</unknown> +<ko>The reference implementation only supports Signed Qn.m</ko> + +###### Min and max support +PF **MAY** support constraining the parameter minimum and maximum value. +<why>To catch user out of valid range errors when changing the parameter +value.</why> +<unknown>The reference implementation does not support it</unknown> + +##### Floating point +###### Support +PF **SHOULD** support floating point parameters . +<unknown>The reference implementation supports it.</unknown> + +###### API +The API to access the values **SHOULD** respect C platform float abi. +<note>Usually the IEEE 754 standard.</note> + +###### Size +PF **SHOULD** support at least 32 and 64 bit size floats. +<why>The reference implementation supports it.</why> +<unknown>The reference implementation only supports 32bits</unknown> + +###### Min and max support +PF **MAY** support constraining the parameter minimum and maximum value. +<why>To catch user out of valid range errors when changing the parameter +value.</why> + +##### Bit field + +###### Support +PF **SHOULD** support 1 or more bit sized integers. +<unknown>The reference implementation supports it.</unknown> + +###### Single bit access API +The API to access a bit parameter is implementation defined. +<why>C has no way to point to a single (or more) bits. Thus there is no </why> + +###### Bit field access API +Such bit parameters **SHOULD** be grouped in a bit field. +A bit field is an ordered set of bit parameter. +The API to access a bit filed **SHOULD** give access to a packed bit +field following the C abi. +<note>This bit field may contain only bit parameter.</note> +<why>To offer a C compatible api to fit field.</why> + + +### Parameter adaptation + +#### Definition +<dl> +<dt>Parameter adaptation<dt> +<dd> +A bijective pure function converting a parameter value between the syncer +and other parameter reader/writer (including the inference engine). + +The adaptation function maps the syncer and client space. It: + + - scales the user value to the hardware value (client => syncer) + - converts the hardware value to the user's value space. (syncer => client) + +<why>For coherency a client getting a previously set parameter should return the setted value, +thus the transformation must be bijective. +</why> +</dd> +</dl> + +#### Philosophy + +Parameters exposed by hardware sometimes need to be normalized. +<note>For example a hardware integer parameter could have a range 64-128 but it might +be necessary for upper layer to access in a range 0-100.</note>\ + +This transformation can also permits to change the unit of a parameter. +<note>For example the hardware could expose a parameter in cm but it might better +to expose it in mm. </note>\ + +Parameters types offer a way to abstract underlined implementation. +<note>For example a Q2,2 (see [fix-point-parameter]) when setting 1 +will be translated to 0100. </note>\ + +With parameter adaptation, types can be even further parameterised. +<note>For example, Qn,m Fix point parameter could be emulated with a $*2^n$ +adaptation over an n + m integer. </note>\ + +Parameter adaptation could be implemented by the syncer. +Nevertheless syncers are supposed to contain only +business logic and should not be impacted by upper layer needs. + +#### Requirements + +##### Support +The following parameter adaptation **SHOULD** be supported + + - Affine adaptation: `affAd(value) = slope * value + offset` where slope and + offset and user-defined constants + <unknown>The reference implementation supports it.</unknown> + + - Logarithm adaptation: `logAd(base, value) = ln(value) / ln(base)` where + `ln` is the natural logarithm and base is a user-defined constant. + <unknown>The reference application supports it.</unknown> + <note>The reference implementation also supports passing a floor value to be + applied after conversion.</note> + +##### Composition +A PF **MAY** offer Parameter adaptation composition. I.e. combine multiple parameter +adaptation +<note>E.g.: composing the affine and logarithm adaptation to +`compAd(value) = slope * logAd(base, value) + offset`.</note> +<why>To avoid combination explosion of parameter adaptations. The idea is to +builtin basic function and let the user compose them to meet its need.</why> +<ko>The reference application supports in a tricky way: the logarithm +adaptation is always combined with the affine adaptation</ko> + +### Parameter tree +A parameter **SHOULD** be structured in a tree. Each parameter being a distinct +tree leaf. +<why>Tree is a simple data structure that can be easily represented and is +enough to map underlined layers.</why> + +#### Identifier +Each node of the tree **SHOULD** have its own identifier with the same +characteristics (type, independence...) than a parameter. +<why>To represent the tree without treating the leaf nodes specifically.</why> + + +# Syncer + +## Philosophy + +The PF philosophy is to map the hardware characteristics to parameters. +In order to impact the hardware when parameters are modified, a hardware specific +code must be used. + +Syncers are responsible for synchronizing the values of parameters to the underlined hardware. +Ie, it is the glue between hardware and parameters. It contains the code specific +to access an hardware. + +The aim of the PF is to keep this hardware specific code as light as possible. + +## Definition + +<dl> +<dt>Syncer<dt> +<dd> +Entity that keeps synchronised PF parameters and their associated hardware. +</dd> +</dl> + +## Requirements + +### Mapping +A syncer **MUST** be mapped to one or more parameters. +<why>The hardware minimal access may be bigger than one parameter.</why> + +### Uniqueness +One parameter **MUST NOT** be mapped to two or more syncer. +Ie: a parameter MUST be mapped to zero or one syncer. +<why>Which syncer should be responsible to retrieve the initial parameter value +if they are multiple per parameter?</why> + +### Read hardware +A syncer **MUST** support retrieving the mapped parameters value from the mapped +hardware. +<why>to retrieve a parameter value at the start of the PF.</why> + +#### Write hardware +A syncer **MUST** support setting the mapped parameters value to the mapped +hardware. +<why>to synchronise hardware on parameter change.</why> + +#### API +This API **MAY** be a packed parameter structure, following the C ABI without +padding. +<note>This is what the reference implementation does.</note> +<unknown>TODO</unknown> + +## Parameter introspection +The syncer API **SHOULD** allow introspection of the mapped parameters. +<why>the parameter structure may be useful for the syncer to communicate with +the hardware. For example a syncer might need each to know each associated +parameter type to send it to the hardware.</why> + +## Plugins + + - This formation is object oriented. Requirements should not require any programing paradigm. + - Is this section about syncer creation and builders too close to implementation ? + +### Definition +The PF creates syncer using syncer builder. + +### Requirements +The PF **MUST** be able to create syncers. +<why>To bind on the corresponding parameters.</why> + +### Identifier + +#### Syncer library +All syncers mapping to the same hardware **SHOULD** have their builders regrouped +in a syncer library. +<note>FIXME: + + - Is this syncer library concept not a definition ? Ie a syncer builder set. + - The concept is needed by other requirement but it does not stand by itself. + - Why is there a requirement of "same hardware" ? + Is this not more a convention than a requirement ? + +</note> +<why>To be able to link a group of parameters and a given hardware. +For example all parameters that are mapped to sound card should be linked to a +sound card syncer library. (Each parameter are then individually mapped to a specific syncer.) +</why> + +#### Syncer ID +A syncer builder **MUST** have a unique identifier in its containing syncer +library. +<why>To uniquely identify the syncer that should bind on parameters. Given that +the syncer library has already been specified.</why> + +#### Library UID +A syncer library **MUST** have a unique identifier in the host system. +<why>To identify the library associated to parameters.</why> + +### Loading + +#### DLL +Syncer library or/and builder **MAY** be loaded from dynamically linked libraries +(called syncer plugins). +<unknown>The reference implementation supports it.</unknown> + +#### Plugin entry point +Such syncer plugins **SHOULD** have an unique entry point that -- when called -- +should register its payload (syncer library/builder) in the provided gatherer. +<note>This permit to merge multiple syncer libraries in one shared +library.</note> +<unknown>The reference implementation supports it.</unknown> + +#### Plugin interdependancies +Multiple syncer plugins, may depend on each other. The PF should appropriately +handle the case and not fail. +<unknown>The reference implementation supports it.</unknown> + +## Mapping +### Definition + +<dl> +<dt>Virtual Parameter</dt> +<dd> +A parameter not bound to a syncer. +(Todo: remove if not used in the requirements.) +</dd> +</dl> + +### Requirements +**TODO**: + - Plugins + - association builder <-> parameters + +## Sync + +### Sync on change +Syncer **SHOULD** synchronise the mapped hardware on parameter change. +<why>To always keep synchronise the underlined hardware and the PF +parameters.</why> + +### Read hardware +Syncer **SHOULD** retrieve parameter value from the hardware if no value has be +set since the PF start. +<note>This is usually implemented on PF start, initialize the parameter values +with the mapped hardware current state.</note> +<why>To allow introspection of the hardware.</why> + +### Explicit sync +A mode with synchronisation on client request **SHOULD** be supported. +<why>The user may want to group the synchronization of multiple parameters -- +for instance if a syncer contains more than 1 parameter -- in order to avoid +undesired intermediary states.</why> + +### Out of sync +Syncers **MAY** report an 'out-of-sync' condition indicating that the hardware +parameter values are not (or no longer) reflecting the last values set by the +Parameter Framework. +<why>This can happen when the underlying hardware subsystem +crashes/reboots/...</why> + +#### Recovery +When a syncer reports an out-of-sync condition, the PF **MUST** try to resync +the hardware values. + +# Rule based dynamic abstraction + +## Philosophy + +The PF offers parameters mapped on hardware. This is a good but weak +abstraction as there is often a 1/1 relation between a parameter and the hardware +it maps. Ie: parameter abstract how to access hardware and what hardware but +are still hardware specific. + +A PF offers a mechanism to abstract the parameters to a higher level concept. + +The goal is to hide numerous parameters and their dynamic values behind simple +and human friendly API. + +It works by grouping parameters with similar management and defining +configurations for each "scenario". These "scenario" are then given a priority +and a detection predicate. Configuration are applied when their associated +"scenario" is detected. + +"Scenario" are detected through arbitrary criterion provided by the PF host +(see below). + +## Definition + +<dl> +<dt>Configuration</dt> +<dd> +Set of values for different parameters. A configuration **MUST NOT** contain 2 +values of the same parameter. + +For example, given a PF with 3 integer parameters A,B,C, a configuration can +contain: + + - 1 value: (A) or (B) or (C); or + - 2 values: (A,B) or (A,C) or (B,C); or + - 3 values: (A,B,C). +</dd> + +<dt>Rogue Parameter</dt> +<dd> +A Parameter that is not contained by any configuration. +<dd> +</dl> + +## Configuration + +### Support +A PF **MUST** offer configurations as described in the Definition chapter. +<note>rule based parameter engine does not manipulate directly values, it +applies configuration on the parameters.</note> +<unknown>This is what the reference implementation does.</unknown> + +### Eligibility +Each configuration **MUST** be associated with a predicate that condition its +eligibility. A configuration with a predicate that evaluates to `true` is called +an "eligible configuration" +<why>This is what the reference implementation does.</why> + +### Default +It **SHOULD** be possible to express a predicate to always evaluates to `true`. +Ie: It *SHOULD* be possible to make a configuration always eligible. +<why>In order to have parameters set to constant values or have a fallback +configuration in a domain -- see below.</why> + +### Predicate implementation +The predicate **SHOULD** be a "selection criterion rule". See next chapter for a +definition. +<why>The reference implementation uses a boolean expression based engine.</why> + +## Selection criterion + +### State uniqueness +A selection criterion **MUST** have one, and only one, state at a given time. + +### State validity +A selection criterion **MUST** have a always known immutable domain of definition. +Ie All the possible state that a selection criterion can take **MUST** be known +at all time. +<why>To be able to validate:\ + - rules on start\ + - state changes +</why> + +### State domain specification +#### Naive +The selection criterion possible states **MUST** be specifiable by directly a +state set (`Input -> states == identity`) +<note>called **exclusive criterion**</note> +<note>An empty set is not allowed as the criterion could not have a state.</note> +<why>Any criterion can be created from this API.</why> + +#### Combination +The selection criterion possible states **SHOULD** be specifiable by a combination +of values +<note>combination in the [mathematical sense](https://en.wikipedia.org/wiki/Combination) +`"ab" -> ["", "a", "b", "ab"]`</note> +<note>called **inclusive criterion**</note> +<note>An empty value set is allowed as its combination -- a set containing the +empty set -- would not be empty. The empty set would be the only possible +criteria state.</note> +<why>The reference implementation supports it.</why> + +### Criteria number +The PF **SHOULD NOT** limit the number of criteria. + +#### State number +The PF **SHOULD NOT** limit the number of possible states of any given criterion +<ko>The reference implementation only supports 32 values for an inclusive +criterion and 2^32 values for an exclusive criterion</ko> + +### Definitions +<dl> +<dt>Selection criterion rule</dt> +<dd> +Function (in the mathematical sense) that **MUST** given selection criteria +return a Boolean. Ie, a [predicate](https://en.wikipedia.org/wiki/Predicate_%28mathematical_logic%29). +</dd> + +<dt>Rule</dt> +<dd> +A Boolean expression of Selection criterion rules. +<note>implementation only allows AND and OR combination</note> +<dd> +</dl> + +### Criterion changes + +#### Multiple criterion change atomicity +The API to change criterion values **MUST** allow atomicity regarding +configuration application. I.e. it **MUST** be possible to change multiple +criterion values without triggering a configuration application. +<why>Two criterion might have an excluding state. If configuration application +was triggered after each criterion change this transitory incompatible state +would impact the system. +For example 2 criterion `Tx` and `Rx` with 2 values `"on"` and `"off"` may have +an incompatible state `Tx = Rx = "on"`. Ie this state is unspecified and the +inference engine would gave unknown result. +\ +When going: \ + - from `Tx = "on" and Rx = "on"` (state 1) \ + - to `Tx = "off" and Rx = "off"` (state 2) \ +<!-- FIXME: why are list closing the why block ? --> +a transitory state `Tx = "on" and Rx = "on"` may be reached. Nevertheless +the inference engine must not be run on such. There must be a way to go +from one state 1 to state 2 without triggering configuration application. +</why> + +### Rules + +It **MUST** always be able to express a selection criterion rule from a given +selection criterion state. +I.e.: a criteria **MUST** always have a state that can be matched by a rule. +<why>If no rules can be formulated from a criterion state, +the hardware can not be abstracted in this state witch defeats the PF purpose.</why> + +Parameter values change **SHOULD** be selected by Rules. +<why>A rule based inference engine has been chosen based on implementation and +configuration ease</why> + +## Domains + +### Definition +<dl> +<dt>Domain</dt> +<dd> +Ordered set of configuration, all of which contain the values for the +same parameters. +</dd> +</dl> + +### Philosophy + +When creating configurations for parameters, a pattern emerges. +Some parameters are naturally grouping together. Ie changing on the same predicates. + +Without carefully crafting configuration predicates for mutual exclusivity, +multiples configuration of the same parameter could be eligible on the same +criterion state. This would lead to an ambiguity: which configuration should be applied. + +Multiple solution could be imagine like: + - ask to the client/user + - having configuration predicate mutual exclusive + - choose randomly + - group configuration applicable on the same in a priority ordered set + +The domains this specification recommend is this last solution. +It has been chosen as the recommended solution (just like parameter tree) +because it is a simple solution and is implemented in the reference implementation. + +The constraint of this solution is that a configuration can no longer be shared +between domains. For example a global default configuration can not exist. +It must be split up for each domain. + +This choice also force parameters to be independently accessible. + +### Requirement + +#### Configuration application ambiguity +There **MUST** be a mechanism to avoid ambiguity on multiple configuration eligibility +for the same parameter. +<why>Applying multiple configurations would leave the parameters in an unknown state.</why> + +#### Domain support +Each configuration **SHOULD** be in a "domain" (see Definition chapter). +<why>Domains are mostly a way to define the priority of configuration application +for some parameters.</why> +<ko>It is not a MUST because this goal could also be achieve with (for +example) global configurations and per parameter priority. It is not a MAY +because the reference implementation uses domains.</ko> + +#### Configuration priority +If multiple configuration are eligible, the first one **MUST** be applied. +<why>If multiple configuration are eligible, there must be a way to discriminate +them. The order was arbitrary chosen. +See the domain philosophy section for more information about this choice.</why> + +#### Lazy application +If no configuration is eligible, no configuration **MUST** be applied. +<note>It means that if none of the configurations is eligible, none is applied. +This also mean that no function can be defined between criteria and states. +I.e.: parameter values MAY depend on previous selection criterion states.</note> +<why>This is what the reference implementation does.</why> + +#### Sequence indifference +Parameter set and get order MUST not change the final state. +<why>Their is no way to order such access if the parameters are from different domains.</why> + +#### Sequence aware domain +Domains **MAY** be sequence aware. Such domains update their associated +parameters in a specific, predictable and configurable order. +<ko>The reference application supports it.</ko> +<why>Some parameters might require specific ordering on set. +This is contradictory with the fact that parameters MUST be accessed independently.</why> + +# (de)serialization + +## Philosophy +Serialization and deserialization are meant to support destruction recovery and +configuration deployment. + +These are the same requirements than for a database, it needs to be able to save +its state and restore for backup, deployment, reboot... + +## Definition +PF data includes: + +- parameters tree +- configurations: + - selection rule + - parameter/value couples +- domain: + - list of associated configurations + - order of priority + +## Requirement + +### Deserializable +The PF data **MUST** be deserializable. +<why>Otherwise a PF instance could only be created empty and then be filled by +the tuning interface. The reference implementation supports it.</why> + +### Deserializable from a file +The PF data **SHOULD** be deserializable from a config file. +<why>This is usually how program configuration are stored. The reference +implementation supports it.</why> + +### Serializable +The PF data **SHOULD** be serializable. +<why>In order to save a PF instance state and restore it later. This achieve +destruction recovery. The reference implementation supports it.</why> + +### (De)Serialization of individual data +The PF data **SHOULD** be serializable/deserializable by parts. +<why>For easier configuration management: for versioning; for selecting only wanted parts of a +complete configuration.</why> + +### Serialization format +**TODO**: XML ? + +### Implementation +Syncer build and syncer library identifiers **SHOULD** be strings. +<unknown>The reference application does so.</unknown> + +# Post mortem debug +A PF **MAY** save all data needed to replay it's state evolution. +<note>Eg: log criterion change, configuration application, parameter +external change. + +This is implementing by logging events by the reference implementation.</note> +<why>In order for the user to debug the user configuration after a bug occurred (post mortem or rare bug). +This is kind of like the bash -x feature. +</why> + +# Introspection +## Philosophy +In order to debug the user configuration, allow introspection of PF data at runtime. +As data is meant to be displayed to user, lots are requirements are towards +pretty printing PF data. + +## Requirements + +### Support +User **SHOULD** be able to inspect PF data. +<why>To offer run time debugging. +This includes: \ +- listing \ +\ \ \ \ + domains\ +\ \ \ \ + configurations of a domains\ +\ \ \ \ + parameters\ +\ \ \ \ + a domain's associated parameters\ +- getting their properties. Including:\ +\ \ \ \ + parameters values, min, max, size... +</why> + +### Pretty print +PF **MAY** offer pretty print of data. Including: + +- printing parameter value in decimal + <why>For human readability</why> +- pretty print parameter tree (such as the Unix tree command for files) + <why>In order to ease runtime debug.</why> + +### Rogue parameter +Users **SHOULD** be able to modify rogue parameters through the native API at +all time. +<why>Otherwise, a rogue parameter is of no use.</why> +<ko>In the reference implementation, under certain conditions, this is not +possible (tuning mode)</ko> + +### Parameter Identifiers + +#### Support +Every parameter **MUST** have an identifier that uniquely identifies it. +<why>to identify a parameter outside the framework</why> + +#### String +This identifier **SHOULD** be a string. +<why>So that a human user can identify a parameter with ease.</why> + +#### Determinism +Two PF instances with the same parameters **MUST** have the same identifier for +those parameters. +I.e. this identifier should be the same across all instances with the same +configuration. +<why>Persistence of parameter identifier across PF instances with the same +configuration. To identify parameters independently of the host machine and PF +instance</why> + +#### Tree path +The identifier of each node of a parameter tree **SHOULD** be a combination of its +parents. More specifically, if the identifier is a string it **SHOULD** be +formated in a similar way as a file system path. E.g. `/root/child1/4/parameter1`. +<why>Usual syntax to address trees.</why> + + +# Tuning + +## Definition + +<dl> +<dt>Tuning</dt> +<dd> +Tuning is the ability to modify the PF data structure at runtime. +</dd> +</dl> + +<note>Is this naming "Tuning" not too audio oriented.</note> + +## Philosophy + +As the PF might model a complex system with its dynamic parameter value engine +(rule based in the default implementation), its behaviour might be hard to +understand and should be easily modified not correct. + +To address this need, a fast modify-update-test cycle should be possible. + +## Requirements + +### Inference engine +Users **SHOULD** be able to modify the PF inference engine behaviour (rules, +configuration...) with minimal effort. +<why>To enable a fast modify-update-test cycle during tuning. +This usually mean avoiding for the user to: \ + - recompile \ + - restart the host process/service +</why> + +<note>No requirement is made on the persistence of those changes, they may or +may not disappear on PF restart. This could be implemented in several way, for +example: + +- exposed in the PF API +- changing a config file and sending a signal to the PF +- providing a IPC +- directly modifying the memory + +</note> + +### Native api +Tuning **SHOULD** be possible from the PF native API. +<why>In order to let the host system implement its own tuning mechanism.</why> + +### Parameter overwriting +Users **SHOULD** be able to modify the parameter values at any time. +This change **SHOULD NOT** be overwritten without a user action. +<note>User overwritten user action could be a log out, leaving some tuning mode, +forcing an inference engine update...</note> +<why>Even if a parameter is managed by the inference engine, it often is useful +(test, debugging) to overwrite its value temporally.</why> + +### Disabling +A PF tuning capability **MAY** be disabled in a context where no tuning is needed. +<why>The reference implementation does so (phone end users can not change the +tuning).</why> + +# Command line interface +<ko>Is this not an implementation detail? Does a client really needs it?</ko> + +## Support +The PF **MAY** offer a command line interface that binds to its IPC. +<why>To have a reference way to interact with a PF without implementing its IPC +protocol.</why> +<note>This requirement is fulfilled by remote-processor and remote-command on the reference implementation.</note> + +## Introspection & tunning +This command line interface **SHOULD** support all tuning and introspection ability. +<why>In order to be used in scripting and live tuning/debugging on an embedded +system.</why> + +## Auto completion +This command line interface **MAY** offer argument auto completion. +<why>Is more user friendly.</why> + +# Bindings + +## C +The PF **SHOULD** expose its API in C. +<why>The PF aims to be a hardware abstraction thus middle ware which is often +written in C or a language compatible with C. Virtually all programing language +support C Foreign Procedure Call, having a C API ease integration whichever the +host language is.</why> + +## Programing language +The PF **MAY** expose its API to multiple programing language. +<unknown>The reference implementation has python bindings.</unknown> + +# Performance + +The reference Parameter Framework implementation is mainly intended for use +in consumer electronics such as smartphones and tablets. Such platforms are +often referred to as "embedded" platforms but their capacity today is so huge in +terms of both computing and memory that they can be considered as small personal +computers. + +Moreover, since one of the Parameter Framework's primary feature is to implement +storage of + + - hardware description + - settings + +its memory footprint largely depends on how many such items are stored. + +For those reasons, there are no performance requirements imposed on the +architecture. Performance considerations are left to the implementation of the +Parameter Framework and/or the client and/or the build chain. + +# Next + +<ko> +The following requirements are not implemented in the reference implementation +and are to be considered draft. +</ko> + +## Multi OS +PF **MAY** support at least: + + - Linux (and Android) + - Windows + - Mac OSX + +<why>As the reference PF implementation leaves its original Android environment, +needs emerge to use it on other platform.</why> + +## Tuning +### Get and set multiple parameter values in one request +#### Atomicity +When setting multiple parameters from one client request, +and when one or more parameter value is invalid (eg. out of range), +no parameter **SHOULD** be set. +Eg: an invalid request to change parameters **SHOULD** not impact the parameters +values nor the subsystems. +<note>This may be implemented by first checking parameters validity +before setting them, or implementing a rollback mechanism, or any other way.</note> +<why>To provide parameter mutation atomicity to the client. +This is especially important if the client wants to implement parameter consistency. +Eg: let two parameters have excluding values, +if a transaction fail after the first parameter is set but not the second, +the excluding constraint may be violated. +It also usefull for the client to know the state of the parameters +after a parameter set without having to query the PF.</why> + +#### Access parameters as Xml +Getting and setting the content of one or more ([one, all]) parameters **SHOULD** +be possible in xml. +<why>For performance reason. Tools often need to update multiple parameter +and having one call per parameter is too slow. (benchmark ?). +This feature permit the client to save and restore from an external database parameter +values a la `alsa.state`.</why> + +#### Access parameters as binary +The PF host API **SHOULD** expose parameter values with the same API syncer use. +<why>The current reference implementation abstracts the memory layout of +parameters. This memory layout is specified in the parameter structure thus +is known by the client.</why> + +## Stage and commit Sync +Explicit sync **SHOULD** only sync parameters which values were updated since last sync. +<why>For performance reason or when an hardware does not support certain +transition state, manual parameter synchronisation is requested. + +Sync request was implemented in the reference implementation by syncing all +parameters, including the one that were not changed since last sync. + +For performance reason only the changed parameters should be send to hardware.</why> + + +## Structured api API +The PF host API **SHOULD** be structured. +I.e.: the PF, when requested for a list of domains, should return a list of +structured object, each containing configuration objects, containing their +values... +<why>The reference implementation has a string oriented API. E.g/: The list of +domains is returned as a concatenation of domains name in one big string. This +leads to hard to use API from C and C++ code. Especially for testing</why> + +### Implementation language +The main implementation will transition to C++11 for + - cross platform support of multi-threading + - remove dependency to pthread + - reduce the gap with the "next" branch +It will be compatible with android thank to clang's libc++" + +<note>Put this in a design document.</note> + +## Long term +The following requirements are not planned to be implemented any time soon as +their is not need identified but are rather a long term guidance. + +### Custom parameter types +The client **MAY** inject custom parameters types. +<why>As the client creates parameters it should also be able to specify the +parameter contains ie its types. Without this possibility the client has to +choose a built-in that may not match what he wants. + +For example representing a prime number with an integer would not allow to enforce primness. + +For example a complex number could be represented with two float but `a+bi` format +could not be used. + +For example stocking a parameter with a dynamic type, say either a string or a number +could be done with a boolean a string and a number but this could not be pretty +print and not memory efficient. +</why> + +### Structure tunning +Users **MAY** be able to modify the parameters (types, identifiers, tree...) with +minimal effort (in the same way they can modify the inference engine). +<ko>The reference implementation does not support it.</ko> +<why>To enable a fast modify-update-test cycle on PF configuration.</why> + +### Immutable parameters +A PF **MAY** support immutable parameters, i.e. parameters which value is determined +on start then read only. +<why>To permit hardware read only value reflection.</why> +<ko>This is not implemented in the PF reference implementation.</ko> + +This value **MUST** be gettable for an immutable parameter. +<why>A parameter that can not be accessed (read or write) is of no use.</why> + +### Endianess adaptation +A parameter or a block of parameters might be presented by the Parameter +Framework but only used as a passthrough to the underlying subsystem (think +"`(void *)` interfaces"). It is then possible that the endianess of the +subsystem differs from the one the Parameter Framework is running on, an +endianness adaptation would allow supporting those cases. + +This can be seen as related to the "Parameter Adaptation" requirement or even +as a special case. + +</article> diff --git a/parameter/Android.mk b/parameter/Android.mk deleted file mode 100644 index 7fa83fc..0000000 --- a/parameter/Android.mk +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright (c) 2011-2014, 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. - -LOCAL_PATH := $(call my-dir) - -#################### -# Common definitions - -common_copy_headers_to := parameter - -common_copy_headers := \ - include/ParameterMgrLoggerForward.h \ - include/ParameterMgrPlatformConnector.h \ - include/ParameterMgrFullConnector.h \ - include/SelectionCriterionTypeInterface.h \ - include/SelectionCriterionInterface.h \ - include/ParameterHandle.h - -common_src_files := \ - AreaConfiguration.cpp \ - ArrayParameter.cpp \ - AutoLog.cpp \ - BaseParameter.cpp \ - BinarySerializableElement.cpp \ - BinaryStream.cpp \ - BitParameterBlock.cpp \ - BitParameterBlockType.cpp \ - BitParameter.cpp \ - BitParameterType.cpp \ - BitwiseAreaConfiguration.cpp \ - BooleanParameterType.cpp \ - ComponentInstance.cpp \ - ComponentLibrary.cpp \ - ComponentType.cpp \ - CompoundRule.cpp \ - ConfigurableDomain.cpp \ - ConfigurableDomains.cpp \ - ConfigurableElementAggregator.cpp \ - ConfigurableElement.cpp \ - ConfigurationAccessContext.cpp \ - DomainConfiguration.cpp \ - Element.cpp \ - ElementLibrary.cpp \ - ElementLibrarySet.cpp \ - ElementLocator.cpp \ - EnumParameterType.cpp \ - EnumValuePair.cpp \ - ErrorContext.cpp \ - FixedPointParameterType.cpp \ - FormattedSubsystemObject.cpp \ - FrameworkConfigurationLocation.cpp \ - HardwareBackSynchronizer.cpp \ - InstanceConfigurableElement.cpp \ - InstanceDefinition.cpp \ - IntegerParameterType.cpp \ - LinearParameterAdaptation.cpp \ - LogarithmicParameterAdaptation.cpp \ - MappingContext.cpp \ - MappingData.cpp \ - ParameterAccessContext.cpp \ - ParameterAdaptation.cpp \ - ParameterBlackboard.cpp \ - ParameterBlockType.cpp \ - Parameter.cpp \ - ParameterFrameworkConfiguration.cpp \ - ParameterHandle.cpp \ - ParameterMgr.cpp \ - ParameterMgrFullConnector.cpp \ - ParameterMgrPlatformConnector.cpp \ - ParameterType.cpp \ - PathNavigator.cpp \ - PluginLocation.cpp \ - RuleParser.cpp \ - SelectionCriteria.cpp \ - SelectionCriteriaDefinition.cpp \ - SelectionCriterion.cpp \ - SelectionCriterionLibrary.cpp \ - SelectionCriterionRule.cpp \ - SelectionCriterionType.cpp \ - SimulatedBackSynchronizer.cpp \ - StringParameter.cpp \ - StringParameterType.cpp \ - Subsystem.cpp \ - SubsystemElementBuilder.cpp \ - SubsystemObject.cpp \ - SubsystemObjectCreator.cpp \ - SyncerSet.cpp \ - SystemClass.cpp \ - TypeElement.cpp \ - VirtualSubsystem.cpp \ - VirtualSyncer.cpp \ - XmlElementSerializingContext.cpp \ - XmlFileIncluderElement.cpp \ - XmlParameterSerializingContext.cpp - -common_module := libparameter -common_module_tags := optional - -common_cflags := \ - -Wall \ - -Werror \ - -Wextra \ - -Wno-unused-parameter \ - -Wno-maybe-uninitialized - -common_c_includes := \ - $(LOCAL_PATH)/include/ \ - $(LOCAL_PATH)/../utility/ \ - $(LOCAL_PATH)/../remote-processor/ - -############################# -# Target build - -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := $(common_copy_headers_to) -LOCAL_COPY_HEADERS := $(common_copy_headers) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -LOCAL_CFLAGS := $(common_cflags) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_MODULE := $(common_module) -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_C_INCLUDES := $(common_c_includes) - -LOCAL_SHARED_LIBRARIES := libxmlserializer libdl -LOCAL_STATIC_LIBRARIES := libpfw_utility - -LOCAL_REQUIRED_MODULES := libremote-processor - -ifeq ($(INCLUDE_STLPORT), true) -include external/stlport/libstlport.mk -endif - -include $(BUILD_SHARED_LIBRARY) - -############################## -# Host build - -include $(CLEAR_VARS) - -LOCAL_COPY_HEADERS_TO := $(common_copy_headers_to) -LOCAL_COPY_HEADERS := $(common_copy_headers) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -LOCAL_CFLAGS := $(common_cflags) -O0 -ggdb - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_MODULE := $(common_module)_host -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_C_INCLUDES += \ - $(common_c_includes) - -LOCAL_SHARED_LIBRARIES := libxmlserializer_host -LOCAL_STATIC_LIBRARIES := libpfw_utility_host libxml2 - -LOCAL_LDLIBS += -ldl - -include $(BUILD_HOST_SHARED_LIBRARY) diff --git a/parameter/AreaConfiguration.cpp b/parameter/AreaConfiguration.cpp index b3a556e..aaf7df8 100644 --- a/parameter/AreaConfiguration.cpp +++ b/parameter/AreaConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -30,42 +30,44 @@ #include "AreaConfiguration.h" #include "ConfigurableElement.h" #include "ConfigurationAccessContext.h" -#include "BinaryStream.h" #include <assert.h> -CAreaConfiguration::CAreaConfiguration(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet) - : _pConfigurableElement(pConfigurableElement), _pSyncerSet(pSyncerSet), _bValid(false) +CAreaConfiguration::CAreaConfiguration(const CConfigurableElement *pConfigurableElement, + const CSyncerSet *pSyncerSet) + : _pConfigurableElement(pConfigurableElement), _pSyncerSet(pSyncerSet) { // Size blackboard _blackboard.setSize(_pConfigurableElement->getFootPrint()); } -CAreaConfiguration::CAreaConfiguration(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet, uint32_t uiSize) - : _pConfigurableElement(pConfigurableElement), _pSyncerSet(pSyncerSet), _bValid(false) +CAreaConfiguration::CAreaConfiguration(const CConfigurableElement *pConfigurableElement, + const CSyncerSet *pSyncerSet, size_t size) + : _pConfigurableElement(pConfigurableElement), _pSyncerSet(pSyncerSet) { // Size blackboard - _blackboard.setSize(uiSize); + _blackboard.setSize(size); } // Save data from current -void CAreaConfiguration::save(const CParameterBlackboard* pMainBlackboard) +void CAreaConfiguration::save(const CParameterBlackboard *pMainBlackboard) { copyFrom(pMainBlackboard, _pConfigurableElement->getOffset()); } // Apply data to current -bool CAreaConfiguration::restore(CParameterBlackboard* pMainBlackboard, bool bSync, std::list<std::string>* plstrError) const +bool CAreaConfiguration::restore(CParameterBlackboard *pMainBlackboard, bool bSync, + core::Results *errors) const { assert(_bValid); copyTo(pMainBlackboard, _pConfigurableElement->getOffset()); // Synchronize if required - return !bSync || _pSyncerSet->sync(*pMainBlackboard, false, plstrError); + return !bSync || _pSyncerSet->sync(*pMainBlackboard, false, errors); } // Ensure validity -void CAreaConfiguration::validate(const CParameterBlackboard* pMainBlackboard) +void CAreaConfiguration::validate(const CParameterBlackboard *pMainBlackboard) { if (!_bValid) { @@ -83,7 +85,7 @@ bool CAreaConfiguration::isValid() const } // Ensure validity against given valid area configuration -void CAreaConfiguration::validateAgainst(const CAreaConfiguration* pValidAreaConfiguration) +void CAreaConfiguration::validateAgainst(const CAreaConfiguration *pValidAreaConfiguration) { // Should be called on purpose assert(!_bValid); @@ -102,7 +104,9 @@ void CAreaConfiguration::validateAgainst(const CAreaConfiguration* pValidAreaCon } // XML configuration settings parsing -bool CAreaConfiguration::serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) +bool CAreaConfiguration::serializeXmlSettings( + CXmlElement &xmlConfigurableElementSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) { // Assign blackboard to configuration context configurationAccessContext.setParameterBlackboard(&_blackboard); @@ -111,7 +115,8 @@ bool CAreaConfiguration::serializeXmlSettings(CXmlElement& xmlConfigurableElemen configurationAccessContext.setBaseOffset(_pConfigurableElement->getOffset()); // Parse configuration settings (element contents) - if (_pConfigurableElement->serializeXmlSettings(xmlConfigurableElementSettingsElementContent, configurationAccessContext)) { + if (_pConfigurableElement->serializeXmlSettings(xmlConfigurableElementSettingsElementContent, + configurationAccessContext)) { if (!configurationAccessContext.serializeOut()) { @@ -124,55 +129,40 @@ bool CAreaConfiguration::serializeXmlSettings(CXmlElement& xmlConfigurableElemen } // Compound handling -const CConfigurableElement* CAreaConfiguration::getConfigurableElement() const +const CConfigurableElement *CAreaConfiguration::getConfigurableElement() const { return _pConfigurableElement; } -void CAreaConfiguration::copyToOuter(CAreaConfiguration* pToAreaConfiguration) const +void CAreaConfiguration::copyToOuter(CAreaConfiguration *pToAreaConfiguration) const { assert(_pConfigurableElement->isDescendantOf(pToAreaConfiguration->getConfigurableElement())); - copyTo(&pToAreaConfiguration->_blackboard, _pConfigurableElement->getOffset() - pToAreaConfiguration->getConfigurableElement()->getOffset()); + copyTo(&pToAreaConfiguration->_blackboard, + _pConfigurableElement->getOffset() - + pToAreaConfiguration->getConfigurableElement()->getOffset()); } -void CAreaConfiguration::copyFromOuter(const CAreaConfiguration* pFromAreaConfiguration) +void CAreaConfiguration::copyFromOuter(const CAreaConfiguration *pFromAreaConfiguration) { assert(_pConfigurableElement->isDescendantOf(pFromAreaConfiguration->getConfigurableElement())); - copyFrom(&pFromAreaConfiguration->_blackboard, _pConfigurableElement->getOffset() - pFromAreaConfiguration->getConfigurableElement()->getOffset()); + copyFrom(&pFromAreaConfiguration->_blackboard, + _pConfigurableElement->getOffset() - + pFromAreaConfiguration->getConfigurableElement()->getOffset()); // Inner becomes valid setValid(true); } -// Serialization -void CAreaConfiguration::serialize(CBinaryStream& binaryStream) -{ - // Delegate to blackboard - _blackboard.serialize(binaryStream); - - if (!binaryStream.isOut()) { - - // Serialized in areas are valid - _bValid = true; - } -} - -// Data size -uint32_t CAreaConfiguration::getSize() const -{ - return _blackboard.getSize(); -} - -CParameterBlackboard& CAreaConfiguration::getBlackboard() +CParameterBlackboard &CAreaConfiguration::getBlackboard() { return _blackboard; } -const CParameterBlackboard& CAreaConfiguration::getBlackboard() const +const CParameterBlackboard &CAreaConfiguration::getBlackboard() const { - return _blackboard; + return _blackboard; } // Store validity @@ -182,13 +172,12 @@ void CAreaConfiguration::setValid(bool bValid) } // Blackboard copies -void CAreaConfiguration::copyTo(CParameterBlackboard* pToBlackboard, uint32_t uiOffset) const +void CAreaConfiguration::copyTo(CParameterBlackboard *pToBlackboard, size_t offset) const { - pToBlackboard->restoreFrom(&_blackboard, uiOffset); + pToBlackboard->restoreFrom(&_blackboard, offset); } -void CAreaConfiguration::copyFrom(const CParameterBlackboard* pFromBlackboard, uint32_t uiOffset) +void CAreaConfiguration::copyFrom(const CParameterBlackboard *pFromBlackboard, size_t offset) { - pFromBlackboard->saveTo(&_blackboard, uiOffset); + pFromBlackboard->saveTo(&_blackboard, offset); } - diff --git a/parameter/AreaConfiguration.h b/parameter/AreaConfiguration.h index 3ea4718..c20db37 100644 --- a/parameter/AreaConfiguration.h +++ b/parameter/AreaConfiguration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -30,8 +30,8 @@ #pragma once #include "ParameterBlackboard.h" -#include "BinaryStream.h" #include "SyncerSet.h" +#include "Results.h" class CConfigurableElement; class CXmlElement; @@ -40,71 +40,72 @@ class CConfigurationAccessContext; class CAreaConfiguration { public: - CAreaConfiguration(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet); + CAreaConfiguration(const CConfigurableElement *pConfigurableElement, + const CSyncerSet *pSyncerSet); - /* FIXME this was missing and probably buggy*/ - virtual ~CAreaConfiguration() {} + virtual ~CAreaConfiguration() = default; // Save data from current - void save(const CParameterBlackboard* pMainBlackboard); + void save(const CParameterBlackboard *pMainBlackboard); - // Apply data to current - bool restore(CParameterBlackboard* pMainBlackboard, bool bSync, std::list<std::string>* plstrError) const; + /** Restore the configuration area + * + * @param[in] pMainBlackboard the application main blackboard + * @param[in] bSync indicates if a synchronisation has to be done + * @param[out] errors, errors encountered during restoration + * @return true if success false otherwise + */ + bool restore(CParameterBlackboard *pMainBlackboard, bool bSync, core::Results *errors) const; // Ensure validity - void validate(const CParameterBlackboard* pMainBlackboard); + void validate(const CParameterBlackboard *pMainBlackboard); // Return validity bool isValid() const; // Ensure validity against given valid area configuration - void validateAgainst(const CAreaConfiguration* pValidAreaConfiguration); + void validateAgainst(const CAreaConfiguration *pValidAreaConfiguration); // Compound handling - const CConfigurableElement* getConfigurableElement() const; + const CConfigurableElement *getConfigurableElement() const; // Configuration merging - virtual void copyToOuter(CAreaConfiguration* pToAreaConfiguration) const; + virtual void copyToOuter(CAreaConfiguration *pToAreaConfiguration) const; // Configuration splitting - virtual void copyFromOuter(const CAreaConfiguration* pFromAreaConfiguration); + virtual void copyFromOuter(const CAreaConfiguration *pFromAreaConfiguration); // XML configuration settings parsing/composing - bool serializeXmlSettings(CXmlElement& xmlConfigurableElementSettingsElementContent, CConfigurationAccessContext& configurationAccessContext); - - // Serialization - void serialize(CBinaryStream& binaryStream); - - // Data size - uint32_t getSize() const; + bool serializeXmlSettings(CXmlElement &xmlConfigurableElementSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext); // Fetch the Configuration Blackboard - CParameterBlackboard& getBlackboard(); - const CParameterBlackboard& getBlackboard() const; + CParameterBlackboard &getBlackboard(); + const CParameterBlackboard &getBlackboard() const; protected: - CAreaConfiguration(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet, uint32_t uiSize); + CAreaConfiguration(const CConfigurableElement *pConfigurableElement, + const CSyncerSet *pSyncerSet, size_t size); private: // Blackboard copies - virtual void copyTo(CParameterBlackboard* pToBlackboard, uint32_t uiOffset) const; - virtual void copyFrom(const CParameterBlackboard* pFromBlackboard, uint32_t uiOffset); + virtual void copyTo(CParameterBlackboard *pToBlackboard, size_t offset) const; + virtual void copyFrom(const CParameterBlackboard *pFromBlackboard, size_t offset); // Store validity void setValid(bool bValid); protected: // Associated configurable element - const CConfigurableElement* _pConfigurableElement; + const CConfigurableElement *_pConfigurableElement; // Configurable element settings CParameterBlackboard _blackboard; private: // Syncer set (required for immediate synchronization) - const CSyncerSet* _pSyncerSet; + const CSyncerSet *_pSyncerSet; // Area configuration validity (invalid area configurations can't be restored) - bool _bValid; + bool _bValid{false}; }; - diff --git a/parameter/ArrayParameter.cpp b/parameter/ArrayParameter.cpp index 291b6a1..83ffe04 100644 --- a/parameter/ArrayParameter.cpp +++ b/parameter/ArrayParameter.cpp @@ -41,83 +41,55 @@ using std::string; -CArrayParameter::CArrayParameter(const string& strName, const CTypeElement* pTypeElement) : base(strName, pTypeElement) +CArrayParameter::CArrayParameter(const string &strName, const CTypeElement *pTypeElement) + : base(strName, pTypeElement) { } -uint32_t CArrayParameter::getFootPrint() const +size_t CArrayParameter::getFootPrint() const { return getSize() * getArrayLength(); } // Array length -uint32_t CArrayParameter::getArrayLength() const +size_t CArrayParameter::getArrayLength() const { return getTypeElement()->getArrayLength(); } // Element properties -void CArrayParameter::showProperties(string& strResult) const +void CArrayParameter::showProperties(string &strResult) const { base::showProperties(strResult); // Array length strResult += "Array length: "; - strResult += CUtility::toString(getArrayLength()); + strResult += std::to_string(getArrayLength()); strResult += "\n"; } -// XML configuration settings parsing -bool CArrayParameter::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const -{ - // Check for value space - handleValueSpaceAttribute(xmlConfigurationSettingsElementContent, configurationAccessContext); - - // Handle access - if (!configurationAccessContext.serializeOut()) { - - // Actually set values to blackboard - if (!setValues(0, configurationAccessContext.getBaseOffset(), xmlConfigurationSettingsElementContent.getTextContent(), configurationAccessContext)) { - - return false; - } - } else { - - // Get string value - string strValue; - - // Whole array requested - getValues(configurationAccessContext.getBaseOffset(), strValue, configurationAccessContext); - - // Populate value into xml text node - xmlConfigurationSettingsElementContent.setTextContent(strValue); - } - - // Done - return true; -} - // User set/get -bool CArrayParameter::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::accessValue(CPathNavigator &pathNavigator, string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { - uint32_t uiIndex; + size_t index; - if (!getIndex(pathNavigator, uiIndex, parameterAccessContext)) { + if (!getIndex(pathNavigator, index, parameterAccessContext)) { return false; } if (bSet) { // Set - if (uiIndex == (uint32_t)-1) { + if (index == (size_t)-1) { // No index provided, start with 0 - uiIndex = 0; + index = 0; } // Actually set values - if (!setValues(uiIndex, parameterAccessContext.getBaseOffset(), strValue, parameterAccessContext)) { - + if (!setValues(index, getOffset() - parameterAccessContext.getBaseOffset(), strValue, + parameterAccessContext)) { return false; } @@ -129,108 +101,129 @@ bool CArrayParameter::accessValue(CPathNavigator& pathNavigator, string& strValu } } else { // Get - if (uiIndex == (uint32_t)-1) { + if (index == (size_t)-1) { // Whole array requested - getValues(parameterAccessContext.getBaseOffset(), strValue, parameterAccessContext); + strValue = getValues(getOffset() - parameterAccessContext.getBaseOffset(), + parameterAccessContext); } else { // Scalar requested - doGetValue(strValue, getOffset() + uiIndex * getSize(), parameterAccessContext); + CParameter::doGetValue(strValue, getOffset() + index * getSize(), + parameterAccessContext); } } return true; } +/// Actual parameter access +// String access +bool CArrayParameter::doSetValue(const string &value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const +{ + return setValues(0, offset, value, parameterAccessContext); +} + +void CArrayParameter::doGetValue(string &value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const +{ + // Whole array requested + value = getValues(offset, parameterAccessContext); +} + // Boolean -bool CArrayParameter::accessAsBooleanArray(std::vector<bool>& abValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::access(std::vector<bool> &abValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return accessValues(abValues, bSet, parameterAccessContext); } // Integer -bool CArrayParameter::accessAsIntegerArray(std::vector<uint32_t>& auiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::access(std::vector<uint32_t> &auiValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return accessValues(auiValues, bSet, parameterAccessContext); } // Signed Integer Access -bool CArrayParameter::accessAsSignedIntegerArray(std::vector<int32_t>& aiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::access(std::vector<int32_t> &aiValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return accessValues(aiValues, bSet, parameterAccessContext); } // Double Access -bool CArrayParameter::accessAsDoubleArray(std::vector<double>& adValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::access(std::vector<double> &adValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return accessValues(adValues, bSet, parameterAccessContext); } // String Access -bool CArrayParameter::accessAsStringArray(std::vector<string>& astrValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::access(std::vector<string> &astrValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return accessValues(astrValues, bSet, parameterAccessContext); } // Dump -void CArrayParameter::logValue(string& strValue, CErrorContext& errorContext) const +string CArrayParameter::logValue(CParameterAccessContext &context) const { - // Parameter context - CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext); - // Dump values - getValues(0, strValue, parameterAccessContext); + return getValues(0, context); } // Used for simulation and virtual subsystems -void CArrayParameter::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +void CArrayParameter::setDefaultValues(CParameterAccessContext ¶meterAccessContext) const { // Get default value from type - uint32_t uiDefaultValue = static_cast<const CParameterType*>(getTypeElement())->getDefaultValue(); + uint32_t uiDefaultValue = + static_cast<const CParameterType *>(getTypeElement())->getDefaultValue(); // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Process - uint32_t uiValueIndex; - uint32_t uiSize = getSize(); - uint32_t uiOffset = getOffset(); - bool bSubsystemIsBigEndian = parameterAccessContext.isBigEndianSubsystem(); - uint32_t uiArrayLength = getArrayLength(); + size_t valueIndex; + size_t size = getSize(); + size_t offset = getOffset(); + size_t arrayLength = getArrayLength(); - for (uiValueIndex = 0; uiValueIndex < uiArrayLength; uiValueIndex++) { + for (valueIndex = 0; valueIndex < arrayLength; valueIndex++) { // Beware this code works on little endian architectures only! - pBlackboard->writeInteger(&uiDefaultValue, uiSize, uiOffset, bSubsystemIsBigEndian); + pBlackboard->writeInteger(&uiDefaultValue, size, offset); - uiOffset += uiSize; + offset += size; } } // Index from path -bool CArrayParameter::getIndex(CPathNavigator& pathNavigator, uint32_t& uiIndex, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::getIndex(CPathNavigator &pathNavigator, size_t &index, + CParameterAccessContext ¶meterAccessContext) const { - uiIndex = (uint32_t)-1; + index = (size_t)-1; - string* pStrChildName = pathNavigator.next(); + string *pStrChildName = pathNavigator.next(); if (pStrChildName) { // Check index is numeric - std::istringstream iss(*pStrChildName); + std::istringstream iss(*pStrChildName); - iss >> uiIndex; + iss >> index; if (!iss) { - parameterAccessContext.setError("Expected numerical expression as last item in " + pathNavigator.getCurrentPath()); + parameterAccessContext.setError("Expected numerical expression as last item in " + + pathNavigator.getCurrentPath()); return false; } - if (uiIndex >= getArrayLength()) { - std::ostringstream oss; + if (index >= getArrayLength()) { + std::ostringstream oss; oss << "Provided index out of range (max is " << getArrayLength() - 1 << ")"; @@ -255,16 +248,17 @@ bool CArrayParameter::getIndex(CPathNavigator& pathNavigator, uint32_t& uiIndex, } // Common set value processing -bool CArrayParameter::setValues(uint32_t uiStartIndex, uint32_t uiBaseOffset, const string& strValue, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::setValues(size_t uiStartIndex, size_t offset, const string &strValue, + CParameterAccessContext ¶meterAccessContext) const { // Deal with value(s) Tokenizer tok(strValue, Tokenizer::defaultDelimiters + ","); std::vector<string> astrValues = tok.split(); - size_t uiNbValues = astrValues.size(); + size_t nbValues = astrValues.size(); // Check number of provided values - if (uiNbValues + uiStartIndex > getArrayLength()) { + if (nbValues + uiStartIndex > getArrayLength()) { // Out of bounds parameterAccessContext.setError("Too many values provided"); @@ -273,60 +267,62 @@ bool CArrayParameter::setValues(uint32_t uiStartIndex, uint32_t uiBaseOffset, co } // Process - uint32_t uiValueIndex; - uint32_t uiSize = getSize(); - uint32_t uiOffset = getOffset() + uiStartIndex * uiSize - uiBaseOffset; + size_t valueIndex; + size_t size = getSize(); + offset += uiStartIndex * size; - for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) { + for (valueIndex = 0; valueIndex < nbValues; valueIndex++) { - if (!doSetValue(astrValues[uiValueIndex], uiOffset, parameterAccessContext)) { + if (!doSet(astrValues[valueIndex], offset, parameterAccessContext)) { // Append parameter path to error parameterAccessContext.appendToError(" " + getPath() + "/" + - CUtility::toString(uiValueIndex + uiStartIndex)); + std::to_string(valueIndex + uiStartIndex)); return false; } - uiOffset += uiSize; + offset += size; } return true; } // Common get value processing -void CArrayParameter::getValues(uint32_t uiBaseOffset, string& strValues, CParameterAccessContext& parameterAccessContext) const +string CArrayParameter::getValues(size_t offset, + CParameterAccessContext ¶meterAccessContext) const { - uint32_t uiValueIndex; - uint32_t uiSize = getSize(); - uint32_t uiOffset = getOffset() - uiBaseOffset; - uint32_t uiArrayLength = getArrayLength(); + size_t size = getSize(); + size_t arrayLength = getArrayLength(); - strValues.clear(); + string output; bool bFirst = true; - for (uiValueIndex = 0; uiValueIndex < uiArrayLength; uiValueIndex++) { + for (size_t valueIndex = 0; valueIndex < arrayLength; valueIndex++) { string strReadValue; - doGetValue(strReadValue, uiOffset, parameterAccessContext); + doGet(strReadValue, offset, parameterAccessContext); if (!bFirst) { - strValues += " "; + output += " "; } else { bFirst = false; } - strValues += strReadValue; + output += strReadValue; - uiOffset += uiSize; + offset += size; } + + return output; } // Generic Access template <typename type> -bool CArrayParameter::accessValues(std::vector<type>& values, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::accessValues(std::vector<type> &values, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { if (bSet) { @@ -353,83 +349,86 @@ bool CArrayParameter::accessValues(std::vector<type>& values, bool bSet, CParame } template <typename type> -bool CArrayParameter::setValues(const std::vector<type>& values, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::setValues(const std::vector<type> &values, + CParameterAccessContext ¶meterAccessContext) const { - uint32_t uiNbValues = getArrayLength(); - uint32_t uiValueIndex; - uint32_t uiSize = getSize(); - uint32_t uiOffset = getOffset(); + size_t nbValues = getArrayLength(); + size_t size = getSize(); + size_t offset = getOffset(); - assert(values.size() == uiNbValues); + assert(values.size() == nbValues); // Process - for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) { + for (size_t valueIndex = 0; valueIndex < nbValues; valueIndex++) { - if (!doSet(values[uiValueIndex], uiOffset, parameterAccessContext)) { + if (!doSet(values[valueIndex], offset, parameterAccessContext)) { return false; } - uiOffset += uiSize; + offset += size; } - return true; + return true; } template <typename type> -bool CArrayParameter::getValues(std::vector<type>& values, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::getValues(std::vector<type> &values, + CParameterAccessContext ¶meterAccessContext) const { - uint32_t uiNbValues = getArrayLength(); - uint32_t uiValueIndex; - uint32_t uiSize = getSize(); - uint32_t uiOffset = getOffset(); + size_t nbValues = getArrayLength(); + size_t size = getSize(); + size_t offset = getOffset(); values.clear(); - for (uiValueIndex = 0; uiValueIndex < uiNbValues; uiValueIndex++) { + for (size_t valueIndex = 0; valueIndex < nbValues; valueIndex++) { type readValue; - if (!doGet(readValue, uiOffset, parameterAccessContext)) { + if (!doGet(readValue, offset, parameterAccessContext)) { return false; } values.push_back(readValue); - uiOffset += uiSize; + offset += size; } return true; } template <typename type> -bool CArrayParameter::doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::doSet(type value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { uint32_t uiData; - if (!static_cast<const CParameterType*>(getTypeElement())->toBlackboard(value, uiData, parameterAccessContext)) { + if (!static_cast<const CParameterType *>(getTypeElement()) + ->toBlackboard(value, uiData, parameterAccessContext)) { return false; } // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->writeInteger(&uiData, getSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->writeInteger(&uiData, getSize(), offset); return true; } template <typename type> -bool CArrayParameter::doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CArrayParameter::doGet(type &value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { uint32_t uiData = 0; // Read blackboard - const CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + const CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->readInteger(&uiData, getSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->readInteger(&uiData, getSize(), offset); - return static_cast<const CParameterType*>(getTypeElement())->fromBlackboard(value, uiData, parameterAccessContext); + return static_cast<const CParameterType *>(getTypeElement()) + ->fromBlackboard(value, uiData, parameterAccessContext); } - diff --git a/parameter/ArrayParameter.h b/parameter/ArrayParameter.h index bdc5632..b2018c2 100644 --- a/parameter/ArrayParameter.h +++ b/parameter/ArrayParameter.h @@ -34,55 +34,71 @@ class CArrayParameter : public CParameter { public: - CArrayParameter(const std::string& strName, const CTypeElement* pTypeElement); + CArrayParameter(const std::string &strName, const CTypeElement *pTypeElement); // Instantiation, allocation - virtual uint32_t getFootPrint() const; + virtual size_t getFootPrint() const; - // XML configuration settings parsing - virtual bool serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const; - - // Value access - // Boolean - virtual bool accessAsBooleanArray(std::vector<bool>& abValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; - // Integer - virtual bool accessAsIntegerArray(std::vector<uint32_t>& auiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; - // Signed Integer Access - virtual bool accessAsSignedIntegerArray(std::vector<int32_t>& aiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; - // Double Access - virtual bool accessAsDoubleArray(std::vector<double>& adValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; - // String Access - virtual bool accessAsStringArray(std::vector<std::string>& astrValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; + /// Value access + using CBaseParameter::access; + bool access(std::vector<bool> &abValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; + bool access(std::vector<uint32_t> &auiValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; + bool access(std::vector<int32_t> &aiValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; + bool access(std::vector<double> &adValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; + bool access(std::vector<std::string> &astrValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; protected: // User set/get - virtual bool accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + virtual bool accessValue(CPathNavigator &pathNavigator, std::string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; // Used for simulation and virtual subsystems - virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const; + virtual void setDefaultValues(CParameterAccessContext ¶meterAccessContext) const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; + private: // Array length - uint32_t getArrayLength() const; + size_t getArrayLength() const; // Common set value processing - bool setValues(uint32_t uiStartIndex, uint32_t uiBaseOffset, const std::string& strValue, CParameterAccessContext& parameterAccessContext) const; + bool setValues(size_t uiStartIndex, size_t offset, const std::string &strValue, + CParameterAccessContext ¶meterAccessContext) const; // Log / get values common - void getValues(uint32_t uiBaseOffset, std::string& strValues, CParameterAccessContext& parameterAccessContext) const; + std::string getValues(size_t baseOffset, CParameterAccessContext ¶meterAccessContext) const; + std::string logValue(CParameterAccessContext &context) const override; // Index retrieval from user set/get request - bool getIndex(CPathNavigator& pathNavigator, uint32_t& uiIndex, CParameterAccessContext& parameterAccessContext) const; + bool getIndex(CPathNavigator &pathNavigator, size_t &index, + CParameterAccessContext ¶meterAccessContext) const; + + /** Access whole array. + * + * @param[in] offset Offset of the array in the context blackboard. + * @{ + */ + bool doSetValue(const std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const override; + void doGetValue(std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const override; + /** @} */ /// Value access // Generic Access template <typename type> - bool accessValues(std::vector<type>& values, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool accessValues(std::vector<type> &values, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; template <typename type> - bool setValues(const std::vector<type>& values, CParameterAccessContext& parameterAccessContext) const; + bool setValues(const std::vector<type> &values, + CParameterAccessContext ¶meterAccessContext) const; template <typename type> - bool getValues(std::vector<type>& values, CParameterAccessContext& parameterAccessContext) const; + bool getValues(std::vector<type> &values, + CParameterAccessContext ¶meterAccessContext) const; template <typename type> - bool doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + bool doSet(type value, size_t offset, CParameterAccessContext ¶meterAccessContext) const; template <typename type> - bool doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + bool doGet(type &value, size_t offset, CParameterAccessContext ¶meterAccessContext) const; }; diff --git a/parameter/BackSynchronizer.h b/parameter/BackSynchronizer.h index 0d6fcb5..ff6c4f6 100644 --- a/parameter/BackSynchronizer.h +++ b/parameter/BackSynchronizer.h @@ -31,15 +31,18 @@ #include "ConfigurableElementAggregator.h" #include "ConfigurableElement.h" +#include <NonCopyable.hpp> + #include <list> class CParameterBlackboard; -class CBackSynchronizer +class CBackSynchronizer : private utility::NonCopyable { public: - CBackSynchronizer(const CConfigurableElement* pConfigurableElement) - : _configurableElementAggregator(_needingBackSyncList, &CConfigurableElement::hasNoValidDomainAssociated) + CBackSynchronizer(const CConfigurableElement *pConfigurableElement) + : _configurableElementAggregator(_needingBackSyncList, + &CConfigurableElement::hasNoValidDomainAssociated) { // Aggegate elements _configurableElementAggregator.aggegate(pConfigurableElement); @@ -47,14 +50,13 @@ public: // Back synchronization virtual void sync() = 0; - virtual ~CBackSynchronizer() {} + virtual ~CBackSynchronizer() = default; protected: // Aggregate list - std::list<const CConfigurableElement*> _needingBackSyncList; + std::list<const CConfigurableElement *> _needingBackSyncList; private: // Aggegator CConfigurableElementAggregator _configurableElementAggregator; }; - diff --git a/parameter/BaseParameter.cpp b/parameter/BaseParameter.cpp index 07314bd..f28a26c 100644 --- a/parameter/BaseParameter.cpp +++ b/parameter/BaseParameter.cpp @@ -38,18 +38,23 @@ using std::string; -CBaseParameter::CBaseParameter(const string& strName, const CTypeElement* pTypeElement) : base(strName, pTypeElement) +CBaseParameter::CBaseParameter(const string &strName, const CTypeElement *pTypeElement) + : base(strName, pTypeElement) { } // XML configuration settings parsing/composing -bool CBaseParameter::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const +bool CBaseParameter::serializeXmlSettings( + CXmlElement &xmlConfigurationSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) const { // Handle access if (!configurationAccessContext.serializeOut()) { // Write to blackboard - if (!doSetValue(xmlConfigurationSettingsElementContent.getTextContent(), getOffset() - configurationAccessContext.getBaseOffset(), configurationAccessContext)) { + if (!doSetValue(xmlConfigurationSettingsElementContent.getTextContent(), + getOffset() - configurationAccessContext.getBaseOffset(), + configurationAccessContext)) { appendParameterPathToError(configurationAccessContext); return false; @@ -59,24 +64,25 @@ bool CBaseParameter::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsE // Get string value string strValue; - doGetValue(strValue, getOffset() - configurationAccessContext.getBaseOffset(), configurationAccessContext); + doGetValue(strValue, getOffset() - configurationAccessContext.getBaseOffset(), + configurationAccessContext); // Populate value into xml text node xmlConfigurationSettingsElementContent.setTextContent(strValue); } // Done - return true; + return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, + configurationAccessContext); } // Dump -void CBaseParameter::logValue(string& strValue, CErrorContext& errorContext) const +string CBaseParameter::logValue(CParameterAccessContext &context) const { - // Parameter context - CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext); - // Dump value - doGetValue(strValue, getOffset(), parameterAccessContext); + string output; + doGetValue(output, getOffset(), context); + return output; } // Check element is a parameter @@ -85,98 +91,67 @@ bool CBaseParameter::isParameter() const return true; } -/// Value access -// Boolean access -bool CBaseParameter::accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(bool & /*bValue*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)bValue; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } - -bool CBaseParameter::accessAsBooleanArray(std::vector<bool>& abValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(std::vector<bool> & /*abValues*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)abValues; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } -// Integer Access -bool CBaseParameter::accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(uint32_t & /*bValue*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)uiValue; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } - -bool CBaseParameter::accessAsIntegerArray(std::vector<uint32_t>& auiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(std::vector<uint32_t> & /*abValues*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)auiValues; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } -// Signed Integer Access -bool CBaseParameter::accessAsSignedInteger(int32_t& iValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(int32_t & /*bValue*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)iValue; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } - -bool CBaseParameter::accessAsSignedIntegerArray(std::vector<int32_t>& aiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(std::vector<int32_t> & /*abValues*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)aiValues; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } -// Double Access -bool CBaseParameter::accessAsDouble(double& dValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(double & /*bValue*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)dValue; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } - -bool CBaseParameter::accessAsDoubleArray(std::vector<double>& adValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(std::vector<double> & /*abValues*/, bool /*bSet*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)adValues; - (void)bSet; - parameterAccessContext.setError("Unsupported conversion"); - return false; } // String Access -bool CBaseParameter::accessAsString(string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { if (bSet) { // Set Value - if (!doSetValue(strValue, getOffset() - parameterAccessContext.getBaseOffset(), parameterAccessContext)) { + if (!doSetValue(strValue, getOffset() - parameterAccessContext.getBaseOffset(), + parameterAccessContext)) { appendParameterPathToError(parameterAccessContext); return false; @@ -190,18 +165,16 @@ bool CBaseParameter::accessAsString(string& strValue, bool bSet, CParameterAcces } else { // Get Value - doGetValue(strValue, getOffset() - parameterAccessContext.getBaseOffset(), parameterAccessContext); + doGetValue(strValue, getOffset() - parameterAccessContext.getBaseOffset(), + parameterAccessContext); } return true; } -bool CBaseParameter::accessAsStringArray(std::vector<string>& astrValues, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::access(std::vector<string> & /*astrValues*/, bool /*bSet*/, + CParameterAccessContext & /*ctx*/) const { - (void)astrValues; - (void)bSet; - (void)parameterAccessContext; - // Generic string array access to scalar parameter must have been filtered out before assert(0); @@ -209,7 +182,8 @@ bool CBaseParameter::accessAsStringArray(std::vector<string>& astrValues, bool b } // Parameter Access -bool CBaseParameter::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBaseParameter::accessValue(CPathNavigator &pathNavigator, string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { // Check path validity if (!checkPathExhausted(pathNavigator, parameterAccessContext)) { @@ -217,19 +191,19 @@ bool CBaseParameter::accessValue(CPathNavigator& pathNavigator, string& strValue return false; } - return accessAsString(strValue, bSet, parameterAccessContext); + return access(strValue, bSet, parameterAccessContext); } -void CBaseParameter::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CBaseParameter::structureToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Delegate to type element getTypeElement()->toXml(xmlElement, serializingContext); } - -void CBaseParameter::appendParameterPathToError(CParameterAccessContext& parameterAccessContext) -const +void CBaseParameter::appendParameterPathToError( + CParameterAccessContext ¶meterAccessContext) const { parameterAccessContext.appendToError(" " + getPath()); } diff --git a/parameter/BaseParameter.h b/parameter/BaseParameter.h index 848d638..1b80fb8 100644 --- a/parameter/BaseParameter.h +++ b/parameter/BaseParameter.h @@ -40,51 +40,71 @@ class CConfigurationAccessContext; class CBaseParameter : public CInstanceConfigurableElement { public: - CBaseParameter(const std::string& strName, const CTypeElement* pTypeElement); + CBaseParameter(const std::string &strName, const CTypeElement *pTypeElement); // XML configuration settings parsing/composing - virtual bool serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const; + virtual bool serializeXmlSettings( + CXmlElement &xmlConfigurationSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) const; // Check element is a parameter virtual bool isParameter() const; - /// Value access // Boolean access - virtual bool accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual bool accessAsBooleanArray(std::vector<bool>& abValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; + virtual bool access(bool &bValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool access(std::vector<bool> &abValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; // Integer Access - virtual bool accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual bool accessAsIntegerArray(std::vector<uint32_t>& auiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; + virtual bool access(uint32_t &uiValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool access(std::vector<uint32_t> &auiValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; // Signed Integer Access - virtual bool accessAsSignedInteger(int32_t& iValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual bool accessAsSignedIntegerArray(std::vector<int32_t>& aiValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; + virtual bool access(int32_t &iValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool access(std::vector<int32_t> &aiValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; // Double Access - virtual bool accessAsDouble(double& dValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual bool accessAsDoubleArray(std::vector<double>& adValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; + virtual bool access(double &dValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool access(std::vector<double> &adValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; // String Access - bool accessAsString(std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual bool accessAsStringArray(std::vector<std::string>& astrValues, bool bSet, CParameterAccessContext& parameterAccessContext) const; + // This one is not virtual because it is very generic. You can think if it + // as the client saying: "I don't care about the type, here's the value as + // a string - convert it yourself". Then, string-to-anything and + // anything-to-string methods are used to convert it into a suitable type. + bool access(std::string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool access(std::vector<std::string> &astrValues, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; - // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + void structureToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const override final; protected: // Parameter Access - virtual bool accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + virtual bool accessValue(CPathNavigator &pathNavigator, std::string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; // Actual value access (to be implemented by derived) - virtual bool doSetValue(const std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const = 0; - virtual void doGetValue(std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const = 0; + virtual bool doSetValue(const std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const = 0; + virtual void doGetValue(std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const = 0; /** * Append the parameter path to the error. * - * @param[in:out] parameterAccessContext Parameter Access Context object. + * @param[in,out] parameterAccessContext Parameter Access Context object. */ - void appendParameterPathToError(CParameterAccessContext& parameterAccessContext) const; + void appendParameterPathToError(CParameterAccessContext ¶meterAccessContext) const; + +private: + std::string logValue(CParameterAccessContext &context) const override; }; diff --git a/parameter/BinaryStream.cpp b/parameter/BinaryStream.cpp deleted file mode 100644 index 2dc3380..0000000 --- a/parameter/BinaryStream.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2011-2014, 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 "BinaryStream.h" -#include <string.h> -#include <assert.h> - -using namespace std; - -CBinaryStream::CBinaryStream(const string& strFileName, bool bOut, size_t uiDataSize, uint8_t uiStructureChecksum) : - _strFileName(strFileName), - _bOut(bOut), - _uiDataSize(uiDataSize), - _uiStructureChecksum(uiStructureChecksum), - _puiData(new uint8_t[uiDataSize]), - _uiPos(0), - _bOpen(false) -{ -} - -CBinaryStream::~CBinaryStream() -{ - if (_bOpen) { - - close(); - } - - delete [] _puiData; -} - -bool CBinaryStream::open(string& strError) -{ - assert(!_bOpen); - - _fileStream.open(_strFileName.c_str(), (_bOut ? ios::out : ios::in|ios::ate)|ios::binary); - - if (!_fileStream.is_open() || !_fileStream.good()) { - - strError = string("Failed to ") + (_bOut ? "write" : "read") + "-open"; - - return false; - } - if (!_bOut) { - - // Get file size - size_t uiFileSize = _fileStream.tellg(); - - // Validate file size - if (_uiDataSize + sizeof(_uiStructureChecksum) != uiFileSize) { - - // Size different from expected - strError = "Unexpected file size"; - - return false; - } - - // Back to beginning of file - _fileStream.seekg(0, ios::beg); - - // Get data - _fileStream.read((char*)_puiData, _uiDataSize); - - // File checksum - uint8_t uiFileChecksum; - _fileStream.read((char*)&uiFileChecksum, sizeof(uiFileChecksum)); - - // Data checksum - uint8_t uiDataChecksum = computeChecksum(); - - // Validate checksum - if (uiDataChecksum != uiFileChecksum) { - - strError = "Integrity checks failed"; - - return false; - } - } - - // Keep track - _bOpen = true; - - return true; -} - -void CBinaryStream::close() -{ - assert(_bOpen); - - if (_bOut) { - - // Get data - _fileStream.write((const char*)_puiData, _uiDataSize); - - // Compute checksum - uint8_t uiDataChecksum = computeChecksum(); - - // Write checksum - _fileStream.write((const char*)&uiDataChecksum, sizeof(uiDataChecksum)); - } - - // Keep track - _bOpen = false; - - // Close file - _fileStream.close(); -} - -void CBinaryStream::reset() -{ - _uiPos = 0; -} - -void CBinaryStream::write(const uint8_t* puiData, size_t uiSize) -{ - assert(_uiPos + uiSize <= _uiDataSize); - - memcpy(&_puiData[_uiPos], puiData, uiSize); - - _uiPos += uiSize; -} - -void CBinaryStream::read(uint8_t* puiData, size_t uiSize) -{ - assert(_uiPos + uiSize <= _uiDataSize); - - memcpy(puiData, &_puiData[_uiPos], uiSize); - - _uiPos += uiSize; -} - -uint8_t CBinaryStream::computeChecksum() const -{ - uint32_t uiIndex; - uint8_t uiDataChecksum = _uiStructureChecksum; - - for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) { - - uiDataChecksum += _puiData[uiIndex]; - } - return uiDataChecksum; -} - -bool CBinaryStream::isOut() const -{ - return _bOut; -} diff --git a/parameter/BitParameter.cpp b/parameter/BitParameter.cpp index 2a53afd..81a9800 100644 --- a/parameter/BitParameter.cpp +++ b/parameter/BitParameter.cpp @@ -39,7 +39,8 @@ using std::string; -CBitParameter::CBitParameter(const string& strName, const CTypeElement* pTypeElement) : base(strName, pTypeElement) +CBitParameter::CBitParameter(const string &strName, const CTypeElement *pTypeElement) + : base(strName, pTypeElement) { } @@ -50,35 +51,37 @@ CInstanceConfigurableElement::Type CBitParameter::getType() const } // Size -uint32_t CBitParameter::getBelongingBlockSize() const +size_t CBitParameter::getBelongingBlockSize() const { - return static_cast<const CBitParameterBlock*>(getParent())->getSize(); + return static_cast<const CBitParameterBlock *>(getParent())->getSize(); } // Instantiation, allocation -uint32_t CBitParameter::getFootPrint() const +size_t CBitParameter::getFootPrint() const { // Allocation done at parent level return 0; } // Actual parameter access (tuning) -bool CBitParameter::doSetValue(const string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CBitParameter::doSetValue(const string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { - return doSet(strValue, uiOffset, parameterAccessContext); + return doSet(strValue, offset, parameterAccessContext); } -void CBitParameter::doGetValue(string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +void CBitParameter::doGetValue(string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { - doGet(strValue, uiOffset, parameterAccessContext); + doGet(strValue, offset, parameterAccessContext); } /// Value access -// Boolean access -bool CBitParameter::accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBitParameter::access(bool &bValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { // Check boolean access validity here - if (static_cast<const CBitParameterType*>(getTypeElement())->getBitSize() != 1) { + if (static_cast<const CBitParameterType *>(getTypeElement())->getBitSize() != 1) { parameterAccessContext.setError("Type mismatch"); appendParameterPathToError(parameterAccessContext); @@ -94,7 +97,7 @@ bool CBitParameter::accessAsBoolean(bool& bValue, bool bSet, CParameterAccessCon uiValue = bValue; } - if (!accessAsInteger(uiValue, bSet, parameterAccessContext)) { + if (!access(uiValue, bSet, parameterAccessContext)) { return false; } @@ -107,15 +110,15 @@ bool CBitParameter::accessAsBoolean(bool& bValue, bool bSet, CParameterAccessCon return true; } -// Integer Access -bool CBitParameter::accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CBitParameter::access(uint32_t &uiValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { - uint32_t uiOffset = getOffset(); + size_t offset = getOffset(); if (bSet) { // Set Value - if (!doSet(uiValue, uiOffset, parameterAccessContext)) { + if (!doSet(uiValue, offset, parameterAccessContext)) { appendParameterPathToError(parameterAccessContext); return false; @@ -129,50 +132,54 @@ bool CBitParameter::accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAcce } else { // Convert - doGet(uiValue, uiOffset, parameterAccessContext); + doGet(uiValue, offset, parameterAccessContext); } return true; } template <typename type> -bool CBitParameter::doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CBitParameter::doSet(type value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { uint64_t uiData = 0; // Read/modify/write - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->readInteger(&uiData, getBelongingBlockSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->readInteger(&uiData, getBelongingBlockSize(), offset); // Convert - if (!static_cast<const CBitParameterType*>(getTypeElement())->toBlackboard(value, uiData, parameterAccessContext)) { + if (!static_cast<const CBitParameterType *>(getTypeElement()) + ->toBlackboard(value, uiData, parameterAccessContext)) { return false; } // Write blackboard - pBlackboard->writeInteger(&uiData, getBelongingBlockSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->writeInteger(&uiData, getBelongingBlockSize(), offset); return true; } template <typename type> -void CBitParameter::doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +void CBitParameter::doGet(type &value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { uint64_t uiData = 0; // Read blackboard - const CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + const CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->readInteger(&uiData, getBelongingBlockSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->readInteger(&uiData, getBelongingBlockSize(), offset); // Convert - static_cast<const CBitParameterType*>(getTypeElement())->fromBlackboard(value, uiData, parameterAccessContext); + static_cast<const CBitParameterType *>(getTypeElement()) + ->fromBlackboard(value, uiData, parameterAccessContext); } // AreaConfiguration creation -CAreaConfiguration* CBitParameter::createAreaConfiguration(const CSyncerSet* pSyncerSet) const +CAreaConfiguration *CBitParameter::createAreaConfiguration(const CSyncerSet *pSyncerSet) const { return new CBitwiseAreaConfiguration(this, pSyncerSet); } @@ -181,5 +188,5 @@ CAreaConfiguration* CBitParameter::createAreaConfiguration(const CSyncerSet* pSy uint64_t CBitParameter::merge(uint64_t uiOriginData, uint64_t uiNewData) const { // Convert - return static_cast<const CBitParameterType*>(getTypeElement())->merge(uiOriginData, uiNewData); + return static_cast<const CBitParameterType *>(getTypeElement())->merge(uiOriginData, uiNewData); } diff --git a/parameter/BitParameter.h b/parameter/BitParameter.h index f9e2b9d..cbe071e 100644 --- a/parameter/BitParameter.h +++ b/parameter/BitParameter.h @@ -36,39 +36,42 @@ class CBitParameter : public CBaseParameter { public: - CBitParameter(const std::string& strName, const CTypeElement* pTypeElement); + CBitParameter(const std::string &strName, const CTypeElement *pTypeElement); // Instantiation, allocation - virtual uint32_t getFootPrint() const; + virtual size_t getFootPrint() const; // Type virtual Type getType() const; /// Value access // Boolean access - virtual bool accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool access(bool &bValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; // Integer Access - virtual bool accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool access(uint32_t &uiValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override final; // AreaConfiguration creation - virtual CAreaConfiguration* createAreaConfiguration(const CSyncerSet* pSyncerSet) const; + virtual CAreaConfiguration *createAreaConfiguration(const CSyncerSet *pSyncerSet) const; // Size - uint32_t getBelongingBlockSize() const; + size_t getBelongingBlockSize() const; // Access from area configuration uint64_t merge(uint64_t uiOriginData, uint64_t uiNewData) const; -private: +private: // String Access - virtual bool doSetValue(const std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; - virtual void doGetValue(std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + virtual bool doSetValue(const std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const; + virtual void doGetValue(std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const; // Generic Access template <typename type> - bool doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + bool doSet(type value, size_t offset, CParameterAccessContext ¶meterAccessContext) const; template <typename type> - void doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; - + void doGet(type &value, size_t offset, CParameterAccessContext ¶meterAccessContext) const; }; diff --git a/parameter/BitParameterBlock.cpp b/parameter/BitParameterBlock.cpp index a394aab..360a6f5 100644 --- a/parameter/BitParameterBlock.cpp +++ b/parameter/BitParameterBlock.cpp @@ -36,7 +36,8 @@ using std::string; -CBitParameterBlock::CBitParameterBlock(const string& strName, const CTypeElement* pTypeElement) : base(strName, pTypeElement) +CBitParameterBlock::CBitParameterBlock(const string &strName, const CTypeElement *pTypeElement) + : base(strName, pTypeElement) { } @@ -46,27 +47,30 @@ CInstanceConfigurableElement::Type CBitParameterBlock::getType() const } // Instantiation, allocation -uint32_t CBitParameterBlock::getFootPrint() const +size_t CBitParameterBlock::getFootPrint() const { return getSize(); } // Size -uint32_t CBitParameterBlock::getSize() const +size_t CBitParameterBlock::getSize() const { - return static_cast<const CBitParameterBlockType*>(getTypeElement())->getSize(); + return static_cast<const CBitParameterBlockType *>(getTypeElement())->getSize(); } // Used for simulation and virtual subsystems -void CBitParameterBlock::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +void CBitParameterBlock::setDefaultValues(CParameterAccessContext ¶meterAccessContext) const { - // Get default value from type - uint32_t uiDefaultValue = 0; + // Default value is 0 as their is no min bound for bit parameters, + // thus 0 is always a valid value. + // BitParameterBlock can be as long a 64 bit, thus an 64 bit long variable + // is necessary to initialize it. + uint64_t uiDefaultValue = 0; // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->writeInteger(&uiDefaultValue, getSize(), getOffset() - parameterAccessContext.getBaseOffset(), parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->writeInteger(&uiDefaultValue, getSize(), + getOffset() - parameterAccessContext.getBaseOffset()); } - diff --git a/parameter/BitParameterBlock.h b/parameter/BitParameterBlock.h index f965b30..f1068f6 100644 --- a/parameter/BitParameterBlock.h +++ b/parameter/BitParameterBlock.h @@ -34,18 +34,23 @@ class CBitParameterBlock : public CInstanceConfigurableElement { public: - CBitParameterBlock(const std::string& strName, const CTypeElement* pTypeElement); + CBitParameterBlock(const std::string &strName, const CTypeElement *pTypeElement); // Instantiation, allocation - virtual uint32_t getFootPrint() const; + virtual size_t getFootPrint() const; // Type virtual Type getType() const; // Size - uint32_t getSize() const; + size_t getSize() const; // Used for simulation and virtual subsystems - virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const; -}; + virtual void setDefaultValues(CParameterAccessContext ¶meterAccessContext) const; + void structureToXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const + { + xmlElement.setAttribute("Size", getSize() * 8); + CInstanceConfigurableElement::structureToXml(xmlElement, serializingContext); + } +}; diff --git a/parameter/BitParameterBlockType.cpp b/parameter/BitParameterBlockType.cpp index 0d344f2..316676d 100644 --- a/parameter/BitParameterBlockType.cpp +++ b/parameter/BitParameterBlockType.cpp @@ -35,7 +35,7 @@ using std::string; -CBitParameterBlockType::CBitParameterBlockType(const string& strName) : base(strName), _uiSize(0) +CBitParameterBlockType::CBitParameterBlockType(const string &strName) : base(strName) { } @@ -50,32 +50,35 @@ bool CBitParameterBlockType::childrenAreDynamic() const } // Size -uint32_t CBitParameterBlockType::getSize() const +size_t CBitParameterBlockType::getSize() const { - return _uiSize; + return _size; } // From IXmlSink -bool CBitParameterBlockType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CBitParameterBlockType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Size - _uiSize = xmlElement.getAttributeInteger("Size") / 8; + xmlElement.getAttribute("Size", _size); + _size /= 8; // Base return base::fromXml(xmlElement, serializingContext); } // Instantiation -CInstanceConfigurableElement* CBitParameterBlockType::doInstantiate() const +CInstanceConfigurableElement *CBitParameterBlockType::doInstantiate() const { return new CBitParameterBlock(getName(), this); } // From IXmlSource -void CBitParameterBlockType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CBitParameterBlockType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Size - xmlElement.setAttributeString("Size", CUtility::toString(_uiSize * 8)); + xmlElement.setAttribute("Size", _size * 8); base::toXml(xmlElement, serializingContext); } diff --git a/parameter/BitParameterBlockType.h b/parameter/BitParameterBlockType.h index 0808e94..419d7aa 100644 --- a/parameter/BitParameterBlockType.h +++ b/parameter/BitParameterBlockType.h @@ -36,25 +36,25 @@ class CBitParameterBlockType : public CTypeElement { public: - CBitParameterBlockType(const std::string& strName); + CBitParameterBlockType(const std::string &strName); // Size - uint32_t getSize() const; + size_t getSize() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // CElement virtual std::string getKind() const; + private: virtual bool childrenAreDynamic() const; // Instantiation - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; // Size in bytes - uint32_t _uiSize; + size_t _size{0}; }; - diff --git a/parameter/BitParameterType.cpp b/parameter/BitParameterType.cpp index 14fe901..5a5c353 100644 --- a/parameter/BitParameterType.cpp +++ b/parameter/BitParameterType.cpp @@ -39,7 +39,7 @@ using std::string; -CBitParameterType::CBitParameterType(const string& strName) : base(strName), _uiBitPos(0), _uiBitSize(0), _uiMax(uint64_t(-1)) +CBitParameterType::CBitParameterType(const string &strName) : base(strName) { } @@ -50,46 +50,49 @@ string CBitParameterType::getKind() const } // Element properties -void CBitParameterType::showProperties(string& strResult) const +void CBitParameterType::showProperties(string &strResult) const { base::showProperties(strResult); // Bit Pos strResult += "Bit pos: "; - strResult += CUtility::toString(_uiBitPos); + strResult += std::to_string(_bitPos); strResult += "\n"; // Bit size strResult += "Bit size: "; - strResult += CUtility::toString(_uiBitSize); + strResult += std::to_string(_uiBitSize); strResult += "\n"; // Max strResult += "Max: "; - strResult += CUtility::toString(_uiMax); + strResult += std::to_string(_uiMax); strResult += "\n"; } // From IXmlSink -bool CBitParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CBitParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Pos - _uiBitPos = xmlElement.getAttributeInteger("Pos"); + xmlElement.getAttribute("Pos", _bitPos); // Size - _uiBitSize = xmlElement.getAttributeInteger("Size"); + xmlElement.getAttribute("Size", _uiBitSize); // Validate bit pos and size still fit into parent type - const CBitParameterBlockType* pBitParameterBlockType = static_cast<const CBitParameterBlockType*>(getParent()); + const CBitParameterBlockType *pBitParameterBlockType = + static_cast<const CBitParameterBlockType *>(getParent()); - uint32_t uiParentBlockBitSize = pBitParameterBlockType->getSize() * 8; + size_t uiParentBlockBitSize = pBitParameterBlockType->getSize() * 8; - if (_uiBitPos + _uiBitSize > uiParentBlockBitSize) { + if (_bitPos + _uiBitSize > uiParentBlockBitSize) { // Range exceeded - std::ostringstream strStream; + std::ostringstream strStream; - strStream << "Pos and Size attributes inconsistent with maximum container element size (" << uiParentBlockBitSize << " bits) for " + getKind(); + strStream << "Pos and Size attributes inconsistent with maximum container element size (" + << uiParentBlockBitSize << " bits) for " + getKind(); serializingContext.setError(strStream.str()); @@ -97,24 +100,18 @@ bool CBitParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingCo } // Max - if (xmlElement.hasAttribute("Max")) { + _uiMax = getMaxEncodableValue(); + if (xmlElement.getAttribute("Max", _uiMax) && (_uiMax > getMaxEncodableValue())) { - _uiMax = xmlElement.getAttributeInteger("Max"); + // Max value exceeded + std::ostringstream strStream; - if (_uiMax > getMaxEncodableValue()) { + strStream << "Max attribute inconsistent with maximum encodable size (" + << getMaxEncodableValue() << ") for " + getKind(); - // Max value exceeded - std::ostringstream strStream; - - strStream << "Max attribute inconsistent with maximum encodable size (" << getMaxEncodableValue() << ") for " + getKind(); - - serializingContext.setError(strStream.str()); - - return false; - } - } else { + serializingContext.setError(strStream.str()); - _uiMax = getMaxEncodableValue(); + return false; } // Base @@ -122,24 +119,23 @@ bool CBitParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingCo } // Conversion -bool CBitParameterType::toBlackboard(const string& strValue, uint64_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBitParameterType::toBlackboard(const string &strValue, uint64_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { - // Hexa - bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); - // Get value uint64_t uiConvertedValue = strtoull(strValue.c_str(), NULL, 0); if (uiConvertedValue > _uiMax) { // Range exceeded - std::ostringstream strStream; + std::ostringstream strStream; strStream << "Value " << strValue << " standing out of admitted range ["; - if (bValueProvidedAsHexa) { + if (utility::isHexadecimal(strValue)) { - strStream << "0x0, " << "0x" << std::hex << std::uppercase; + strStream << "0x0, " + << "0x" << std::hex << std::uppercase; } else { strStream << "0, "; @@ -152,14 +148,15 @@ bool CBitParameterType::toBlackboard(const string& strValue, uint64_t& uiValue, } // Do bitwise RMW operation - uiValue = (uiValue & ~getMask()) | (uiConvertedValue << _uiBitPos); + uiValue = (uiValue & ~getMask()) | (uiConvertedValue << _bitPos); return true; } -void CBitParameterType::fromBlackboard(string& strValue, const uint64_t& uiValue, CParameterAccessContext& parameterAccessContext) const +void CBitParameterType::fromBlackboard(string &strValue, const uint64_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { - uint64_t uiConvertedValue = (uiValue & getMask()) >> _uiBitPos; + uint64_t uiConvertedValue = (uiValue & getMask()) >> _bitPos; // Format std::ostringstream strStream; @@ -177,7 +174,8 @@ void CBitParameterType::fromBlackboard(string& strValue, const uint64_t& uiValue // Value access // Integer -bool CBitParameterType::toBlackboard(uint64_t uiUserValue, uint64_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBitParameterType::toBlackboard(uint64_t uiUserValue, uint64_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { if (uiUserValue > _uiMax) { @@ -187,16 +185,15 @@ bool CBitParameterType::toBlackboard(uint64_t uiUserValue, uint64_t& uiValue, CP } // Do bitwise RMW operation - uiValue = (uiValue & ~getMask()) | (uiUserValue << _uiBitPos); + uiValue = (uiValue & ~getMask()) | (uiUserValue << _bitPos); return true; } -void CBitParameterType::fromBlackboard(uint32_t& uiUserValue, uint64_t uiValue, CParameterAccessContext& parameterAccessContext) const +void CBitParameterType::fromBlackboard(uint32_t &userValue, uint64_t value, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - - uiUserValue = (uiValue & getMask()) >> _uiBitPos; + userValue = static_cast<uint32_t>((value & getMask()) >> _bitPos); } // Access from area configuration @@ -206,12 +203,12 @@ uint64_t CBitParameterType::merge(uint64_t uiOriginData, uint64_t uiNewData) con } // Bit Size -uint32_t CBitParameterType::getBitSize() const +size_t CBitParameterType::getBitSize() const { return _uiBitSize; } -CInstanceConfigurableElement* CBitParameterType::doInstantiate() const +CInstanceConfigurableElement *CBitParameterType::doInstantiate() const { return new CBitParameter(getName(), this); } @@ -225,13 +222,13 @@ uint64_t CBitParameterType::getMaxEncodableValue() const // Biwise mask uint64_t CBitParameterType::getMask() const { - return getMaxEncodableValue() << _uiBitPos; + return getMaxEncodableValue() << _bitPos; } // Check data has no bit set outside available range bool CBitParameterType::isEncodable(uint64_t uiData) const { - uint32_t uiShift = 8 * sizeof(uiData) - _uiBitSize; + size_t uiShift = 8 * sizeof(uiData) - _uiBitSize; if (uiShift) { @@ -243,17 +240,17 @@ bool CBitParameterType::isEncodable(uint64_t uiData) const } // From IXmlSource -void CBitParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CBitParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Position - xmlElement.setAttributeString("Pos", CUtility::toString(_uiBitPos)); + xmlElement.setAttribute("Pos", _bitPos); // Size - xmlElement.setAttributeString("Size", CUtility::toString(_uiBitSize)); + xmlElement.setAttribute("Size", _uiBitSize); // Maximum - xmlElement.setAttributeString("Max", CUtility::toString(_uiMax)); + xmlElement.setAttribute("Max", _uiMax); base::toXml(xmlElement, serializingContext); - } diff --git a/parameter/BitParameterType.h b/parameter/BitParameterType.h index 4c91a1a..f8d67ed 100644 --- a/parameter/BitParameterType.h +++ b/parameter/BitParameterType.h @@ -34,34 +34,39 @@ #include "TypeElement.h" #include <string> +#include <limits> class CParameterAccessContext; class CBitParameterType : public CTypeElement { public: - CBitParameterType(const std::string& strName); + CBitParameterType(const std::string &strName); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; /// Conversion // String - bool toBlackboard(const std::string& strValue, uint64_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - void fromBlackboard(std::string& strValue, const uint64_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + bool toBlackboard(const std::string &strValue, uint64_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + void fromBlackboard(std::string &strValue, const uint64_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Integer - bool toBlackboard(uint64_t uiUserValue, uint64_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - void fromBlackboard(uint32_t& uiUserValue, uint64_t uiValue, CParameterAccessContext& parameterAccessContext) const; + bool toBlackboard(uint64_t uiUserValue, uint64_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + void fromBlackboard(uint32_t &uiUserValue, uint64_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Access from area configuration uint64_t merge(uint64_t uiOriginData, uint64_t uiNewData) const; // Bit Size - uint32_t getBitSize() const; + size_t getBitSize() const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // CElement virtual std::string getKind() const; @@ -72,10 +77,10 @@ public: * * @return position of the bit. */ - uint32_t getBitPos() const { return _uiBitPos; } + size_t getBitPos() const { return _bitPos; } private: // Instantiation - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; // Max encodable value uint64_t getMaxEncodableValue() const; // Biwise mask @@ -84,9 +89,9 @@ private: bool isEncodable(uint64_t uiData) const; // Pos in bits - uint32_t _uiBitPos; + size_t _bitPos{0}; // Size in bits - uint32_t _uiBitSize; + size_t _uiBitSize{0}; // Max value - uint64_t _uiMax; + uint64_t _uiMax{std::numeric_limits<uint64_t>::max()}; }; diff --git a/parameter/BitwiseAreaConfiguration.cpp b/parameter/BitwiseAreaConfiguration.cpp index 6440019..f2a09f0 100644 --- a/parameter/BitwiseAreaConfiguration.cpp +++ b/parameter/BitwiseAreaConfiguration.cpp @@ -33,17 +33,18 @@ #define base CAreaConfiguration -CBitwiseAreaConfiguration::CBitwiseAreaConfiguration(const CConfigurableElement *pConfigurableElement, const CSyncerSet *pSyncerSet) - : base(pConfigurableElement, pSyncerSet, static_cast<const CBitParameter*>(pConfigurableElement)->getBelongingBlockSize()), - _bBigEndian(pConfigurableElement->getBelongingSubsystem()->isBigEndian()) +CBitwiseAreaConfiguration::CBitwiseAreaConfiguration( + const CConfigurableElement *pConfigurableElement, const CSyncerSet *pSyncerSet) + : base(pConfigurableElement, pSyncerSet, + static_cast<const CBitParameter *>(pConfigurableElement)->getBelongingBlockSize()) { } // Blackboard copies -void CBitwiseAreaConfiguration::copyTo(CParameterBlackboard* pToBlackboard, uint32_t uiOffset) const +void CBitwiseAreaConfiguration::copyTo(CParameterBlackboard *pToBlackboard, size_t offset) const { // Beware this code works on little endian architectures only! - const CBitParameter* pBitParameter = static_cast<const CBitParameter*>(_pConfigurableElement); + const CBitParameter *pBitParameter = static_cast<const CBitParameter *>(_pConfigurableElement); uint64_t uiSrcData = 0; uint64_t uiDstData = 0; @@ -51,22 +52,22 @@ void CBitwiseAreaConfiguration::copyTo(CParameterBlackboard* pToBlackboard, uint /// Read/modify/write // Read dst blackboard - pToBlackboard->readInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), uiOffset, _bBigEndian); + pToBlackboard->readInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), offset); // Read src blackboard - _blackboard.readInteger(&uiSrcData, pBitParameter->getBelongingBlockSize(), 0, _bBigEndian); + _blackboard.readInteger(&uiSrcData, pBitParameter->getBelongingBlockSize(), 0); // Convert uiDstData = pBitParameter->merge(uiDstData, uiSrcData); // Write dst blackboard - pToBlackboard->writeInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), uiOffset, _bBigEndian); + pToBlackboard->writeInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), offset); } -void CBitwiseAreaConfiguration::copyFrom(const CParameterBlackboard* pFromBlackboard, uint32_t uiOffset) +void CBitwiseAreaConfiguration::copyFrom(const CParameterBlackboard *pFromBlackboard, size_t offset) { // Beware this code works on little endian architectures only! - const CBitParameter* pBitParameter = static_cast<const CBitParameter*>(_pConfigurableElement); + const CBitParameter *pBitParameter = static_cast<const CBitParameter *>(_pConfigurableElement); uint64_t uiSrcData = 0; uint64_t uiDstData = 0; @@ -74,15 +75,14 @@ void CBitwiseAreaConfiguration::copyFrom(const CParameterBlackboard* pFromBlackb /// Read/modify/write // Read dst blackboard - _blackboard.readInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), 0, _bBigEndian); + _blackboard.readInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), 0); // Read src blackboard - pFromBlackboard->readInteger(&uiSrcData, pBitParameter->getBelongingBlockSize(), uiOffset, _bBigEndian); + pFromBlackboard->readInteger(&uiSrcData, pBitParameter->getBelongingBlockSize(), offset); // Convert uiDstData = pBitParameter->merge(uiDstData, uiSrcData); // Write dst blackboard - _blackboard.writeInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), 0, _bBigEndian); + _blackboard.writeInteger(&uiDstData, pBitParameter->getBelongingBlockSize(), 0); } - diff --git a/parameter/BitwiseAreaConfiguration.h b/parameter/BitwiseAreaConfiguration.h index 96b972a..4a10c2c 100644 --- a/parameter/BitwiseAreaConfiguration.h +++ b/parameter/BitwiseAreaConfiguration.h @@ -36,14 +36,11 @@ class CBitParameter; class CBitwiseAreaConfiguration : public CAreaConfiguration { public: - CBitwiseAreaConfiguration(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet); + CBitwiseAreaConfiguration(const CConfigurableElement *pConfigurableElement, + const CSyncerSet *pSyncerSet); private: // Blackboard copies - virtual void copyTo(CParameterBlackboard* pToBlackboard, uint32_t uiOffset) const; - virtual void copyFrom(const CParameterBlackboard* pFromBlackboard, uint32_t uiOffset); - - // Endianness - bool _bBigEndian; + virtual void copyTo(CParameterBlackboard *pToBlackboard, size_t offset) const; + virtual void copyFrom(const CParameterBlackboard *pFromBlackboard, size_t offset); }; - diff --git a/parameter/BooleanParameterType.cpp b/parameter/BooleanParameterType.cpp index 87088ef..66556d3 100644 --- a/parameter/BooleanParameterType.cpp +++ b/parameter/BooleanParameterType.cpp @@ -29,25 +29,23 @@ */ #include "BooleanParameterType.h" #include "ParameterAccessContext.h" +#include "Utility.h" #define base CParameterType -CBooleanParameterType::CBooleanParameterType(const std::string& strName) : base(strName) +CBooleanParameterType::CBooleanParameterType(const std::string &strName) : base(strName) { setSize(1); } -CBooleanParameterType::~CBooleanParameterType() -{ -} - std::string CBooleanParameterType::getKind() const { return "BooleanParameter"; } // Tuning interface -bool CBooleanParameterType::toBlackboard(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBooleanParameterType::toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { if (strValue == "1" || strValue == "0x1") { @@ -58,10 +56,7 @@ bool CBooleanParameterType::toBlackboard(const std::string& strValue, uint32_t& } else { parameterAccessContext.setError(strValue + " value not part of numerical space {"); - // Hexa - bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); - - if (bValueProvidedAsHexa) { + if (utility::isHexadecimal(strValue)) { parameterAccessContext.appendToError("0x0, 0x1"); } else { @@ -76,7 +71,8 @@ bool CBooleanParameterType::toBlackboard(const std::string& strValue, uint32_t& return true; } -bool CBooleanParameterType::fromBlackboard(std::string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBooleanParameterType::fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { strValue = uiValue ? "1" : "0"; @@ -89,26 +85,25 @@ bool CBooleanParameterType::fromBlackboard(std::string& strValue, const uint32_t } // Value access -bool CBooleanParameterType::toBlackboard(bool bUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBooleanParameterType::toBlackboard(bool bUserValue, uint32_t &uiValue, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - uiValue = bUserValue; return true; } -bool CBooleanParameterType::fromBlackboard(bool& bUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBooleanParameterType::fromBlackboard(bool &bUserValue, uint32_t uiValue, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - bUserValue = uiValue != 0; return true; } // Integer -bool CBooleanParameterType::toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBooleanParameterType::toBlackboard(uint32_t uiUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { if (uiUserValue > 1) { @@ -120,10 +115,9 @@ bool CBooleanParameterType::toBlackboard(uint32_t uiUserValue, uint32_t& uiValue return true; } -bool CBooleanParameterType::fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CBooleanParameterType::fromBlackboard(uint32_t &uiUserValue, uint32_t uiValue, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - uiUserValue = uiValue != 0; return true; diff --git a/parameter/BooleanParameterType.h b/parameter/BooleanParameterType.h index 2f95eb7..6a88488 100644 --- a/parameter/BooleanParameterType.h +++ b/parameter/BooleanParameterType.h @@ -36,20 +36,26 @@ class CBooleanParameterType : public CParameterType { public: - CBooleanParameterType(const std::string& strName); - virtual ~CBooleanParameterType(); + CBooleanParameterType(const std::string &strName); + virtual ~CBooleanParameterType() = default; // Kind virtual std::string getKind() const; /// Conversion // String - virtual bool toBlackboard(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(std::string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Boolean - virtual bool toBlackboard(bool bUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(bool& bUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(bool bUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(bool &bUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Integer - virtual bool toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(uint32_t uiUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(uint32_t &uiUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; }; diff --git a/parameter/CMakeLists.txt b/parameter/CMakeLists.txt index 94369fb..230dd5f 100644 --- a/parameter/CMakeLists.txt +++ b/parameter/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2014-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,19 +26,23 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +if(WIN32) + set(parameter_RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/Resource.rc") + set(parameter_OS_SPECIFIC_SRCS ${parameter_RESOURCE_FILE}) +endif() + add_library(parameter SHARED + ${parameter_OS_SPECIFIC_SRCS} AreaConfiguration.cpp ArrayParameter.cpp - AutoLog.cpp BaseParameter.cpp - BinarySerializableElement.cpp - BinaryStream.cpp BitParameterBlock.cpp BitParameterBlockType.cpp BitParameter.cpp BitParameterType.cpp BitwiseAreaConfiguration.cpp BooleanParameterType.cpp + CommandHandlerWrapper.cpp ComponentInstance.cpp ComponentLibrary.cpp ComponentType.cpp @@ -55,8 +59,8 @@ add_library(parameter SHARED ElementLocator.cpp EnumParameterType.cpp EnumValuePair.cpp - ErrorContext.cpp FixedPointParameterType.cpp + FloatingPointParameterType.cpp FormattedSubsystemObject.cpp FrameworkConfigurationLocation.cpp HardwareBackSynchronizer.cpp @@ -65,6 +69,7 @@ add_library(parameter SHARED IntegerParameterType.cpp LinearParameterAdaptation.cpp LogarithmicParameterAdaptation.cpp + LoggingElementBuilderTemplate.cpp MappingContext.cpp MappingData.cpp ParameterAccessContext.cpp @@ -73,7 +78,7 @@ add_library(parameter SHARED ParameterBlockType.cpp Parameter.cpp ParameterFrameworkConfiguration.cpp - ParameterHandle.cpp + ElementHandle.cpp ParameterMgr.cpp ParameterMgrFullConnector.cpp ParameterMgrPlatformConnector.cpp @@ -103,19 +108,43 @@ add_library(parameter SHARED XmlFileIncluderElement.cpp XmlParameterSerializingContext.cpp) -include_directories( - include - "${PROJECT_SOURCE_DIR}/xmlserializer" - "${PROJECT_SOURCE_DIR}/utility" - "${PROJECT_SOURCE_DIR}/remote-processor") +include(GenerateExportHeader) +generate_export_header(parameter) + +if(WIN32) + set(WINRC_MAJOR ${PF_VERSION_MAJOR}) + set(WINRC_MINOR ${PF_VERSION_MINOR}) + set(WINRC_PATCH ${PF_VERSION_PATCH}) + set(WINRC_TWEAK ${PF_VERSION_TWEAK}) + target_compile_definitions(parameter PRIVATE + WINRC_DLL + WINRC_FILENAME="$<TARGET_FILE_NAME:parameter>") + set(WINRC_FILE_DESCRIPTION "Parameter Framework library") + configure_file("${PROJECT_SOURCE_DIR}/support/windows/Resource.rc.in" + "${parameter_RESOURCE_FILE}") +endif() + +configure_file(version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h") + +target_link_libraries(parameter + # Unfortunatly xmlSink and xmlSource need to be exposed to the plugins + PUBLIC xmlserializer + PRIVATE pfw_utility remote-processor + PRIVATE ${CMAKE_DL_LIBS}) -# No need to link with libremote-processor: it is accessed via dlopen() -find_library(dl dl) -target_link_libraries(parameter xmlserializer pfw_utility dl) +target_include_directories(parameter + PUBLIC include log/include + # Export symbol macro header + PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" + # FIXE: define . as an PUBLIC include directory only for plugins + PUBLIC .) -install(TARGETS parameter LIBRARY DESTINATION lib) +install(TARGETS parameter LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib) # Client headers install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/parameter_export.h" + include/CommandHandlerInterface.h + include/ElementHandle.h include/ParameterHandle.h include/ParameterMgrLoggerForward.h include/ParameterMgrFullConnector.h @@ -125,10 +154,9 @@ install(FILES DESTINATION "include/parameter/client") # Core (plugin) headers install(FILES - AutoLog.h + "${CMAKE_CURRENT_BINARY_DIR}/parameter_export.h" BitParameterBlockType.h ConfigurableElement.h - ConfigurableElementWithMapping.h DefaultElementLibrary.h Element.h ElementBuilder.h @@ -136,12 +164,13 @@ install(FILES FileIncluderElementBuilder.h FormattedSubsystemObject.h InstanceConfigurableElement.h + LoggingElementBuilderTemplate.h Mapper.h MappingContext.h - NamedElementBuilderTemplate.h ParameterBlockType.h ParameterType.h PathNavigator.h + Plugin.h Subsystem.h SubsystemLibrary.h SubsystemObject.h @@ -151,3 +180,5 @@ install(FILES TypeElement.h VirtualSubsystem.h DESTINATION "include/parameter/plugin") +install(DIRECTORY log/include/log/ + DESTINATION "include/parameter/plugin/log") diff --git a/parameter/CommandHandlerWrapper.cpp b/parameter/CommandHandlerWrapper.cpp new file mode 100644 index 0000000..c291f34 --- /dev/null +++ b/parameter/CommandHandlerWrapper.cpp @@ -0,0 +1,49 @@ +/* + * 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 "CommandHandlerWrapper.h" +#include <RequestMessage.h> + +CommandHandlerWrapper::CommandHandlerWrapper(std::unique_ptr<IRemoteCommandHandler> &&wrapped) + : mWrapped(std::move(wrapped)) +{ +} + +bool CommandHandlerWrapper::process(const std::string &command, + const std::vector<std::string> &arguments, std::string &output) +{ + CRequestMessage request(command); + + for (auto &arg : arguments) { + request.addArgument(arg); + } + + return mWrapped->remoteCommandProcess(request, output); +} diff --git a/parameter/BinarySerializableElement.h b/parameter/CommandHandlerWrapper.h index 222b8e9..8794018 100644 --- a/parameter/BinarySerializableElement.h +++ b/parameter/CommandHandlerWrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,20 +29,18 @@ */ #pragma once -#include "Element.h" -#include "BinaryStream.h" +#include "CommandHandlerInterface.h" +#include <RemoteCommandHandler.h> +#include <memory> -#include <string> - -class CBinarySerializableElement : public CElement +class CommandHandlerWrapper : public CommandHandlerInterface { public: - CBinarySerializableElement(const std::string& strName = ""); + CommandHandlerWrapper(std::unique_ptr<IRemoteCommandHandler> &&wrapped); - // Serialization - virtual void binarySerialize(CBinaryStream& binaryStream); + bool process(const std::string &command, const std::vector<std::string> &arguments, + std::string &output) override; - // Data size - virtual size_t getDataSize() const; -protected: +private: + std::unique_ptr<IRemoteCommandHandler> mWrapped; }; diff --git a/parameter/Component.h b/parameter/Component.h index 4ec1f71..b89ea0b 100644 --- a/parameter/Component.h +++ b/parameter/Component.h @@ -36,14 +36,11 @@ class CComponent : public CInstanceConfigurableElement { public: - CComponent(const std::string& strName, const CTypeElement* pTypeElement) : CInstanceConfigurableElement(strName, pTypeElement) + CComponent(const std::string &strName, const CTypeElement *pTypeElement) + : CInstanceConfigurableElement(strName, pTypeElement) { } // Type - virtual Type getType() const - { - return EComponent; - } + virtual Type getType() const { return EComponent; } }; - diff --git a/parameter/ComponentInstance.cpp b/parameter/ComponentInstance.cpp index f26a383..22fcdcc 100644 --- a/parameter/ComponentInstance.cpp +++ b/parameter/ComponentInstance.cpp @@ -31,17 +31,25 @@ #include "ComponentLibrary.h" #include "ComponentType.h" #include "Component.h" +#include "ParameterBlock.h" // for "array" instantiation #include "XmlParameterSerializingContext.h" #define base CTypeElement -CComponentInstance::CComponentInstance(const std::string& strName) : base(strName), _pComponentType(NULL) +CComponentInstance::CComponentInstance(const std::string &strName) : base(strName) { } std::string CComponentInstance::getKind() const { - return "Component"; + return "ComponentInstance"; +} + +std::string CComponentInstance::getXmlElementName() const +{ + // Once instantiated components are reflected as parameter blocks + // in XML documents + return "ParameterBlock"; } bool CComponentInstance::childrenAreDynamic() const @@ -49,10 +57,12 @@ bool CComponentInstance::childrenAreDynamic() const return true; } -bool CComponentInstance::getMappingData(const std::string& strKey, const std::string*& pStrValue) const +bool CComponentInstance::getMappingData(const std::string &strKey, + const std::string *&pStrValue) const { // Try myself first then associated component type - return base::getMappingData(strKey, pStrValue) || (_pComponentType && _pComponentType->getMappingData(strKey, pStrValue)); + return base::getMappingData(strKey, pStrValue) || + (_pComponentType && _pComponentType->getMappingData(strKey, pStrValue)); } bool CComponentInstance::hasMappingData() const @@ -63,36 +73,35 @@ bool CComponentInstance::hasMappingData() const std::string CComponentInstance::getFormattedMapping() const { - // Try myself first then associated component type - std::string strValue = base::getFormattedMapping(); - if (_pComponentType) { - - strValue += _pComponentType->getFormattedMapping(); - } - - return strValue; + return base::getFormattedMapping(_pComponentType); } -bool CComponentInstance::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CComponentInstance::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Context - CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext); + CXmlParameterSerializingContext ¶meterBuildContext = + static_cast<CXmlParameterSerializingContext &>(serializingContext); - const CComponentLibrary* pComponentLibrary = parameterBuildContext.getComponentLibrary(); + const CComponentLibrary *pComponentLibrary = parameterBuildContext.getComponentLibrary(); - std::string strComponentType = xmlElement.getAttributeString("Type"); + std::string strComponentType; + xmlElement.getAttribute("Type", strComponentType); _pComponentType = pComponentLibrary->getComponentType(strComponentType); if (!_pComponentType) { - serializingContext.setError("Unable to create Component " + xmlElement.getPath() + ". ComponentType " + strComponentType + " not found!"); + serializingContext.setError("Unable to create Component " + xmlElement.getPath() + + ". ComponentType " + strComponentType + " not found!"); return false; } if (_pComponentType == getParent()) { - serializingContext.setError("Recursive definition of " + _pComponentType->getName() + " due to " + xmlElement.getPath() + " referring to one of its own type."); + serializingContext.setError("Recursive definition of " + _pComponentType->getName() + + " due to " + xmlElement.getPath() + + " referring to one of its own type."); return false; } @@ -100,14 +109,35 @@ bool CComponentInstance::fromXml(const CXmlElement& xmlElement, CXmlSerializingC return base::fromXml(xmlElement, serializingContext); } -CInstanceConfigurableElement* CComponentInstance::doInstantiate() const +CInstanceConfigurableElement *CComponentInstance::doInstantiate() const { - return new CComponent(getName(), this); + if (isScalar()) { + return new CComponent(getName(), this); + } else { + return new CParameterBlock(getName(), this); + } } -void CComponentInstance::populate(CElement* pElement) const +void CComponentInstance::populate(CElement *pElement) const { - base::populate(pElement); + size_t arrayLength = getArrayLength(); - _pComponentType->populate(static_cast<CComponent*>(pElement)); + if (arrayLength != 0) { + + // Create child elements + for (size_t child = 0; child < arrayLength; child++) { + + CComponent *pChildComponent = new CComponent(std::to_string(child), this); + + pElement->addChild(pChildComponent); + + base::populate(pChildComponent); + + _pComponentType->populate(pChildComponent); + } + } else { + base::populate(pElement); + + _pComponentType->populate(static_cast<CComponent *>(pElement)); + } } diff --git a/parameter/ComponentInstance.h b/parameter/ComponentInstance.h index 0c49a54..27af963 100644 --- a/parameter/ComponentInstance.h +++ b/parameter/ComponentInstance.h @@ -38,10 +38,10 @@ class CComponentType; class CComponentInstance : public CTypeElement { public: - CComponentInstance(const std::string& strName); + CComponentInstance(const std::string &strName); // Mapping info - virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const; + virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const; virtual bool hasMappingData() const; /** * Returns the mapping associated to the current TypeElement instance @@ -51,16 +51,17 @@ public: virtual std::string getFormattedMapping() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // CElement virtual std::string getKind() const; + std::string getXmlElementName() const override; + private: virtual bool childrenAreDynamic() const; - virtual CInstanceConfigurableElement* doInstantiate() const; - virtual void populate(CElement* pElement) const; + virtual CInstanceConfigurableElement *doInstantiate() const; + virtual void populate(CElement *pElement) const; // Related component type - const CComponentType* _pComponentType; + const CComponentType *_pComponentType{nullptr}; }; - diff --git a/parameter/ComponentLibrary.cpp b/parameter/ComponentLibrary.cpp index 1c6daa2..8b27c46 100644 --- a/parameter/ComponentLibrary.cpp +++ b/parameter/ComponentLibrary.cpp @@ -31,10 +31,6 @@ #include "ComponentType.h" #include <assert.h> -CComponentLibrary::CComponentLibrary() -{ -} - bool CComponentLibrary::childrenAreDynamic() const { return true; @@ -45,13 +41,13 @@ std::string CComponentLibrary::getKind() const return "ComponentLibrary"; } -const CComponentType* CComponentLibrary::getComponentType(const std::string& strName) const +const CComponentType *CComponentLibrary::getComponentType(const std::string &strName) const { - return static_cast<const CComponentType*>(findChild(strName)); + return static_cast<const CComponentType *>(findChild(strName)); } -bool CComponentLibrary::fromXml(const CXmlElement& xmlElement, - CXmlSerializingContext& serializingContext) +bool CComponentLibrary::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { CXmlElement childElement; @@ -70,7 +66,7 @@ bool CComponentLibrary::fromXml(const CXmlElement& xmlElement, } } else { // Regular child creation and populating - CElement* pChild = createChild(childElement, serializingContext); + CElement *pChild = createChild(childElement, serializingContext); if (!pChild || !pChild->fromXml(childElement, serializingContext)) { @@ -81,4 +77,3 @@ bool CComponentLibrary::fromXml(const CXmlElement& xmlElement, return true; } - diff --git a/parameter/ComponentLibrary.h b/parameter/ComponentLibrary.h index f1445c3..572b062 100644 --- a/parameter/ComponentLibrary.h +++ b/parameter/ComponentLibrary.h @@ -40,14 +40,12 @@ class CComponentType; class CComponentLibrary : public CElement { public: - CComponentLibrary(); - - const CComponentType* getComponentType(const std::string& strName) const; + const CComponentType *getComponentType(const std::string &strName) const; virtual std::string getKind() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); private: virtual bool childrenAreDynamic() const; diff --git a/parameter/ComponentType.cpp b/parameter/ComponentType.cpp index ee71596..76fb211 100644 --- a/parameter/ComponentType.cpp +++ b/parameter/ComponentType.cpp @@ -35,7 +35,7 @@ #define base CTypeElement -CComponentType::CComponentType(const std::string& strName) : base(strName), _pExtendsComponentType(NULL) +CComponentType::CComponentType(const std::string &strName) : base(strName) { } @@ -49,36 +49,33 @@ bool CComponentType::childrenAreDynamic() const return true; } -bool CComponentType::getMappingData(const std::string& strKey, const std::string*& pStrValue) const +bool CComponentType::getMappingData(const std::string &strKey, const std::string *&pStrValue) const { // Try myself first then extended component type - return base::getMappingData(strKey, pStrValue) || (_pExtendsComponentType && _pExtendsComponentType->getMappingData(strKey, pStrValue)); + return base::getMappingData(strKey, pStrValue) || + (_pExtendsComponentType && _pExtendsComponentType->getMappingData(strKey, pStrValue)); } bool CComponentType::hasMappingData() const { // Try myself first then extended component type - return base::hasMappingData() || (_pExtendsComponentType && _pExtendsComponentType->hasMappingData()); + return base::hasMappingData() || + (_pExtendsComponentType && _pExtendsComponentType->hasMappingData()); } std::string CComponentType::getFormattedMapping() const { - // Try myself first then associated component type - std::string strValue = base::getFormattedMapping(); - if (_pExtendsComponentType) { - - strValue += _pExtendsComponentType->getFormattedMapping(); - } - - return strValue; + return base::getFormattedMapping(_pExtendsComponentType); } -bool CComponentType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CComponentType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Context - CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext); + CXmlParameterSerializingContext ¶meterBuildContext = + static_cast<CXmlParameterSerializingContext &>(serializingContext); - const CComponentLibrary* pComponentLibrary = parameterBuildContext.getComponentLibrary(); + const CComponentLibrary *pComponentLibrary = parameterBuildContext.getComponentLibrary(); // Populate children if (!base::fromXml(xmlElement, serializingContext)) { @@ -89,20 +86,23 @@ bool CComponentType::fromXml(const CXmlElement& xmlElement, CXmlSerializingConte // Check for Extends attribute (extensions will be populated after and not before) if (xmlElement.hasAttribute("Extends")) { - std::string strExtendsType = xmlElement.getAttributeString("Extends"); + std::string strExtendsType; + xmlElement.getAttribute("Extends", strExtendsType); _pExtendsComponentType = pComponentLibrary->getComponentType(strExtendsType); if (!_pExtendsComponentType) { - serializingContext.setError("ComponentType " + strExtendsType + " referred to by " + xmlElement.getPath() + " not found!"); + serializingContext.setError("ComponentType " + strExtendsType + " referred to by " + + xmlElement.getPath() + " not found!"); return false; } if (_pExtendsComponentType == this) { - serializingContext.setError("Recursive ComponentType definition of " + xmlElement.getPath()); + serializingContext.setError("Recursive ComponentType definition of " + + xmlElement.getPath()); return false; } @@ -111,7 +111,7 @@ bool CComponentType::fromXml(const CXmlElement& xmlElement, CXmlSerializingConte return true; } -void CComponentType::populate(CElement* pElement) const +void CComponentType::populate(CElement *pElement) const { // Populate children base::populate(pElement); @@ -124,7 +124,7 @@ void CComponentType::populate(CElement* pElement) const } } -CInstanceConfigurableElement* CComponentType::doInstantiate() const +CInstanceConfigurableElement *CComponentType::doInstantiate() const { // Not supposed to be called directly (instantiation made through CComponentInstance object) assert(0); diff --git a/parameter/ComponentType.h b/parameter/ComponentType.h index 3a34c92..e8c7fff 100644 --- a/parameter/ComponentType.h +++ b/parameter/ComponentType.h @@ -38,13 +38,13 @@ class CInstanceConfigurableElement; class CComponentType : public CTypeElement { public: - CComponentType(const std::string& strName); + CComponentType(const std::string &strName); // Object creation - virtual void populate(CElement* pElement) const; + virtual void populate(CElement *pElement) const; // Mapping info - virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const; + virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const; virtual bool hasMappingData() const; /** * Returns the mapping associated to the current TypeElement instance @@ -54,15 +54,16 @@ public: virtual std::string getFormattedMapping() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // CElement virtual std::string getKind() const; + private: // CElement virtual bool childrenAreDynamic() const; // Component creation - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; // Ref - const CComponentType* _pExtendsComponentType; + const CComponentType *_pExtendsComponentType{nullptr}; }; diff --git a/parameter/CompoundRule.cpp b/parameter/CompoundRule.cpp index addb31c..e69592b 100644 --- a/parameter/CompoundRule.cpp +++ b/parameter/CompoundRule.cpp @@ -35,14 +35,7 @@ using std::string; // Types -const char* CCompoundRule::_apcTypes[2] = { - "Any", - "All" -}; - -CCompoundRule::CCompoundRule() : _bTypeAll(false) -{ -} +const char *CCompoundRule::_apcTypes[2] = {"Any", "All"}; // Class kind string CCompoundRule::getKind() const @@ -57,26 +50,22 @@ bool CCompoundRule::childrenAreDynamic() const } // Content dumping -void CCompoundRule::logValue(string& strValue, CErrorContext& errorContext) const +string CCompoundRule::logValue(utility::ErrorContext & /*ctx*/) const { - (void)errorContext; - // Type - strValue = _apcTypes[_bTypeAll]; + return _apcTypes[_bTypeAll]; } // Parse -bool CCompoundRule::parse(CRuleParser& ruleParser, string& strError) +bool CCompoundRule::parse(CRuleParser &ruleParser, string &strError) { // Get rule type - uint32_t uiType; - - for (uiType = 0; uiType < 2; uiType++) { + for (size_t typeIndex = 0; typeIndex < 2; typeIndex++) { - if (ruleParser.getType() == _apcTypes[uiType]) { + if (ruleParser.getType() == _apcTypes[typeIndex]) { // Set type - _bTypeAll = uiType != 0; + _bTypeAll = typeIndex != 0; return true; } @@ -90,10 +79,9 @@ bool CCompoundRule::parse(CRuleParser& ruleParser, string& strError) } // Dump -void CCompoundRule::dump(string& strResult) const +string CCompoundRule::dump() const { - strResult += _apcTypes[_bTypeAll]; - strResult += "{"; + string output = string(_apcTypes[_bTypeAll]) + "{"; // Children size_t uiChild; @@ -104,18 +92,19 @@ void CCompoundRule::dump(string& strResult) const if (!bFirst) { - strResult += ", "; + output += ", "; } // Dump inner rule - const CRule* pRule = static_cast<const CRule*>(getChild(uiChild)); + const CRule *pRule = static_cast<const CRule *>(getChild(uiChild)); - pRule->dump(strResult); + output += pRule->dump(); bFirst = false; } - strResult += "}"; + output += "}"; + return output; } // Rule check @@ -126,7 +115,7 @@ bool CCompoundRule::matches() const for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CRule* pRule = static_cast<const CRule*>(getChild(uiChild)); + const CRule *pRule = static_cast<const CRule *>(getChild(uiChild)); if (pRule->matches() ^ _bTypeAll) { @@ -137,20 +126,23 @@ bool CCompoundRule::matches() const } // From IXmlSink -bool CCompoundRule::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CCompoundRule::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Get type - _bTypeAll = xmlElement.getAttributeBoolean("Type", _apcTypes[true]); + string strType; + xmlElement.getAttribute("Type", strType); + _bTypeAll = strType == _apcTypes[true]; // Base return base::fromXml(xmlElement, serializingContext); } // From IXmlSource -void CCompoundRule::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CCompoundRule::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const { // Set type - xmlElement.setAttributeString("Type", _apcTypes[_bTypeAll]); + xmlElement.setAttribute("Type", _apcTypes[_bTypeAll]); // Base base::toXml(xmlElement, serializingContext); diff --git a/parameter/CompoundRule.h b/parameter/CompoundRule.h index 5cac53b..712ff70 100644 --- a/parameter/CompoundRule.h +++ b/parameter/CompoundRule.h @@ -36,35 +36,34 @@ class CCompoundRule : public CRule { public: - CCompoundRule(); - // Parse - virtual bool parse(CRuleParser& ruleParser, std::string& strError); + virtual bool parse(CRuleParser &ruleParser, std::string &strError); // Dump - virtual void dump(std::string& strResult) const; + std::string dump() const override; // Rule check virtual bool matches() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // Class kind virtual std::string getKind() const; -protected: - // Content dumping - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + private: + // Content dumping + std::string logValue(utility::ErrorContext &errorContext) const override; + // Returns true if children dynamic creation is to be dealt with virtual bool childrenAreDynamic() const; // Type - bool _bTypeAll; + bool _bTypeAll{false}; // Types - static const char* _apcTypes[]; + static const char *_apcTypes[]; }; diff --git a/parameter/ConfigurableDomain.cpp b/parameter/ConfigurableDomain.cpp index 346b1f9..2a74307 100644 --- a/parameter/ConfigurableDomain.cpp +++ b/parameter/ConfigurableDomain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -34,18 +34,15 @@ #include "XmlDomainSerializingContext.h" #include "XmlDomainImportContext.h" #include "XmlDomainExportContext.h" -#include <assert.h> +#include "Utility.h" +#include "AlwaysAssert.hpp" +#include <cassert> -#define base CBinarySerializableElement +#define base CElement using std::string; -CConfigurableDomain::CConfigurableDomain() : - _bSequenceAware(false), _pLastAppliedConfiguration(NULL) -{ -} - -CConfigurableDomain::CConfigurableDomain(const string& strName) : base(strName), _bSequenceAware(false), _pLastAppliedConfiguration(NULL) +CConfigurableDomain::CConfigurableDomain(const string &strName) : base(strName) { } @@ -56,7 +53,7 @@ CConfigurableDomain::~CConfigurableDomain() for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - CConfigurableElement* pConfigurableElement = *it; + CConfigurableElement *pConfigurableElement = *it; // Remove from configurable element pConfigurableElement->removeAttachedConfigurableDomain(this); @@ -65,7 +62,8 @@ CConfigurableDomain::~CConfigurableDomain() // Remove all associated syncer sets ConfigurableElementToSyncerSetMapIterator mapIt; - for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) { + for (mapIt = _configurableElementToSyncerSetMap.begin(); + mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) { delete mapIt->second; } @@ -82,21 +80,16 @@ bool CConfigurableDomain::childrenAreDynamic() const } // Content dumping -void CConfigurableDomain::logValue(string& strValue, CErrorContext& errorContext) const +string CConfigurableDomain::logValue(utility::ErrorContext & /*ctx*/) const { - (void)errorContext; + return string("{") + - strValue = "{"; - - // Sequence awareness - strValue += "Sequence aware: "; - strValue += _bSequenceAware ? "yes" : "no"; + "Sequence aware: " + (_bSequenceAware ? "yes" : "no") + - // Last applied configuration - strValue += ", Last applied configuration: "; - strValue += _pLastAppliedConfiguration ? _pLastAppliedConfiguration->getName() : "<none>"; + ", Last applied configuration: " + + (_pLastAppliedConfiguration ? _pLastAppliedConfiguration->getName() : "<none>") + - strValue += "}"; + "}"; } // Sequence awareness @@ -104,8 +97,6 @@ void CConfigurableDomain::setSequenceAwareness(bool bSequenceAware) { if (_bSequenceAware != bSequenceAware) { - log_info("Making domain \"%s\" sequence %s", getName().c_str(), bSequenceAware ? "aware" : "unaware"); - _bSequenceAware = bSequenceAware; } } @@ -116,16 +107,17 @@ bool CConfigurableDomain::getSequenceAwareness() const } // From IXmlSource -void CConfigurableDomain::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CConfigurableDomain::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { base::toXml(xmlElement, serializingContext); // Sequence awareness - xmlElement.setAttributeBoolean("SequenceAware", _bSequenceAware); + xmlElement.setAttribute("SequenceAware", _bSequenceAware); } -void CConfigurableDomain::childrenToXml(CXmlElement& xmlElement, - CXmlSerializingContext& serializingContext) const +void CConfigurableDomain::childrenToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Configurations composeDomainConfigurations(xmlElement, serializingContext); @@ -134,11 +126,12 @@ void CConfigurableDomain::childrenToXml(CXmlElement& xmlElement, composeConfigurableElements(xmlElement); // Settings - composeSettings(xmlElement, serializingContext); + composeSettings(xmlElement, static_cast<CXmlDomainExportContext &>(serializingContext)); } // XML composing -void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CConfigurableDomain::composeDomainConfigurations( + CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const { // Create Configurations element CXmlElement xmlConfigurationsElement; @@ -149,7 +142,7 @@ void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, C base::childrenToXml(xmlConfigurationsElement, serializingContext); } -void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) const +void CConfigurableDomain::composeConfigurableElements(CXmlElement &xmlElement) const { // Create ConfigurableElements element CXmlElement xmlConfigurableElementsElement; @@ -161,25 +154,23 @@ void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) c for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; // Create corresponding XML child element CXmlElement xmlChildConfigurableElement; - xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement"); + xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, + "ConfigurableElement"); // Set Path attribute - xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath()); + xmlChildConfigurableElement.setAttribute("Path", pConfigurableElement->getPath()); } } -void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CConfigurableDomain::composeSettings(CXmlElement &xmlElement, + CXmlDomainExportContext &context) const { - // Context - const CXmlDomainExportContext& xmlDomainExportContext = - static_cast<const CXmlDomainExportContext&>(serializingContext); - - if (!xmlDomainExportContext.withSettings()) { + if (!context.withSettings()) { return; } @@ -193,34 +184,40 @@ void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializi size_t uiNbConfigurations = getNbChildren(); size_t uiChildConfiguration; - for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) { + for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; + uiChildConfiguration++) { - const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration)); + const CDomainConfiguration *pDomainConfiguration = + static_cast<const CDomainConfiguration *>(getChild(uiChildConfiguration)); // Create child xml element for that configuration CXmlElement xmlConfigurationSettingsElement; - xmlSettingsElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind()); + xmlSettingsElement.createChild(xmlConfigurationSettingsElement, + pDomainConfiguration->getXmlElementName()); // Set its name attribute xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName()); // Serialize out configuration settings - pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, serializingContext); + pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, context); } } // From IXmlSink -bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CConfigurableDomain::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Context - CXmlDomainImportContext& xmlDomainImportContext = - static_cast<CXmlDomainImportContext&>(serializingContext); + CXmlDomainImportContext &xmlDomainImportContext = + static_cast<CXmlDomainImportContext &>(serializingContext); // Sequence awareness (optional) - _bSequenceAware = xmlElement.hasAttribute("SequenceAware") && xmlElement.getAttributeBoolean("SequenceAware"); + xmlElement.getAttribute("SequenceAware", _bSequenceAware); - setName(xmlElement.getAttributeString("Name")); + std::string name; + xmlElement.getAttribute("Name", name); + setName(name); // Local parsing. Do not dig if (!parseDomainConfigurations(xmlElement, xmlDomainImportContext) || @@ -231,7 +228,8 @@ bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializing } // All provided configurations are parsed - // Attempt validation on areas of non provided configurations for all configurable elements if required + // Attempt validation on areas of non provided configurations for all configurable elements if + // required if (xmlDomainImportContext.autoValidationRequired()) { autoValidateAll(); @@ -241,8 +239,8 @@ bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializing } // XML parsing -bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement, - CXmlDomainImportContext& serializingContext) +bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement &xmlElement, + CXmlDomainImportContext &serializingContext) { // We're supposedly clean assert(_configurableElementList.empty()); @@ -257,10 +255,10 @@ bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElemen } // Parse configurable elements -bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement, - CXmlDomainImportContext& serializingContext) +bool CConfigurableDomain::parseConfigurableElements(const CXmlElement &xmlElement, + CXmlDomainImportContext &serializingContext) { - CSystemClass& systemClass = serializingContext.getSystemClass(); + CSystemClass &systemClass = serializingContext.getSystemClass(); // Get ConfigurableElements element CXmlElement xmlConfigurableElementsElement; @@ -274,7 +272,8 @@ bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElemen while (it.next(xmlConfigurableElementElement)) { // Locate configurable element - string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path"); + string strConfigurableElementPath; + xmlConfigurableElementElement.getAttribute("Path", strConfigurableElementPath); CPathNavigator pathNavigator(strConfigurableElementPath); string strError; @@ -282,23 +281,29 @@ bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElemen // Is there an element and does it match system class name? if (!pathNavigator.navigateThrough(systemClass.getName(), strError)) { - serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")"); + serializingContext.setError( + "Could not find configurable element of path " + strConfigurableElementPath + + " from ConfigurableDomain description " + getName() + " (" + strError + ")"); return false; } // Browse system class for configurable element - CConfigurableElement* pConfigurableElement = - static_cast<CConfigurableElement*>(systemClass.findDescendant(pathNavigator)); + CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(systemClass.findDescendant(pathNavigator)); if (!pConfigurableElement) { - serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName()); + serializingContext.setError("Could not find configurable element of path " + + strConfigurableElementPath + + " from ConfigurableDomain description " + getName()); return false; } // Add found element to domain - if (!addConfigurableElement(pConfigurableElement, NULL, strError)) { + core::Results infos; + if (!addConfigurableElement(pConfigurableElement, NULL, infos)) { + strError = utility::asString(infos); serializingContext.setError(strError); return false; @@ -309,8 +314,8 @@ bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElemen } // Parse settings -bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement, - CXmlDomainImportContext& serializingContext) +bool CConfigurableDomain::parseSettings(const CXmlElement &xmlElement, + CXmlDomainImportContext &serializingContext) { // Check we actually need to parse configuration settings if (!serializingContext.withSettings()) { @@ -334,12 +339,14 @@ bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement, while (it.next(xmlConfigurationSettingsElement)) { // Get domain configuration - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute())); + CDomainConfiguration *pDomainConfiguration = static_cast<CDomainConfiguration *>( + findChild(xmlConfigurationSettingsElement.getNameAttribute())); if (!pDomainConfiguration) { serializingContext.setError("Could not find domain configuration referred to by" - " configurable domain \"" + getName() + "\"."); + " configurable domain \"" + + getName() + "\"."); return false; } @@ -354,12 +361,15 @@ bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement, return true; } // Configurable elements association -bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError) +bool CConfigurableDomain::addConfigurableElement(CConfigurableElement *pConfigurableElement, + const CParameterBlackboard *pMainBlackboard, + core::Results &infos) { // Already associated? if (containsConfigurableElement(pConfigurableElement)) { - strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName(); + infos.push_back("Configurable element " + pConfigurableElement->getPath() + + " already associated to configuration domain " + getName()); return false; } @@ -367,27 +377,29 @@ bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigur // Already owned? if (pConfigurableElement->belongsTo(this)) { - strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName(); + infos.push_back("Configurable element " + pConfigurableElement->getPath() + + " already owned by configuration domain " + getName()); return false; } // Do add - doAddConfigurableElement(pConfigurableElement, pMainBlackboard); + doAddConfigurableElement(pConfigurableElement, infos, pMainBlackboard); return true; } -bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError) +bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement *pConfigurableElement, + string &strError) { // Not associated? if (!containsConfigurableElement(pConfigurableElement)) { - strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName(); + strError = "Configurable element " + pConfigurableElement->getPath() + + " not associated to configuration domain " + getName(); return false; } - log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str()); // Do remove doRemoveConfigurableElement(pConfigurableElement, true); @@ -407,21 +419,21 @@ bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfi * @param[in] strConfiguration Name of the Configuration. * @param[in] pCandidateDescendantConfigurableElement Pointer to a CConfigurableElement that * belongs to the Domain. -* @param[out] uiBaseOffset The base offset of the CConfigurableElement. +* @param[out] baseOffset The base offset of the CConfigurableElement. * @param[out] bIsLastApplied Boolean indicating that the Configuration is * the last one applied of the Domain. * @param[out] strError Error message * * return Pointer to the Blackboard of the Configuration. */ -CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const string& strConfiguration, - const CConfigurableElement* pCandidateDescendantConfigurableElement, - uint32_t& uiBaseOffset, - bool& bIsLastApplied, - string& strError) const +CParameterBlackboard *CConfigurableDomain::findConfigurationBlackboard( + const string &strConfiguration, + const CConfigurableElement *pCandidateDescendantConfigurableElement, size_t &baseOffset, + bool &bIsLastApplied, string &strError) const { // Find Configuration - const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration)); + const CDomainConfiguration *pDomainConfiguration = + static_cast<const CDomainConfiguration *>(findChild(strConfiguration)); if (!pDomainConfiguration) { @@ -435,13 +447,14 @@ CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const str for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - const CConfigurableElement* pAssociatedConfigurableElement = *it; + const CConfigurableElement *pAssociatedConfigurableElement = *it; // Check if the the associated element is the configurable element or one of its ancestors if ((pCandidateDescendantConfigurableElement == pAssociatedConfigurableElement) || - (pCandidateDescendantConfigurableElement->isDescendantOf(pAssociatedConfigurableElement))) { + (pCandidateDescendantConfigurableElement->isDescendantOf( + pAssociatedConfigurableElement))) { - uiBaseOffset = pAssociatedConfigurableElement->getOffset(); + baseOffset = pAssociatedConfigurableElement->getOffset(); bIsLastApplied = (pDomainConfiguration == _pLastAppliedConfiguration); return pDomainConfiguration->getBlackboard(pAssociatedConfigurableElement); @@ -454,62 +467,69 @@ CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const str } // Domain splitting -bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError) +bool CConfigurableDomain::split(CConfigurableElement *pConfigurableElement, core::Results &infos) { // Not associated? if (!containsConfigurableElement(pConfigurableElement)) { - strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName(); + std::string strError = "Configurable element " + pConfigurableElement->getPath() + + " not associated to configuration domain " + getName(); + infos.push_back(strError); return false; } - log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str()); // Create sub domain areas for all configurable element's children size_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren(); if (!uiNbConfigurableElementChildren) { - strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to"; + std::string strError = "Configurable element " + pConfigurableElement->getPath() + + " has no children to split configurable domain to"; + infos.push_back(strError); return false; } - size_t uiChild; - - for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) { - CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild)); + CConfigurableElement *pChildConfigurableElement = + static_cast<CConfigurableElement *>(pConfigurableElement->getChild(uiChild)); - doAddConfigurableElement(pChildConfigurableElement); + doAddConfigurableElement(pChildConfigurableElement, infos); } // Delegate to configurations size_t uiNbConfigurations = getNbChildren(); - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); pDomainConfiguration->split(pConfigurableElement); } // Remove given configurable element from this domain - // Note: we shouldn't need to recompute the sync set in that case, as the splitted element should include the syncers of its children elements + // Note: we shouldn't need to recompute the sync set in that case, as the splitted element + // should include the syncers of its children elements doRemoveConfigurableElement(pConfigurableElement, false); return true; } -// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration -const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const +// Check if there is a pending configuration for this domain: i.e. an applicable configuration +// different from the last applied configuration +const CDomainConfiguration *CConfigurableDomain::getPendingConfiguration() const { - const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration(); + const CDomainConfiguration *pApplicableDomainConfiguration = + findApplicableDomainConfiguration(); if (pApplicableDomainConfiguration) { // Check not the last one before applying - if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) { + if (!_pLastAppliedConfiguration || + (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) { return pApplicableDomainConfiguration; } @@ -519,11 +539,12 @@ const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const } // Configuration application if required -void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const +void CConfigurableDomain::apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet *pSyncerSet, + bool bForce, std::string &strInfo) const { // Apply configuration only if the blackboard will // be synchronized either now or by syncerSet. - if(!pSyncerSet ^ _bSequenceAware) { + if (!pSyncerSet ^ _bSequenceAware) { // The configuration can not be syncronised return; } @@ -532,16 +553,17 @@ void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyn // Force a configuration restore by forgetting about last applied configuration _pLastAppliedConfiguration = NULL; } - const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration(); + const CDomainConfiguration *pApplicableDomainConfiguration = + findApplicableDomainConfiguration(); if (pApplicableDomainConfiguration) { // Check not the last one before applying - if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) { + if (!_pLastAppliedConfiguration || + _pLastAppliedConfiguration != pApplicableDomainConfiguration) { - log_info("Applying configuration \"%s\" from domain \"%s\"", - pApplicableDomainConfiguration->getName().c_str(), - getName().c_str()); + strInfo = "Applying configuration '" + pApplicableDomainConfiguration->getName() + + "' from domain '" + getName() + "'"; // Check if we need to synchronize during restore bool bSync = !pSyncerSet && _bSequenceAware; @@ -563,11 +585,14 @@ void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyn } // Return applicable configuration validity for given configurable element -bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const +bool CConfigurableDomain::isApplicableConfigurationValid( + const CConfigurableElement *pConfigurableElement) const { - const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration(); + const CDomainConfiguration *pApplicableDomainConfiguration = + findApplicableDomainConfiguration(); - return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement); + return pApplicableDomainConfiguration && + pApplicableDomainConfiguration->isValid(pConfigurableElement); } // In case configurable element was removed @@ -579,16 +604,19 @@ void CConfigurableDomain::computeSyncSet() // Add syncer sets for all associated configurable elements ConfigurableElementToSyncerSetMapIterator mapIt; - for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) { + for (mapIt = _configurableElementToSyncerSetMap.begin(); + mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) { - const CSyncerSet* pSyncerSet = mapIt->second; + const CSyncerSet *pSyncerSet = mapIt->second; _syncerSet += *pSyncerSet; } } // Configuration Management -bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError) +bool CConfigurableDomain::createConfiguration(const string &strName, + const CParameterBlackboard *pMainBlackboard, + string &strError) { // Already exists? if (findChild(strName)) { @@ -597,20 +625,20 @@ bool CConfigurableDomain::createConfiguration(const string& strName, const CPara return false; } - log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str()); // Creation - CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName); + CDomainConfiguration *pDomainConfiguration = new CDomainConfiguration(strName); // Configurable elements association ConfigurableElementListIterator it; for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it;; + const CConfigurableElement *pConfigurableElement = *it; + ; // Retrieve associated syncer set - CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement); + CSyncerSet *pSyncerSet = getSyncerSet(pConfigurableElement); // Associate to configuration pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet); @@ -623,24 +651,23 @@ bool CConfigurableDomain::createConfiguration(const string& strName, const CPara // Attempt auto validation, so that the user gets his/her own settings by defaults if (!autoValidateConfiguration(pDomainConfiguration)) { - // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts) + // No valid configuration found to copy in from, validate againt main blackboard (will + // concerned remaining invalid parts) pDomainConfiguration->validate(pMainBlackboard); } return true; } -bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError) +bool CConfigurableDomain::deleteConfiguration(const string &strName, string &strError) { - CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError); + CDomainConfiguration *pDomainConfiguration = findConfiguration(strName, strError); if (!pDomainConfiguration) { return false; } - log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str()); - // Was the last applied? if (pDomainConfiguration == _pLastAppliedConfiguration) { @@ -657,72 +684,72 @@ bool CConfigurableDomain::deleteConfiguration(const string& strName, string& str return true; } -void CConfigurableDomain::listAssociatedToElements(string& strResult) const +void CConfigurableDomain::listAssociatedToElements(string &strResult) const { - strResult = "\n"; - ConfigurableElementListIterator it; // Browse all configurable elements for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; strResult += pConfigurableElement->getPath() + "\n"; } } -bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError) +bool CConfigurableDomain::renameConfiguration(const string &strName, const string &strNewName, + string &strError) { - CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError); + CDomainConfiguration *pDomainConfiguration = findConfiguration(strName, strError); if (!pDomainConfiguration) { return false; } - log_info("Renaming domain \"%s\"'s configuration \"%s\" to \"%s\"", getName().c_str(), strName.c_str(), strNewName.c_str()); // Rename return pDomainConfiguration->rename(strNewName, strError); } -bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const +bool CConfigurableDomain::restoreConfiguration(const string &configurationName, + CParameterBlackboard *mainBlackboard, bool autoSync, + core::Results &errors) const { - string strError; + string error; - const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError); + const CDomainConfiguration *configuration = findConfiguration(configurationName, error); - if (!pDomainConfiguration) { + if (configuration == NULL) { - lstrError.push_back(strError); + errors.push_back(error); return false; } - log_info("Restoring domain \"%s\"'s configuration \"%s\" to parameter blackboard", getName().c_str(), pDomainConfiguration->getName().c_str()); // Delegate - bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError); + bool bSuccess = configuration->restore(mainBlackboard, autoSync && _bSequenceAware, &errors); // Record last applied configuration - _pLastAppliedConfiguration = pDomainConfiguration; + _pLastAppliedConfiguration = configuration; // Synchronize - if (bAutoSync && !_bSequenceAware) { + if (autoSync && !_bSequenceAware) { - bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError); + bSuccess &= _syncerSet.sync(*mainBlackboard, false, &errors); } return bSuccess; } -bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError) +bool CConfigurableDomain::saveConfiguration(const string &strName, + const CParameterBlackboard *pMainBlackboard, + string &strError) { // Find Domain configuration - CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError); + CDomainConfiguration *pDomainConfiguration = findConfiguration(strName, strError); if (!pDomainConfiguration) { return false; } - log_info("Saving domain \"%s\"'s configuration \"%s\" from parameter blackboard", getName().c_str(), pDomainConfiguration->getName().c_str()); // Delegate pDomainConfiguration->save(pMainBlackboard); @@ -730,10 +757,12 @@ bool CConfigurableDomain::saveConfiguration(const string& strName, const CParame return true; } -bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError) +bool CConfigurableDomain::setElementSequence(const string &strConfiguration, + const std::vector<string> &astrNewElementSequence, + string &strError) { // Find Domain configuration - CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError); + CDomainConfiguration *pDomainConfiguration = findConfiguration(strConfiguration, strError); if (!pDomainConfiguration) { @@ -744,10 +773,12 @@ bool CConfigurableDomain::setElementSequence(const string& strConfiguration, con return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError); } -bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const +bool CConfigurableDomain::getElementSequence(const string &strConfiguration, + string &strResult) const { // Find Domain configuration - const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult); + const CDomainConfiguration *pDomainConfiguration = + findConfiguration(strConfiguration, strResult); if (!pDomainConfiguration) { @@ -760,10 +791,12 @@ bool CConfigurableDomain::getElementSequence(const string& strConfiguration, str return true; } -bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError) +bool CConfigurableDomain::setApplicationRule( + const string &strConfiguration, const string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, string &strError) { // Find Domain configuration - CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError); + CDomainConfiguration *pDomainConfiguration = findConfiguration(strConfiguration, strError); if (!pDomainConfiguration) { @@ -771,13 +804,14 @@ bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, con } // Delegate to configuration - return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError); + return pDomainConfiguration->setApplicationRule(strApplicationRule, + pSelectionCriteriaDefinition, strError); } -bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError) +bool CConfigurableDomain::clearApplicationRule(const string &strConfiguration, string &strError) { // Find Domain configuration - CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError); + CDomainConfiguration *pDomainConfiguration = findConfiguration(strConfiguration, strError); if (!pDomainConfiguration) { @@ -790,10 +824,12 @@ bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, s return true; } -bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const +bool CConfigurableDomain::getApplicationRule(const string &strConfiguration, + string &strResult) const { // Find Domain configuration - const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult); + const CDomainConfiguration *pDomainConfiguration = + findConfiguration(strConfiguration, strResult); if (!pDomainConfiguration) { @@ -801,7 +837,7 @@ bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, str } // Delegate to configuration - pDomainConfiguration->getApplicationRule(strResult); + strResult = pDomainConfiguration->getApplicationRule(); return true; } @@ -819,49 +855,61 @@ string CConfigurableDomain::getLastAppliedConfigurationName() const // Pending configuration string CConfigurableDomain::getPendingConfigurationName() const { - const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration(); + const CDomainConfiguration *pApplicableDomainConfiguration = + findApplicableDomainConfiguration(); - if (pPendingConfiguration) { + if (!pApplicableDomainConfiguration) { - return pPendingConfiguration->getName(); + // No configuration is pending + return "<none>"; + } + + // Check it will be applied + if (pApplicableDomainConfiguration != _pLastAppliedConfiguration) { + + // Found config will get applied + return pApplicableDomainConfiguration->getName(); + } else { + + // Same configuration as current + return ""; } - return "<none>"; } // Ensure validity on whole domain from main blackboard -void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard) +void CConfigurableDomain::validate(const CParameterBlackboard *pMainBlackboard) { // Propagate size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); pDomainConfiguration->validate(pMainBlackboard); } } // Ensure validity on areas related to configurable element -void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard) +void CConfigurableDomain::validateAreas(const CConfigurableElement *pConfigurableElement, + const CParameterBlackboard *pMainBlackboard) { - log_info("Validating domain \"%s\" against main blackboard for configurable element \"%s\"", getName().c_str(), pConfigurableElement->getPath().c_str()); - // Propagate size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard); } } -// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain +// Attempt validation for all configurable element's areas, relying on already existing valid +// configuration inside domain void CConfigurableDomain::autoValidateAll() { // Validate @@ -870,18 +918,20 @@ void CConfigurableDomain::autoValidateAll() // Browse all configurable elements for configuration validation for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; // Auto validate element autoValidateAreas(pConfigurableElement); } } -// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain -void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement) +// Attempt validation for configurable element's areas, relying on already existing valid +// configuration inside domain +void CConfigurableDomain::autoValidateAreas(const CConfigurableElement *pConfigurableElement) { // Find first valid configuration for given configurable element - const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement); + const CDomainConfiguration *pValidDomainConfiguration = + findValidDomainConfiguration(pConfigurableElement); // No valid configuration found, give up if (!pValidDomainConfiguration) { @@ -891,29 +941,31 @@ void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigu // Validate all other configurations against found one, if any size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); - if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) { + if (pDomainConfiguration != pValidDomainConfiguration && + !pDomainConfiguration->isValid(pConfigurableElement)) { // Validate pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement); } } } -// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain -bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration) +// Attempt configuration validation for all configurable elements' areas, relying on already +// existing valid configuration inside domain +bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration *pDomainConfiguration) { // Find another configuration than this one, that ought to be valid! size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild)); + const CDomainConfiguration *pPotententialValidDomainConfiguration = + static_cast<const CDomainConfiguration *>(getChild(uiChild)); if (pPotententialValidDomainConfiguration != pDomainConfiguration) { @@ -927,14 +979,15 @@ bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomai } // Search for a valid configuration for given configurable element -const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const +const CDomainConfiguration *CConfigurableDomain::findValidDomainConfiguration( + const CConfigurableElement *pConfigurableElement) const { size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild)); + const CDomainConfiguration *pDomainConfiguration = + static_cast<const CDomainConfiguration *>(getChild(uiChild)); if (pDomainConfiguration->isValid(pConfigurableElement)) { @@ -945,14 +998,14 @@ const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(co } // Search for an applicable configuration -const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const +const CDomainConfiguration *CConfigurableDomain::findApplicableDomainConfiguration() const { size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild)); + const CDomainConfiguration *pDomainConfiguration = + static_cast<const CDomainConfiguration *>(getChild(uiChild)); if (pDomainConfiguration->isApplicable()) { @@ -963,14 +1016,16 @@ const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfigurati } // Gather set of configurable elements -void CConfigurableDomain::gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const +void CConfigurableDomain::gatherConfigurableElements( + std::set<const CConfigurableElement *> &configurableElementSet) const { // Insert all configurable elements configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end()); } // Check configurable element already attached -bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const +bool CConfigurableDomain::containsConfigurableElement( + const CConfigurableElement *pConfigurableCandidateElement) const { ConfigurableElementListIterator it; @@ -986,23 +1041,27 @@ bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement } // Merge any descended configurable element to this one with this one -void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement) +void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements( + CConfigurableElement *newElement, core::Results &infos) { - std::list<CConfigurableElement*> mergedConfigurableElementList; + std::list<CConfigurableElement *> mergedConfigurableElementList; ConfigurableElementListIterator it; // Browse all configurable elements (new one not yet in the list!) for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) { - CConfigurableElement* pConfigurablePotentialDescendantElement = *it; + CConfigurableElement *pConfigurablePotentialDescendantElement = *it; - if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) { + if (pConfigurablePotentialDescendantElement->isDescendantOf(newElement)) { - log_info("In domain \"%s\", merging descendant configurable element's configurations \"%s\" into its ascendant \"%s\" ones", getName().c_str(), pConfigurablePotentialDescendantElement->getName().c_str(), pNewConfigurableElement->getName().c_str()); + infos.push_back("In domain '" + getName() + + "', merging descendant configurable element's configurations '" + + pConfigurablePotentialDescendantElement->getName() + + "' into its ascendant '" + newElement->getName() + "' ones"); // Merge configuration data - mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement); + mergeConfigurations(newElement, pConfigurablePotentialDescendantElement); // Keep track for removal mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement); @@ -1010,25 +1069,28 @@ void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(C } // Remove all merged elements (new one not yet in the list!) - for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) { + for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); + ++it) { - CConfigurableElement* pMergedConfigurableElement = *it; + CConfigurableElement *pMergedConfigurableElement = *it; // Remove merged from configurable element from internal tracking list - // Note: we shouldn't need to recompute the sync set in that case, as the merged to element should include the syncers of merged from elements + // Note: we shouldn't need to recompute the sync set in that case, as the merged to element + // should include the syncers of merged from elements doRemoveConfigurableElement(pMergedConfigurableElement, false); } } -void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement) +void CConfigurableDomain::mergeConfigurations(CConfigurableElement *pToConfigurableElement, + CConfigurableElement *pFromConfigurableElement) { // Propagate to domain configurations size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); // Do the merge. pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement); @@ -1036,13 +1098,15 @@ void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigura } // Configurable elements association -void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard) +void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement *pConfigurableElement, + core::Results &infos, + const CParameterBlackboard *pMainBlackboard) { // Inform configurable element pConfigurableElement->addAttachedConfigurableDomain(this); // Create associated syncer set - CSyncerSet* pSyncerSet = new CSyncerSet; + CSyncerSet *pSyncerSet = new CSyncerSet; // Add to sync set the configurable element one pConfigurableElement->fillSyncerSet(*pSyncerSet); @@ -1055,11 +1119,11 @@ void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfig // Inform configurations size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet); } @@ -1067,24 +1131,28 @@ void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfig // Ensure area validity for that configurable element (if main blackboard provided) if (pMainBlackboard) { + infos.push_back("Validating domain '" + getName() + + "' against main blackboard for configurable element '" + + pConfigurableElement->getPath() + "'"); // Need to validate against main blackboard validateAreas(pConfigurableElement, pMainBlackboard); } // Already associated descendend configurable elements need a merge of their configuration data - mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement); + mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement, infos); // Add to list _configurableElementList.push_back(pConfigurableElement); } -void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet) +void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement *pConfigurableElement, + bool bRecomputeSyncSet) { // Remove from list _configurableElementList.remove(pConfigurableElement); // Remove associated syncer set - CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement); + CSyncerSet *pSyncerSet = getSyncerSet(pConfigurableElement); _configurableElementToSyncerSetMap.erase(pConfigurableElement); @@ -1095,11 +1163,11 @@ void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pCon // Inform configurations size_t uiNbConfigurations = getNbChildren(); - size_t uiChild; - for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { + for (size_t uiChild = 0; uiChild < uiNbConfigurations; uiChild++) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(getChild(uiChild)); pDomainConfiguration->removeConfigurableElement(pConfigurableElement); } @@ -1111,19 +1179,24 @@ void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pCon } // Syncer set retrieval from configurable element -CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const +CSyncerSet *CConfigurableDomain::getSyncerSet( + const CConfigurableElement *pConfigurableElement) const { - ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement); + ConfigurableElementToSyncerSetMapIterator mapIt = + _configurableElementToSyncerSetMap.find(pConfigurableElement); - assert(mapIt != _configurableElementToSyncerSetMap.end()); + ALWAYS_ASSERT(mapIt != _configurableElementToSyncerSetMap.end(), + "Could not find syncer set for " << getName() << " configurable domain"); return mapIt->second; } // Configuration retrieval -CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) +CDomainConfiguration *CConfigurableDomain::findConfiguration(const string &strConfiguration, + string &strError) { - CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration)); + CDomainConfiguration *pDomainConfiguration = + static_cast<CDomainConfiguration *>(findChild(strConfiguration)); if (!pDomainConfiguration) { @@ -1134,9 +1207,11 @@ CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strCo return pDomainConfiguration; } -const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const +const CDomainConfiguration *CConfigurableDomain::findConfiguration(const string &strConfiguration, + string &strError) const { - const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration)); + const CDomainConfiguration *pDomainConfiguration = + static_cast<const CDomainConfiguration *>(findChild(strConfiguration)); if (!pDomainConfiguration) { diff --git a/parameter/ConfigurableDomain.h b/parameter/ConfigurableDomain.h index a29c1ba..256e602 100644 --- a/parameter/ConfigurableDomain.h +++ b/parameter/ConfigurableDomain.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,10 +29,11 @@ */ #pragma once -#include "BinarySerializableElement.h" #include "XmlSerializingContext.h" #include "XmlDomainImportContext.h" +#include "XmlDomainExportContext.h" #include "SyncerSet.h" +#include "Results.h" #include <list> #include <set> #include <map> @@ -43,13 +44,15 @@ class CDomainConfiguration; class CParameterBlackboard; class CSelectionCriteriaDefinition; -class CConfigurableDomain : public CBinarySerializableElement +class CConfigurableDomain : public CElement { - typedef std::list<CConfigurableElement*>::const_iterator ConfigurableElementListIterator; - typedef std::map<const CConfigurableElement*, CSyncerSet*>::const_iterator ConfigurableElementToSyncerSetMapIterator; + typedef std::list<CConfigurableElement *>::const_iterator ConfigurableElementListIterator; + typedef std::map<const CConfigurableElement *, CSyncerSet *>::const_iterator + ConfigurableElementToSyncerSetMapIterator; + public: - CConfigurableDomain(); - CConfigurableDomain(const std::string& strName); + CConfigurableDomain() = default; + CConfigurableDomain(const std::string &strName); virtual ~CConfigurableDomain(); // Sequence awareness @@ -57,16 +60,36 @@ public: bool getSequenceAwareness() const; // Configuration Management - bool createConfiguration(const std::string& strName, const CParameterBlackboard* pMainBlackboard, std::string& strError); - bool deleteConfiguration(const std::string& strName, std::string& strError); - bool renameConfiguration(const std::string& strName, const std::string& strNewName, std::string& strError); - bool restoreConfiguration(const std::string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<std::string>& strError) const; - bool saveConfiguration(const std::string& strName, const CParameterBlackboard* pMainBlackboard, std::string& strError); - bool setElementSequence(const std::string& strConfiguration, const std::vector<std::string>& astrNewElementSequence, std::string& strError); - bool getElementSequence(const std::string& strConfiguration, std::string& strResult) const; - bool setApplicationRule(const std::string& strConfiguration, const std::string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, std::string& strError); - bool clearApplicationRule(const std::string& strConfiguration, std::string& strError); - bool getApplicationRule(const std::string& strConfiguration, std::string& strResult) const; + bool createConfiguration(const std::string &strName, + const CParameterBlackboard *pMainBlackboard, std::string &strError); + bool deleteConfiguration(const std::string &strName, std::string &strError); + bool renameConfiguration(const std::string &strName, const std::string &strNewName, + std::string &strError); + + /** Restore a configuration + * + * @param[in] configurationName the configuration name + * @param[in] mainBlackboard the application main blackboard + * @param[in] autoSync boolean which indicates if auto sync mechanism is on + * @param[out] errors, errors encountered during restoration + * @return true if success false otherwise + */ + bool restoreConfiguration(const std::string &configurationName, + CParameterBlackboard *mainBlackboard, bool autoSync, + core::Results &errors) const; + + bool saveConfiguration(const std::string &strName, const CParameterBlackboard *pMainBlackboard, + std::string &strError); + bool setElementSequence(const std::string &strConfiguration, + const std::vector<std::string> &astrNewElementSequence, + std::string &strError); + bool getElementSequence(const std::string &strConfiguration, std::string &strResult) const; + bool setApplicationRule(const std::string &strConfiguration, + const std::string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, + std::string &strError); + bool clearApplicationRule(const std::string &strConfiguration, std::string &strError); + bool getApplicationRule(const std::string &strConfiguration, std::string &strResult) const; // Last applied configuration name std::string getLastAppliedConfigurationName() const; @@ -75,86 +98,130 @@ public: std::string getPendingConfigurationName() const; // Associated Configurable elements - void gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const; - void listAssociatedToElements(std::string& strResult) const; + void gatherConfigurableElements( + std::set<const CConfigurableElement *> &configurableElementSet) const; + void listAssociatedToElements(std::string &strResult) const; + + /** Add a configurable element to the domain + * + * @param[in] pConfigurableElement pointer to the element to add + * @param[in] pMainBlackboard pointer to the application main blackboard + * @param[out] infos useful information we can provide to client + * @return true if succeed false otherwise + */ + bool addConfigurableElement(CConfigurableElement *pConfigurableElement, + const CParameterBlackboard *pMainBlackboard, core::Results &infos); - // Configurable elements association - bool addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, std::string& strError); - bool removeConfigurableElement(CConfigurableElement* pConfigurableElement, std::string& strError); + bool removeConfigurableElement(CConfigurableElement *pConfigurableElement, + std::string &strError); // Blackboard Configuration and Base Offset retrieval - CParameterBlackboard* findConfigurationBlackboard(const std::string& strConfiguration, - const CConfigurableElement* pConfigurableElement, - uint32_t& uiBaseOffset, - bool& bIsLastApplied, - std::string& strError) const; + CParameterBlackboard *findConfigurationBlackboard( + const std::string &strConfiguration, const CConfigurableElement *pConfigurableElement, + size_t &baseOffset, bool &bIsLastApplied, std::string &strError) const; - // Domain splitting - bool split(CConfigurableElement* pConfigurableElement, std::string& strError); + /** Split the domain in two. + * Remove an element of a domain and create a new domain which owns the element. + * + * @param[in] pConfigurableElement pointer to the element to remove + * @param[out] infos useful information we can provide to client + * @return true if succeed false otherwise + */ + bool split(CConfigurableElement *pConfigurableElement, core::Results &infos); // Ensure validity on whole domain from main blackboard - void validate(const CParameterBlackboard* pMainBlackboard); + void validate(const CParameterBlackboard *pMainBlackboard); - // Configuration application if required - void apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForced) const; + /** Apply the configuration if required + * + * @param[in] pParameterBlackboard the blackboard to synchronize + * @param[in] pSyncerSet pointer to the set containing application syncers + * @param[in] bForced boolean used to force configuration application + * @param[out] info string containing useful information we can provide to client + */ + void apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet *pSyncerSet, bool bForced, + std::string &info) const; // Return applicable configuration validity for given configurable element - bool isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const; + bool isApplicableConfigurationValid(const CConfigurableElement *pConfigurableElement) const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; - virtual void childrenToXml(CXmlElement& xmlElement, - CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; + virtual void childrenToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const; // Class kind virtual std::string getKind() const; protected: // Content dumping - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + std::string logValue(utility::ErrorContext &errorContext) const override; private: // Get pending configuration - const CDomainConfiguration* getPendingConfiguration() const; + const CDomainConfiguration *getPendingConfiguration() const; // Search for an applicable configuration - const CDomainConfiguration* findApplicableDomainConfiguration() const; + const CDomainConfiguration *findApplicableDomainConfiguration() const; - // Returns true if children dynamic creation is to be dealt with (here, will allow child deletion upon clean) + // Returns true if children dynamic creation is to be dealt with (here, will allow child + // deletion upon clean) virtual bool childrenAreDynamic() const; // Ensure validity on areas related to configurable element - void validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard); + void validateAreas(const CConfigurableElement *pConfigurableElement, + const CParameterBlackboard *pMainBlackboard); - // Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain + // Attempt validation for all configurable element's areas, relying on already existing valid + // configuration inside domain void autoValidateAll(); - // Attempt validation for one configurable element's areas, relying on already existing valid configuration inside domain - void autoValidateAreas(const CConfigurableElement* pConfigurableElement); + // Attempt validation for one configurable element's areas, relying on already existing valid + // configuration inside domain + void autoValidateAreas(const CConfigurableElement *pConfigurableElement); - // Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain - bool autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration); + // Attempt configuration validation for all configurable elements' areas, relying on already + // existing valid configuration inside domain + bool autoValidateConfiguration(CDomainConfiguration *pDomainConfiguration); // Search for a valid configuration for given configurable element - const CDomainConfiguration* findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const; - + const CDomainConfiguration *findValidDomainConfiguration( + const CConfigurableElement *pConfigurableElement) const; // In case configurable element was removed void computeSyncSet(); // Check configurable element already attached - bool containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const; + bool containsConfigurableElement( + const CConfigurableElement *pConfigurableCandidateElement) const; - // Merge any descended configurable element to this one - void mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement); - void mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement); + /** Merge any descended configurable element to this one + * + * @param[in] newElement pointer to element which has potential descendants which can be merged + * @param[out] infos useful information we can provide to client + */ + void mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement *newElement, + core::Results &infos); - // Configurable elements association - void doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard = NULL); - void doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet); + void mergeConfigurations(CConfigurableElement *pToConfigurableElement, + CConfigurableElement *pFromConfigurableElement); + + /** Actually realize the association between the domain and a configurable element + * + * @param[in] pConfigurableElement pointer to the element to add + * @param[out] infos useful information we can provide to client + * @param[in] (optional) pMainBlackboard, pointer to the application main blackboard + * Default value is NULL, when provided, blackboard area concerning the configurable + * element are validated. + */ + void doAddConfigurableElement(CConfigurableElement *pConfigurableElement, core::Results &infos, + const CParameterBlackboard *pMainBlackboard = NULL); + + void doRemoveConfigurableElement(CConfigurableElement *pConfigurableElement, + bool bRecomputeSyncSet); // XML parsing /** @@ -166,8 +233,8 @@ private: * * @return false if an error occurs, true otherwise. */ - bool parseDomainConfigurations(const CXmlElement& xmlElement, - CXmlDomainImportContext& serializingContext); + bool parseDomainConfigurations(const CXmlElement &xmlElement, + CXmlDomainImportContext &serializingContext); /** * Deserialize domain elements from an Xml document and add them to * the domain. @@ -177,8 +244,8 @@ private: * * @return false if an error occurs, true otherwise. */ - bool parseConfigurableElements(const CXmlElement& xmlElement, - CXmlDomainImportContext& serializingContext); + bool parseConfigurableElements(const CXmlElement &xmlElement, + CXmlDomainImportContext &serializingContext); /** * Deserialize settings from an Xml document and add them to * the domain. @@ -188,34 +255,35 @@ private: * * @return false if an error occurs, true otherwise. */ - bool parseSettings(const CXmlElement& xmlElement, - CXmlDomainImportContext& serializingContext); + bool parseSettings(const CXmlElement &xmlElement, CXmlDomainImportContext &serializingContext); // XML composing - void composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; - void composeConfigurableElements(CXmlElement& xmlElement) const; - void composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + void composeDomainConfigurations(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const; + void composeConfigurableElements(CXmlElement &xmlElement) const; + void composeSettings(CXmlElement &xmlElement, CXmlDomainExportContext &context) const; // Syncer set retrieval from configurable element - CSyncerSet* getSyncerSet(const CConfigurableElement* pConfigurableElement) const; + CSyncerSet *getSyncerSet(const CConfigurableElement *pConfigurableElement) const; // Configuration retrieval - CDomainConfiguration* findConfiguration(const std::string& strConfiguration, std::string& strError); - const CDomainConfiguration* findConfiguration(const std::string& strConfiguration, std::string& strError) const; + CDomainConfiguration *findConfiguration(const std::string &strConfiguration, + std::string &strError); + const CDomainConfiguration *findConfiguration(const std::string &strConfiguration, + std::string &strError) const; // Configurable elements - std::list<CConfigurableElement*> _configurableElementList; + std::list<CConfigurableElement *> _configurableElementList; // Associated syncer sets - std::map<const CConfigurableElement*, CSyncerSet*> _configurableElementToSyncerSetMap; + std::map<const CConfigurableElement *, CSyncerSet *> _configurableElementToSyncerSetMap; // Sequence awareness - bool _bSequenceAware; + bool _bSequenceAware{false}; // Syncer set used to ensure propoer synchronization of restored configurable elements CSyncerSet _syncerSet; // Last applied configuration - mutable const CDomainConfiguration* _pLastAppliedConfiguration; + mutable const CDomainConfiguration *_pLastAppliedConfiguration{nullptr}; }; - diff --git a/parameter/ConfigurableDomains.cpp b/parameter/ConfigurableDomains.cpp index bfa9271..7c51083 100644 --- a/parameter/ConfigurableDomains.cpp +++ b/parameter/ConfigurableDomains.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,17 +31,11 @@ #include "ConfigurableDomains.h" #include "ConfigurableDomain.h" #include "ConfigurableElement.h" -#include "BinaryStream.h" -#include "AutoLog.h" -#define base CBinarySerializableElement +#define base CElement using std::string; -CConfigurableDomains::CConfigurableDomains() -{ -} - string CConfigurableDomains::getKind() const { return "ConfigurableDomains"; @@ -53,63 +47,73 @@ bool CConfigurableDomains::childrenAreDynamic() const } // Ensure validity on whole domains from main blackboard -void CConfigurableDomains::validate(const CParameterBlackboard* pMainBlackboard) +void CConfigurableDomains::validate(const CParameterBlackboard *pMainBlackboard) { // Delegate to domains - size_t uiChild; size_t uiNbConfigurableDomains = getNbChildren(); - for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { + for (size_t child = 0; child < uiNbConfigurableDomains; child++) { - CConfigurableDomain* pChildConfigurableDomain = static_cast<CConfigurableDomain*>(getChild(uiChild)); + CConfigurableDomain *pChildConfigurableDomain = + static_cast<CConfigurableDomain *>(getChild(child)); pChildConfigurableDomain->validate(pMainBlackboard); } } // Configuration application if required -void CConfigurableDomains::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet& syncerSet, bool bForce) const +void CConfigurableDomains::apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet &syncerSet, + bool bForce, core::Results &infos) const { - CAutoLog autoLog(this, "Applying configurations"); - /// Delegate to domains // Start with domains that can be synchronized all at once (with passed syncer set) - size_t uiChild; size_t uiNbConfigurableDomains = getNbChildren(); - for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { + for (size_t child = 0; child < uiNbConfigurableDomains; child++) { - const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); + const CConfigurableDomain *pChildConfigurableDomain = + static_cast<const CConfigurableDomain *>(getChild(child)); + std::string info; // Apply and collect syncers when relevant - pChildConfigurableDomain->apply(pParameterBlackboard, &syncerSet, bForce); + pChildConfigurableDomain->apply(pParameterBlackboard, &syncerSet, bForce, info); + + if (!info.empty()) { + infos.push_back(info); + } } // Synchronize those collected syncers syncerSet.sync(*pParameterBlackboard, false, NULL); // Then deal with domains that need to synchronize along apply - for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { + for (size_t child = 0; child < uiNbConfigurableDomains; child++) { - const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); + const CConfigurableDomain *pChildConfigurableDomain = + static_cast<const CConfigurableDomain *>(getChild(child)); + std::string info; // Apply and synchronize when relevant - pChildConfigurableDomain->apply(pParameterBlackboard, NULL, bForce); + pChildConfigurableDomain->apply(pParameterBlackboard, NULL, bForce, info); + if (!info.empty()) { + infos.push_back(info); + } } } // From IXmlSource -void CConfigurableDomains::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CConfigurableDomains::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Set attribute - xmlElement.setAttributeString("SystemClassName", getName()); + xmlElement.setAttribute("SystemClassName", getName()); base::childrenToXml(xmlElement, serializingContext); } // Configuration/Domains handling /// Domains -bool CConfigurableDomains::createDomain(const string& strName, string& strError) +bool CConfigurableDomains::createDomain(const string &strName, string &strError) { // Already exists? if (findChild(strName)) { @@ -119,51 +123,44 @@ bool CConfigurableDomains::createDomain(const string& strName, string& strError) return false; } - log_info("Creating configurable domain \"%s\"", strName.c_str()); - // Creation/Hierarchy addChild(new CConfigurableDomain(strName)); return true; } -bool CConfigurableDomains::addDomain(CConfigurableDomain& domain, bool bOverwrite, - string& strError) +bool CConfigurableDomains::addDomain(CConfigurableDomain &domain, bool bOverwrite, string &strError) { string strErrorDrop; string strDomainName(domain.getName()); - CConfigurableDomain* pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop); + CConfigurableDomain *pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop); if (pExistingDomain) { if (!bOverwrite) { strError = "Can't add domain \"" + strDomainName + - "\" because it already exists and overwrite was not requested."; + "\" because it already exists and overwrite was not requested."; return false; } deleteDomain(*pExistingDomain); } - log_info("Adding configurable domain \"%s\"", strDomainName.c_str()); - addChild(&domain); return true; } -void CConfigurableDomains::deleteDomain(CConfigurableDomain& configurableDomain) +void CConfigurableDomains::deleteDomain(CConfigurableDomain &configurableDomain) { - log_info("Deleting configurable domain \"%s\"", configurableDomain.getName().c_str() ); - removeChild(&configurableDomain); delete &configurableDomain; } -bool CConfigurableDomains::deleteDomain(const string& strName, string& strError) +bool CConfigurableDomains::deleteDomain(const string &strName, string &strError) { - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError); if (pConfigurableDomain) { deleteDomain(*pConfigurableDomain); @@ -175,30 +172,28 @@ bool CConfigurableDomains::deleteDomain(const string& strName, string& strError) void CConfigurableDomains::deleteAllDomains() { - log_info("Deleting all configurable domains"); - - //remove Children + // remove Children clean(); } -bool CConfigurableDomains::renameDomain(const string& strName, const string& strNewName, string& strError) +bool CConfigurableDomains::renameDomain(const string &strName, const string &strNewName, + string &strError) { - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError); if (!pConfigurableDomain) { return false; } - log_info("Renaming configurable domain \"%s\" to \"%s\"", strName.c_str(), strNewName.c_str()); - // Rename return pConfigurableDomain->rename(strNewName, strError); } -bool CConfigurableDomains::setSequenceAwareness(const string& strDomain, bool bSequenceAware, string& strError) +bool CConfigurableDomains::setSequenceAwareness(const string &strDomain, bool bSequenceAware, + string &strError) { - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -210,9 +205,10 @@ bool CConfigurableDomains::setSequenceAwareness(const string& strDomain, bool bS return true; } -bool CConfigurableDomains::getSequenceAwareness(const string& strDomain, bool& bSequenceAware, string& strError) const +bool CConfigurableDomains::getSequenceAwareness(const string &strDomain, bool &bSequenceAware, + string &strError) const { - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -225,9 +221,9 @@ bool CConfigurableDomains::getSequenceAwareness(const string& strDomain, bool& b } /// Configurations -bool CConfigurableDomains::listConfigurations(const string& strDomain, string& strResult) const +bool CConfigurableDomains::listConfigurations(const string &strDomain, string &strResult) const { - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); + const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult); if (!pConfigurableDomain) { @@ -239,10 +235,13 @@ bool CConfigurableDomains::listConfigurations(const string& strDomain, string& s return true; } -bool CConfigurableDomains::createConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError) +bool CConfigurableDomains::createConfiguration(const string &strDomain, + const string &strConfiguration, + const CParameterBlackboard *pMainBlackboard, + string &strError) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -252,10 +251,11 @@ bool CConfigurableDomains::createConfiguration(const string& strDomain, const st return pConfigurableDomain->createConfiguration(strConfiguration, pMainBlackboard, strError); } -bool CConfigurableDomains::deleteConfiguration(const string& strDomain, const string& strConfiguration, string& strError) +bool CConfigurableDomains::deleteConfiguration(const string &strDomain, + const string &strConfiguration, string &strError) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -265,23 +265,27 @@ bool CConfigurableDomains::deleteConfiguration(const string& strDomain, const st return pConfigurableDomain->deleteConfiguration(strConfiguration, strError); } -bool CConfigurableDomains::renameConfiguration(const string& strDomain, const string& strConfigurationName, const string& strNewConfigurationName, string& strError) +bool CConfigurableDomains::renameConfiguration(const string &strDomain, + const string &strConfigurationName, + const string &strNewConfigurationName, + string &strError) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { return false; } // Delegate - return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName, strError); + return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName, + strError); } -bool CConfigurableDomains::listDomainElements(const string& strDomain, string& strResult) const +bool CConfigurableDomains::listDomainElements(const string &strDomain, string &strResult) const { // Find domain - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); + const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult); if (!pConfigurableDomain) { @@ -293,36 +297,37 @@ bool CConfigurableDomains::listDomainElements(const string& strDomain, string& s return true; } -bool CConfigurableDomains::split(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError) +bool CConfigurableDomains::split(const string &domainName, CConfigurableElement *element, + core::Results &infos) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + std::string error; + CConfigurableDomain *domain = findConfigurableDomain(domainName, error); - if (!pConfigurableDomain) { + if (domain == NULL) { + infos.push_back(error); return false; } // Delegate - pConfigurableDomain->split(pConfigurableElement, strError); + domain->split(element, infos); return true; } -void CConfigurableDomains::listAssociatedElements(string& strResult) const +void CConfigurableDomains::listAssociatedElements(string &strResult) const { - strResult = "\n"; - - std::set<const CConfigurableElement*> configurableElementSet; + std::set<const CConfigurableElement *> configurableElementSet; // Get all owned configurable elements gatherAllOwnedConfigurableElements(configurableElementSet); // Fill result - std::set<const CConfigurableElement*>::const_iterator it; + std::set<const CConfigurableElement *>::const_iterator it; for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; string strAssociatedDomainList; @@ -332,21 +337,19 @@ void CConfigurableDomains::listAssociatedElements(string& strResult) const } } -void CConfigurableDomains::listConflictingElements(string& strResult) const +void CConfigurableDomains::listConflictingElements(string &strResult) const { - strResult = "\n"; - - std::set<const CConfigurableElement*> configurableElementSet; + std::set<const CConfigurableElement *> configurableElementSet; // Get all owned configurable elements gatherAllOwnedConfigurableElements(configurableElementSet); // Fill result - std::set<const CConfigurableElement*>::const_iterator it; + std::set<const CConfigurableElement *>::const_iterator it; for (it = configurableElementSet.begin(); it != configurableElementSet.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; if (pConfigurableElement->getBelongingDomainCount() > 1) { @@ -354,22 +357,21 @@ void CConfigurableDomains::listConflictingElements(string& strResult) const pConfigurableElement->listBelongingDomains(strBelongingDomainList, false); - strResult += pConfigurableElement->getPath() + " contained in multiple domains: " + strBelongingDomainList + "\n"; + strResult += pConfigurableElement->getPath() + " contained in multiple domains: " + + strBelongingDomainList + "\n"; } } } -void CConfigurableDomains::listDomains(string& strResult) const +void CConfigurableDomains::listDomains(string &strResult) const { - strResult = "\n"; - // List domains - size_t uiChild; size_t uiNbConfigurableDomains = getNbChildren(); - for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { + for (size_t child = 0; child < uiNbConfigurableDomains; child++) { - const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); + const CConfigurableDomain *pChildConfigurableDomain = + static_cast<const CConfigurableDomain *>(getChild(child)); // Name strResult += pChildConfigurableDomain->getName(); @@ -384,41 +386,48 @@ void CConfigurableDomains::listDomains(string& strResult) const } // Gather configurable elements owned by any domain -void CConfigurableDomains::gatherAllOwnedConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const +void CConfigurableDomains::gatherAllOwnedConfigurableElements( + std::set<const CConfigurableElement *> &configurableElementSet) const { // Delegate to domains - size_t uiChild; size_t uiNbConfigurableDomains = getNbChildren(); - for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { + for (size_t child = 0; child < uiNbConfigurableDomains; child++) { - const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); + const CConfigurableDomain *pChildConfigurableDomain = + static_cast<const CConfigurableDomain *>(getChild(child)); pChildConfigurableDomain->gatherConfigurableElements(configurableElementSet); } } // Config restore -bool CConfigurableDomains::restoreConfiguration(const string& strDomain, const string& strConfiguration, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const +bool CConfigurableDomains::restoreConfiguration(const string &domainName, + const string &configurationName, + CParameterBlackboard *mainBlackboard, bool autoSync, + core::Results &errors) const { - string strError; + string error; // Find domain - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + const CConfigurableDomain *domain = findConfigurableDomain(domainName, error); - if (!pConfigurableDomain) { + if (domain == NULL) { - lstrError.push_back(strError); + errors.push_back(error); return false; } // Delegate - return pConfigurableDomain->restoreConfiguration(strConfiguration, pMainBlackboard, bAutoSync, lstrError); + return domain->restoreConfiguration(configurationName, mainBlackboard, autoSync, errors); } // Config save -bool CConfigurableDomains::saveConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError) +bool CConfigurableDomains::saveConfiguration(const string &strDomain, + const string &strConfiguration, + const CParameterBlackboard *pMainBlackboard, + string &strError) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -428,10 +437,13 @@ bool CConfigurableDomains::saveConfiguration(const string& strDomain, const stri return pConfigurableDomain->saveConfiguration(strConfiguration, pMainBlackboard, strError); } -bool CConfigurableDomains::setElementSequence(const string& strDomain, const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError) +bool CConfigurableDomains::setElementSequence(const string &strDomain, + const string &strConfiguration, + const std::vector<string> &astrNewElementSequence, + string &strError) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -439,13 +451,16 @@ bool CConfigurableDomains::setElementSequence(const string& strDomain, const str } // Delegate to domain - return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence, strError); + return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence, + strError); } -bool CConfigurableDomains::getElementSequence(const string& strDomain, const string& strConfiguration, string& strResult) const +bool CConfigurableDomains::getElementSequence(const string &strDomain, + const string &strConfiguration, + string &strResult) const { // Find domain - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); + const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult); if (!pConfigurableDomain) { @@ -455,9 +470,11 @@ bool CConfigurableDomains::getElementSequence(const string& strDomain, const str return pConfigurableDomain->getElementSequence(strConfiguration, strResult); } -bool CConfigurableDomains::setApplicationRule(const string& strDomain, const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError) +bool CConfigurableDomains::setApplicationRule( + const string &strDomain, const string &strConfiguration, const string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, string &strError) { - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -465,12 +482,14 @@ bool CConfigurableDomains::setApplicationRule(const string& strDomain, const str } // Delegate to domain - return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule, pSelectionCriteriaDefinition, strError); + return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule, + pSelectionCriteriaDefinition, strError); } -bool CConfigurableDomains::clearApplicationRule(const string& strDomain, const string& strConfiguration, string& strError) +bool CConfigurableDomains::clearApplicationRule(const string &strDomain, + const string &strConfiguration, string &strError) { - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -481,9 +500,11 @@ bool CConfigurableDomains::clearApplicationRule(const string& strDomain, const s return pConfigurableDomain->clearApplicationRule(strConfiguration, strError); } -bool CConfigurableDomains::getApplicationRule(const string& strDomain, const string& strConfiguration, string& strResult) const +bool CConfigurableDomains::getApplicationRule(const string &strDomain, + const string &strConfiguration, + string &strResult) const { - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strResult); + const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strResult); if (!pConfigurableDomain) { @@ -495,38 +516,45 @@ bool CConfigurableDomains::getApplicationRule(const string& strDomain, const str } // Last applied configurations -void CConfigurableDomains::listLastAppliedConfigurations(string& strResult) const +void CConfigurableDomains::listLastAppliedConfigurations(string &strResult) const { // Browse domains - size_t uiChild; size_t uiNbConfigurableDomains = getNbChildren(); - for (uiChild = 0; uiChild < uiNbConfigurableDomains; uiChild++) { + for (size_t child = 0; child < uiNbConfigurableDomains; child++) { - const CConfigurableDomain* pChildConfigurableDomain = static_cast<const CConfigurableDomain*>(getChild(uiChild)); + const CConfigurableDomain *pChildConfigurableDomain = + static_cast<const CConfigurableDomain *>(getChild(child)); - strResult += pChildConfigurableDomain->getName() + ": " + pChildConfigurableDomain->getLastAppliedConfigurationName() + " [" + pChildConfigurableDomain->getPendingConfigurationName() + "]\n"; + strResult += pChildConfigurableDomain->getName() + ": " + + pChildConfigurableDomain->getLastAppliedConfigurationName() + " [" + + pChildConfigurableDomain->getPendingConfigurationName() + "]\n"; } } // Configurable element - domain association -bool CConfigurableDomains::addConfigurableElementToDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError) +bool CConfigurableDomains::addConfigurableElementToDomain( + const string &domainName, CConfigurableElement *element, + const CParameterBlackboard *mainBlackboard, core::Results &infos) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + std::string error; + CConfigurableDomain *domain = findConfigurableDomain(domainName, error); - if (!pConfigurableDomain) { + if (domain == NULL) { + infos.push_back(error); return false; } // Delegate - return pConfigurableDomain->addConfigurableElement(pConfigurableElement, pMainBlackboard, strError); + return domain->addConfigurableElement(element, mainBlackboard, infos); } -bool CConfigurableDomains::removeConfigurableElementFromDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError) +bool CConfigurableDomains::removeConfigurableElementFromDomain( + const string &strDomain, CConfigurableElement *pConfigurableElement, string &strError) { // Find domain - CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -536,18 +564,13 @@ bool CConfigurableDomains::removeConfigurableElementFromDomain(const string& str return pConfigurableDomain->removeConfigurableElement(pConfigurableElement, strError); } -CParameterBlackboard* CConfigurableDomains::findConfigurationBlackboard(const string& strDomain, - const string& strConfiguration, - const CConfigurableElement* pConfigurableElement, - uint32_t& uiBaseOffset, - bool& bIsLastApplied, - string& strError) const +CParameterBlackboard *CConfigurableDomains::findConfigurationBlackboard( + const string &strDomain, const string &strConfiguration, + const CConfigurableElement *pConfigurableElement, size_t &baseOffset, bool &bIsLastApplied, + string &strError) const { - log_info("Find configuration blackboard for Domain:%s, Configuration:%s, Element:%s", - strDomain.c_str(), strConfiguration.c_str(), pConfigurableElement->getPath().c_str()); - // Find domain - const CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError); + const CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strDomain, strError); if (!pConfigurableDomain) { @@ -557,51 +580,33 @@ CParameterBlackboard* CConfigurableDomains::findConfigurationBlackboard(const st // Check that element belongs to the domain if (!pConfigurableElement->belongsTo(pConfigurableDomain)) { - strError = "Element \"" + pConfigurableElement->getPath() + "\" does not belong to domain \"" + strDomain + "\""; + strError = "Element \"" + pConfigurableElement->getPath() + + "\" does not belong to domain \"" + strDomain + "\""; return NULL; } // Find Configuration Blackboard and Base Offset - return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement, uiBaseOffset, bIsLastApplied, strError); -} - -// Binary settings load/store -bool CConfigurableDomains::serializeSettings(const string& strBinarySettingsFilePath, bool bOut, uint8_t uiStructureChecksum, string& strError) -{ - // Instantiate byte stream - CBinaryStream binarySettingsStream(strBinarySettingsFilePath, bOut, getDataSize(), uiStructureChecksum); - - // Open file - if (!binarySettingsStream.open(strError)) { - - strError = "Unable to open binary settings file " + strBinarySettingsFilePath + ": " + strError; - - return false; - } - - // Serialize - binarySerialize(binarySettingsStream); - - // Close stream - binarySettingsStream.close(); - - return true; + return pConfigurableDomain->findConfigurationBlackboard(strConfiguration, pConfigurableElement, + baseOffset, bIsLastApplied, strError); } // Domain retrieval -CConfigurableDomain* CConfigurableDomains::findConfigurableDomain(const string& strDomain, string& strError) +CConfigurableDomain *CConfigurableDomains::findConfigurableDomain(const string &strDomain, + string &strError) { // Call the const equivalent - return const_cast<CConfigurableDomain*>( - static_cast<const CConfigurableDomains*>(this)->findConfigurableDomain(strDomain, strError) - ); + return const_cast<CConfigurableDomain *>( + static_cast<const CConfigurableDomains *>(this)->findConfigurableDomain(strDomain, + strError)); } -const CConfigurableDomain* CConfigurableDomains::findConfigurableDomain(const string& strDomain, string& strError) const +const CConfigurableDomain *CConfigurableDomains::findConfigurableDomain(const string &strDomain, + string &strError) const { // Find domain - const CConfigurableDomain* pConfigurableDomain = static_cast<const CConfigurableDomain*>(findChild(strDomain)); + const CConfigurableDomain *pConfigurableDomain = + static_cast<const CConfigurableDomain *>(findChild(strDomain)); if (!pConfigurableDomain) { diff --git a/parameter/ConfigurableDomains.h b/parameter/ConfigurableDomains.h index 3cc16df..70e943b 100644 --- a/parameter/ConfigurableDomains.h +++ b/parameter/ConfigurableDomains.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,26 +29,23 @@ */ #pragma once -#include "BinarySerializableElement.h" +#include "Element.h" +#include "Results.h" #include <set> -#include <list> #include <string> - class CParameterBlackboard; class CConfigurableElement; class CSyncerSet; class CConfigurableDomain; class CSelectionCriteriaDefinition; -class CConfigurableDomains : public CBinarySerializableElement +class CConfigurableDomains : public CElement { public: - CConfigurableDomains(); - // Configuration/Domains handling /// Domains - bool createDomain(const std::string& strName, std::string& strError); + bool createDomain(const std::string &strName, std::string &strError); /* * Adds a domain object to configurable domains. The ConfigurableDomains @@ -62,7 +59,7 @@ public: * * @returns true if the domain was successfully added */ - bool addDomain(CConfigurableDomain& domain, bool bOverwrite, std::string& strError); + bool addDomain(CConfigurableDomain &domain, bool bOverwrite, std::string &strError); /** * Delete a domain by name @@ -73,61 +70,115 @@ public: * @returns true of the domain was sucessfully deleted, false otherwise (i.e. * the domain didn't exist). */ - bool deleteDomain(const std::string& strName, std::string& strError); + bool deleteDomain(const std::string &strName, std::string &strError); void deleteAllDomains(); - bool renameDomain(const std::string& strName, const std::string& strNewName, std::string& strError); - bool setSequenceAwareness(const std::string& strDomain, bool bSequenceAware, std::string& strError); - bool getSequenceAwareness(const std::string& strDomain, bool& bSequenceAware, std::string& strError) const; - bool listDomainElements(const std::string& strDomain, std::string& strResult) const; - bool split(const std::string& strDomain, CConfigurableElement* pConfigurableElement, std::string& strError); - void listAssociatedElements(std::string& strResult) const; - void listConflictingElements(std::string& strResult) const; - void listDomains(std::string& strResult) const; + bool renameDomain(const std::string &strName, const std::string &strNewName, + std::string &strError); + bool setSequenceAwareness(const std::string &strDomain, bool bSequenceAware, + std::string &strError); + bool getSequenceAwareness(const std::string &strDomain, bool &bSequenceAware, + std::string &strError) const; + bool listDomainElements(const std::string &strDomain, std::string &strResult) const; + + /** Split a domain in two. + * Remove an element of a domain and create a new domain which owns the element. + * + * @param[in] domainName the domain name + * @param[in] element pointer to the element to remove + * @param[out] infos useful information we can provide to client + * @return true if succeed false otherwise + */ + bool split(const std::string &domainName, CConfigurableElement *element, core::Results &infos); + + void listAssociatedElements(std::string &strResult) const; + void listConflictingElements(std::string &strResult) const; + void listDomains(std::string &strResult) const; /// Configurations - bool listConfigurations(const std::string& strDomain, std::string& strResult) const; - bool createConfiguration(const std::string& strDomain, const std::string& strConfiguration, const CParameterBlackboard* pMainBlackboard, std::string& strError); - bool deleteConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); - bool renameConfiguration(const std::string& strDomain, const std::string& strConfigurationName, const std::string& strNewConfigurationName, std::string& strError); - bool restoreConfiguration(const std::string& strDomain, const std::string& strConfiguration, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<std::string>& lstrError) const; - bool saveConfiguration(const std::string& strDomain, const std::string& strConfiguration, const CParameterBlackboard* pMainBlackboard, std::string& strError); - bool setElementSequence(const std::string& strDomain, const std::string& strConfiguration, const std::vector<std::string>& astrNewElementSequence, std::string& strError); - bool getElementSequence(const std::string& strDomain, const std::string& strConfiguration, std::string& strResult) const; - bool setApplicationRule(const std::string& strDomain, const std::string& strConfiguration, const std::string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, std::string& strError); - bool clearApplicationRule(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); - bool getApplicationRule(const std::string& strDomain, const std::string& strConfiguration, std::string& strResult) const; + bool listConfigurations(const std::string &strDomain, std::string &strResult) const; + bool createConfiguration(const std::string &strDomain, const std::string &strConfiguration, + const CParameterBlackboard *pMainBlackboard, std::string &strError); + bool deleteConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); + bool renameConfiguration(const std::string &strDomain, const std::string &strConfigurationName, + const std::string &strNewConfigurationName, std::string &strError); + + /** Restore a configuration + * + * @param[in] strDomain the domain name + * @param[in] strConfiguration the configuration name + * @param[in] pMainBlackboard the application main blackboard + * @param[in] bAutoSync boolean which indicates if auto sync mechanism is on + * @param[out] errors, errors encountered during restoration + * @return true if success false otherwise + */ + bool restoreConfiguration(const std::string &strDomain, const std::string &strConfiguration, + CParameterBlackboard *pMainBlackboard, bool bAutoSync, + core::Results &errors) const; + + bool saveConfiguration(const std::string &strDomain, const std::string &strConfiguration, + const CParameterBlackboard *pMainBlackboard, std::string &strError); + bool setElementSequence(const std::string &strDomain, const std::string &strConfiguration, + const std::vector<std::string> &astrNewElementSequence, + std::string &strError); + bool getElementSequence(const std::string &strDomain, const std::string &strConfiguration, + std::string &strResult) const; + bool setApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + const std::string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, + std::string &strError); + bool clearApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); + bool getApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + std::string &strResult) const; // Last applied configurations - void listLastAppliedConfigurations(std::string& strResult) const; + void listLastAppliedConfigurations(std::string &strResult) const; - // Configurable element - domain association - bool addConfigurableElementToDomain(const std::string& strDomain, CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, std::string& strError); - bool removeConfigurableElementFromDomain(const std::string& strDomain, CConfigurableElement* pConfigurableElement, std::string& strError); + /** Associate a configurable element to a domain + * + * @param[in] domainName the domain name + * @param[in] element pointer to the element to add + * @param[in] mainBlackboard pointer to the application main blackboard + * @param[out] infos useful information we can provide to client + * @return true if succeed false otherwise + */ + bool addConfigurableElementToDomain(const std::string &domainName, + CConfigurableElement *element, + const CParameterBlackboard *mainBlackboard, + core::Results &infos); - // Configuration Blackboard for element - CParameterBlackboard* findConfigurationBlackboard(const std::string& strDomain, - const std::string& strConfiguration, - const CConfigurableElement* pConfigurableElement, - uint32_t& uiBaseOffset, - bool& bIsLastApplied, - std::string& strError) const; + bool removeConfigurableElementFromDomain(const std::string &strDomain, + CConfigurableElement *pConfigurableElement, + std::string &strError); - const CConfigurableDomain* findConfigurableDomain(const std::string& strDomain, - std::string& strError) const; + // Configuration Blackboard for element + CParameterBlackboard *findConfigurationBlackboard( + const std::string &strDomain, const std::string &strConfiguration, + const CConfigurableElement *pConfigurableElement, size_t &baseOffset, bool &bIsLastApplied, + std::string &strError) const; - // Binary settings load/store - bool serializeSettings(const std::string& strBinarySettingsFilePath, bool bOut, uint8_t uiStructureChecksum, std::string& strError); + const CConfigurableDomain *findConfigurableDomain(const std::string &strDomain, + std::string &strError) const; // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // Ensure validity on whole domains from main blackboard - void validate(const CParameterBlackboard* pMainBlackboard); + void validate(const CParameterBlackboard *pMainBlackboard); - // Configuration application if required - void apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet& syncerSet, bool bForce) const; + /** Apply the configuration if required + * + * @param[in] pParameterBlackboard the blackboard to synchronize + * @param[in] syncerSet the set containing application syncers + * @param[in] bForce boolean used to force configuration application + * @param[out] infos useful information we can provide to client + */ + void apply(CParameterBlackboard *pParameterBlackboard, CSyncerSet &syncerSet, bool bForce, + core::Results &infos) const; // Class kind virtual std::string getKind() const; + private: /** Delete a domain * @@ -136,12 +187,13 @@ private: * @returns true of the domain was sucessfully deleted, false otherwise (i.e. * the domain didn't exist). */ - void deleteDomain(CConfigurableDomain& configurableDomain); + void deleteDomain(CConfigurableDomain &configurableDomain); // Returns true if children dynamic creation is to be dealt with virtual bool childrenAreDynamic() const; // Gather owned configurable elements owned by any domain - void gatherAllOwnedConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const; + void gatherAllOwnedConfigurableElements( + std::set<const CConfigurableElement *> &configurableElementSet) const; // Domain retrieval - CConfigurableDomain* findConfigurableDomain(const std::string& strDomain, std::string& strError); + CConfigurableDomain *findConfigurableDomain(const std::string &strDomain, + std::string &strError); }; - diff --git a/parameter/ConfigurableElement.cpp b/parameter/ConfigurableElement.cpp index 08a0122..615d72b 100644 --- a/parameter/ConfigurableElement.cpp +++ b/parameter/ConfigurableElement.cpp @@ -34,23 +34,53 @@ #include "ConfigurationAccessContext.h" #include "ConfigurableElementAggregator.h" #include "AreaConfiguration.h" +#include "Iterator.hpp" #include "Utility.h" +#include "XmlParameterSerializingContext.h" #include <assert.h> #define base CElement -CConfigurableElement::CConfigurableElement(const std::string& strName) : base(strName), _uiOffset(0) +CConfigurableElement::CConfigurableElement(const std::string &strName) : base(strName) { } -CConfigurableElement::~CConfigurableElement() +bool CConfigurableElement::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { + auto &context = static_cast<CXmlParameterSerializingContext &>(serializingContext); + auto &accessContext = context.getAccessContext(); + + if (accessContext.serializeSettings()) { + // As serialization and deserialisation are handled through the *same* function + // the (de)serialize object can not be const in `serializeXmlSettings` signature. + // As a result a const_cast is unavoidable :(. + // Fixme: split serializeXmlSettings in two functions (in and out) to avoid the `const_cast` + return serializeXmlSettings(const_cast<CXmlElement &>(xmlElement), + static_cast<CConfigurationAccessContext &>(accessContext)); + } + return structureFromXml(xmlElement, serializingContext); +} + +void CConfigurableElement::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const +{ + auto &context = static_cast<CXmlParameterSerializingContext &>(serializingContext); + auto &accessContext = context.getAccessContext(); + if (accessContext.serializeSettings()) { + + serializeXmlSettings(xmlElement, static_cast<CConfigurationAccessContext &>(accessContext)); + } else { + + structureToXml(xmlElement, serializingContext); + } } // XML configuration settings parsing -bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const +bool CConfigurableElement::serializeXmlSettings( + CXmlElement &xmlConfigurationSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) const { - size_t uiIndex; size_t uiNbChildren = getNbChildren(); if (!configurationAccessContext.serializeOut()) { @@ -60,39 +90,68 @@ bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSet CXmlElement xmlChildConfigurableElementSettingsElement; // Propagate to children - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { // Get child - const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex)); + const CConfigurableElement *pChildConfigurableElement = + static_cast<const CConfigurableElement *>(getChild(index)); if (!it.next(xmlChildConfigurableElementSettingsElement)) { // Structure error - configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName()); + configurationAccessContext.setError( + "Configuration settings parsing: missing child node " + + pChildConfigurableElement->getXmlElementName() + " (name:" + + pChildConfigurableElement->getName() + ") in " + getName()); return false; } // Check element type matches in type - if (xmlChildConfigurableElementSettingsElement.getType() != pChildConfigurableElement->getKind()) { - - // Type error - configurationAccessContext.setError("Configuration settings parsing: Settings for configurable element " + pChildConfigurableElement->getName() + " does not match expected type: " + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + pChildConfigurableElement->getKind()); - - return false; + if (xmlChildConfigurableElementSettingsElement.getType() != + pChildConfigurableElement->getXmlElementName()) { + + // "Component" tag has been renamed to "ParameterBlock", but retro-compatibility + // shall be ensured. + // + // So checking if this case occurs, i.e. element name is "ParameterBlock" + // but xml setting name is "Component". + bool compatibilityCase = + (pChildConfigurableElement->getXmlElementName() == "ParameterBlock") && + (xmlChildConfigurableElementSettingsElement.getType() == "Component"); + + // Error if the compatibility case does not occur. + if (!compatibilityCase) { + + // Type error + configurationAccessContext.setError( + "Configuration settings parsing: Settings " + "for configurable element " + + pChildConfigurableElement->getQualifiedPath() + + " does not match expected type: " + + xmlChildConfigurableElementSettingsElement.getType() + " instead of " + + pChildConfigurableElement->getKind()); + return false; + } } // Check element type matches in name - if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != pChildConfigurableElement->getName()) { + if (xmlChildConfigurableElementSettingsElement.getNameAttribute() != + pChildConfigurableElement->getName()) { // Name error - configurationAccessContext.setError("Configuration settings parsing: Under configurable elememnt " + getName() + ", expected element name " + pChildConfigurableElement->getName() + " but found " + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead"); + configurationAccessContext.setError( + "Configuration settings parsing: Under configurable element " + + getQualifiedPath() + ", expected element name " + + pChildConfigurableElement->getName() + " but found " + + xmlChildConfigurableElementSettingsElement.getNameAttribute() + " instead"); return false; } // Parse child configurable element's settings - if (!pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext)) { + if (!pChildConfigurableElement->serializeXmlSettings( + xmlChildConfigurableElementSettingsElement, configurationAccessContext)) { return false; } @@ -101,26 +160,32 @@ bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSet if (it.next(xmlChildConfigurableElementSettingsElement)) { // Structure error - configurationAccessContext.setError("Configuration settings parsing: Settings don't conform to structure of configurable element " + getName()); + configurationAccessContext.setError( + "Configuration settings parsing: Unexpected xml element node " + + xmlChildConfigurableElementSettingsElement.getType() + " in " + getQualifiedPath()); return false; } } else { + // Handle element name attribute + xmlConfigurationSettingsElementContent.setNameAttribute(getName()); + // Propagate to children - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { - const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex)); + const CConfigurableElement *pChildConfigurableElement = + static_cast<const CConfigurableElement *>(getChild(index)); // Create corresponding child element CXmlElement xmlChildConfigurableElementSettingsElement; - xmlConfigurationSettingsElementContent.createChild(xmlChildConfigurableElementSettingsElement, pChildConfigurableElement->getKind()); - - // Handle element name attribute - xmlChildConfigurableElementSettingsElement.setNameAttribute(pChildConfigurableElement->getName()); + xmlConfigurationSettingsElementContent.createChild( + xmlChildConfigurableElementSettingsElement, + pChildConfigurableElement->getXmlElementName()); // Propagate - pChildConfigurableElement->serializeXmlSettings(xmlChildConfigurableElementSettingsElement, configurationAccessContext); + pChildConfigurableElement->serializeXmlSettings( + xmlChildConfigurableElementSettingsElement, configurationAccessContext); } } // Done @@ -128,24 +193,30 @@ bool CConfigurableElement::serializeXmlSettings(CXmlElement& xmlConfigurationSet } // AreaConfiguration creation -CAreaConfiguration* CConfigurableElement::createAreaConfiguration(const CSyncerSet* pSyncerSet) const +CAreaConfiguration *CConfigurableElement::createAreaConfiguration( + const CSyncerSet *pSyncerSet) const { return new CAreaConfiguration(this, pSyncerSet); } // Parameter access -bool CConfigurableElement::accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CConfigurableElement::accessValue(CPathNavigator &pathNavigator, std::string &strValue, + bool bSet, + CParameterAccessContext ¶meterAccessContext) const { - std::string* pStrChildName = pathNavigator.next(); + std::string *pStrChildName = pathNavigator.next(); if (!pStrChildName) { - parameterAccessContext.setError((bSet ? "Can't set " : "Can't get ") + pathNavigator.getCurrentPath() + " because it is not a parameter"); + parameterAccessContext.setError((bSet ? "Can't set " : "Can't get ") + + pathNavigator.getCurrentPath() + + " because it is not a parameter"); return false; } - const CConfigurableElement* pChild = static_cast<const CConfigurableElement*>(findChild(*pStrChildName)); + const CConfigurableElement *pChild = + static_cast<const CConfigurableElement *>(findChild(*pStrChildName)); if (!pChild) { @@ -157,78 +228,139 @@ bool CConfigurableElement::accessValue(CPathNavigator& pathNavigator, std::strin return pChild->accessValue(pathNavigator, strValue, bSet, parameterAccessContext); } -void CConfigurableElement::getListOfElementsWithMapping( - std::list<const CConfigurableElement*>& configurableElementPath) const +// Whole element access +void CConfigurableElement::getSettingsAsBytes(std::vector<uint8_t> &bytes, + CParameterAccessContext ¶meterAccessContext) const { - // Check parent - const CElement* pParent = getParent(); - if (isOfConfigurableElementType(pParent)) { + bytes.resize(getFootPrint()); + + parameterAccessContext.getParameterBlackboard()->readBytes( + bytes, getOffset() - parameterAccessContext.getBaseOffset()); +} + +bool CConfigurableElement::setSettingsAsBytes(const std::vector<uint8_t> &bytes, + CParameterAccessContext ¶meterAccessContext) const +{ + CParameterBlackboard *pParameterBlackboard = parameterAccessContext.getParameterBlackboard(); + + // Size + size_t size = getFootPrint(); + + // Check sizes match + if (size != bytes.size()) { - const CConfigurableElement* pConfigurableElement = - static_cast<const CConfigurableElement*>(pParent); + parameterAccessContext.setError(std::string("Wrong size: Expected: ") + + std::to_string(size) + " Provided: " + + std::to_string(bytes.size())); - pConfigurableElement->getListOfElementsWithMapping(configurableElementPath); + return false; } + + // Write bytes + pParameterBlackboard->writeBytes(bytes, getOffset() - parameterAccessContext.getBaseOffset()); + + if (not parameterAccessContext.getAutoSync()) { + // Auto sync is not activated, sync will be defered until an explicit request + return true; + } + + CSyncerSet syncerSet; + fillSyncerSet(syncerSet); + core::Results res; + if (not syncerSet.sync(*parameterAccessContext.getParameterBlackboard(), false, &res)) { + + parameterAccessContext.setError(utility::asString(res)); + return false; + } + return true; +} + +std::list<const CConfigurableElement *> CConfigurableElement::getConfigurableElementContext() const +{ + std::list<const CConfigurableElement *> configurableElementPath; + + const CElement *element = this; + while (element != nullptr and isOfConfigurableElementType(element)) { + auto configurableElement = static_cast<const CConfigurableElement *>(element); + + configurableElementPath.push_back(configurableElement); + element = element->getParent(); + } + + return configurableElementPath; } // Used for simulation and virtual subsystems -void CConfigurableElement::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +void CConfigurableElement::setDefaultValues(CParameterAccessContext ¶meterAccessContext) const { // Propagate to children - size_t uiIndex; size_t uiNbChildren = getNbChildren(); - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex)); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(getChild(index)); pConfigurableElement->setDefaultValues(parameterAccessContext); } } // Element properties -void CConfigurableElement::showProperties(std::string& strResult) const +void CConfigurableElement::showProperties(std::string &strResult) const { base::showProperties(strResult); strResult += "Total size: " + getFootprintAsString() + "\n"; } +std::string CConfigurableElement::logValue(utility::ErrorContext &context) const +{ + return logValue(static_cast<CParameterAccessContext &>(context)); +} + +std::string CConfigurableElement::logValue(CParameterAccessContext & /*ctx*/) const +{ + // By default, an element does not have a value. Only leaf elements have + // one. This method could be pure virtual but then, several derived classes + // would need to implement it in order to simply return an empty string. + return ""; +} + // Offset -void CConfigurableElement::setOffset(uint32_t uiOffset) +void CConfigurableElement::setOffset(size_t offset) { // Assign offset locally - _uiOffset = uiOffset; + _offset = offset; // Propagate to children - size_t uiIndex; size_t uiNbChildren = getNbChildren(); - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { - CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(getChild(uiIndex)); + CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(getChild(index)); - pConfigurableElement->setOffset(uiOffset); + pConfigurableElement->setOffset(offset); - uiOffset += pConfigurableElement->getFootPrint(); + offset += pConfigurableElement->getFootPrint(); } } -uint32_t CConfigurableElement::getOffset() const +size_t CConfigurableElement::getOffset() const { - return _uiOffset; + return _offset; } // Memory -uint32_t CConfigurableElement::getFootPrint() const +size_t CConfigurableElement::getFootPrint() const { - uint32_t uiSize = 0; - size_t uiIndex; + size_t uiSize = 0; size_t uiNbChildren = getNbChildren(); - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex)); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(getChild(index)); uiSize += pConfigurableElement->getFootPrint(); } @@ -237,23 +369,23 @@ uint32_t CConfigurableElement::getFootPrint() const } // Browse parent path to find syncer -ISyncer* CConfigurableElement::getSyncer() const +ISyncer *CConfigurableElement::getSyncer() const { // Check parent - const CElement* pParent = getParent(); + const CElement *pParent = getParent(); if (isOfConfigurableElementType(pParent)) { - return static_cast<const CConfigurableElement*>(pParent)->getSyncer(); + return static_cast<const CConfigurableElement *>(pParent)->getSyncer(); } return NULL; } // Syncer set (me, ascendant or descendant ones) -void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const +void CConfigurableElement::fillSyncerSet(CSyncerSet &syncerSet) const { // Try me or ascendants - ISyncer* pMineOrAscendantSyncer = getSyncer(); + ISyncer *pMineOrAscendantSyncer = getSyncer(); if (pMineOrAscendantSyncer) { @@ -268,33 +400,35 @@ void CConfigurableElement::fillSyncerSet(CSyncerSet& syncerSet) const } // Syncer set (descendant) -void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const +void CConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const { // Dig - size_t uiIndex; size_t uiNbChildren = getNbChildren(); - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(getChild(uiIndex)); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(getChild(index)); pConfigurableElement->fillSyncerSetFromDescendant(syncerSet); } } // Configurable domain association -void CConfigurableElement::addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) +void CConfigurableElement::addAttachedConfigurableDomain( + const CConfigurableDomain *pConfigurableDomain) { _configurableDomainList.push_back(pConfigurableDomain); } -void CConfigurableElement::removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) +void CConfigurableElement::removeAttachedConfigurableDomain( + const CConfigurableDomain *pConfigurableDomain) { _configurableDomainList.remove(pConfigurableDomain); } // Belonging domain -bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDomain) const +bool CConfigurableElement::belongsTo(const CConfigurableDomain *pConfigurableDomain) const { if (containsConfigurableDomain(pConfigurableDomain)) { @@ -304,23 +438,26 @@ bool CConfigurableElement::belongsTo(const CConfigurableDomain* pConfigurableDom } // Belonging domains -void CConfigurableElement::getBelongingDomains(std::list<const CConfigurableDomain*>& configurableDomainList) const +void CConfigurableElement::getBelongingDomains( + std::list<const CConfigurableDomain *> &configurableDomainList) const { - configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), _configurableDomainList.end()); + configurableDomainList.insert(configurableDomainList.end(), _configurableDomainList.begin(), + _configurableDomainList.end()); // Check parent - const CElement* pParent = getParent(); + const CElement *pParent = getParent(); if (isOfConfigurableElementType(pParent)) { - static_cast<const CConfigurableElement*>(pParent)->getBelongingDomains(configurableDomainList); + static_cast<const CConfigurableElement *>(pParent)->getBelongingDomains( + configurableDomainList); } } -void CConfigurableElement::listBelongingDomains(std::string& strResult, bool bVertical) const +void CConfigurableElement::listBelongingDomains(std::string &strResult, bool bVertical) const { // Get belonging domain list - std::list<const CConfigurableDomain*> configurableDomainList; + std::list<const CConfigurableDomain *> configurableDomainList; getBelongingDomains(configurableDomainList); @@ -329,39 +466,52 @@ void CConfigurableElement::listBelongingDomains(std::string& strResult, bool bVe } // Elements with no domains -void CConfigurableElement::listRogueElements(std::string& strResult) const +void CConfigurableElement::listRogueElements(std::string &strResult) const { - strResult = "\n"; - // Get rogue element aggregate list (no associated domain) - std::list<const CConfigurableElement*> rogueElementList; + std::list<const CConfigurableElement *> rogueElementList; - CConfigurableElementAggregator configurableElementAggregator(rogueElementList, &CConfigurableElement::hasNoDomainAssociated); + CConfigurableElementAggregator configurableElementAggregator( + rogueElementList, &CConfigurableElement::hasNoDomainAssociated); configurableElementAggregator.aggegate(this); // Build list as std::string - std::list<const CConfigurableElement*>::const_iterator it; + std::list<const CConfigurableElement *>::const_iterator it; for (it = rogueElementList.begin(); it != rogueElementList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; strResult += pConfigurableElement->getPath() + "\n"; } } -// Belonging to no domains bool CConfigurableElement::isRogue() const { - return !getBelongingDomainCount(); + // Check not belonging to any domin from current level and towards ascendents + if (getBelongingDomainCount() != 0) { + + return false; + } + + // Get a list of elements (current + descendants) with no domains associated + std::list<const CConfigurableElement *> rogueElementList; + + CConfigurableElementAggregator agregator(rogueElementList, + &CConfigurableElement::hasNoDomainAssociated); + + agregator.aggegate(this); + + // Check only one element found which ought to be current one + return (rogueElementList.size() == 1) && (rogueElementList.front() == this); } // Footprint as string std::string CConfigurableElement::getFootprintAsString() const { // Get size as string - return CUtility::toString(getFootPrint()) + " byte(s)"; + return std::to_string(getFootPrint()) + " byte(s)"; } // Matching check for no domain association @@ -384,7 +534,7 @@ bool CConfigurableElement::hasNoValidDomainAssociated() const // Browse all configurable domains for validity checking for (it = _configurableDomainList.begin(); it != _configurableDomainList.end(); ++it) { - const CConfigurableDomain* pConfigurableDomain = *it; + const CConfigurableDomain *pConfigurableDomain = *it; if (pConfigurableDomain->isApplicableConfigurationValid(this)) { @@ -396,7 +546,7 @@ bool CConfigurableElement::hasNoValidDomainAssociated() const } // Owning domains -void CConfigurableElement::listAssociatedDomains(std::string& strResult, bool bVertical) const +void CConfigurableElement::listAssociatedDomains(std::string &strResult, bool bVertical) const { // Fill list listDomains(_configurableDomainList, strResult, bVertical); @@ -405,20 +555,17 @@ void CConfigurableElement::listAssociatedDomains(std::string& strResult, bool bV size_t CConfigurableElement::getBelongingDomainCount() const { // Get belonging domain list - std::list<const CConfigurableDomain*> configurableDomainList; + std::list<const CConfigurableDomain *> configurableDomainList; getBelongingDomains(configurableDomainList); return configurableDomainList.size(); } -void CConfigurableElement::listDomains(const std::list<const CConfigurableDomain*>& configurableDomainList, std::string& strResult, bool bVertical) const +void CConfigurableElement::listDomains( + const std::list<const CConfigurableDomain *> &configurableDomainList, std::string &strResult, + bool bVertical) const { - if (bVertical && configurableDomainList.empty()) { - - strResult = "\n"; - } - // Fill list ConfigurableDomainListConstIterator it; bool bFirst = true; @@ -426,7 +573,7 @@ void CConfigurableElement::listDomains(const std::list<const CConfigurableDomain // Browse all configurable domains for comparison for (it = configurableDomainList.begin(); it != configurableDomainList.end(); ++it) { - const CConfigurableDomain* pConfigurableDomain = *it; + const CConfigurableDomain *pConfigurableDomain = *it; if (!bVertical && !bFirst) { @@ -445,7 +592,8 @@ void CConfigurableElement::listDomains(const std::list<const CConfigurableDomain } } -bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const +bool CConfigurableElement::containsConfigurableDomain( + const CConfigurableDomain *pConfigurableDomain) const { ConfigurableDomainListConstIterator it; @@ -461,22 +609,23 @@ bool CConfigurableElement::containsConfigurableDomain(const CConfigurableDomain* } // Belonging domain ascending search -bool CConfigurableElement::belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const +bool CConfigurableElement::belongsToDomainAscending( + const CConfigurableDomain *pConfigurableDomain) const { // Check parent - const CElement* pParent = getParent(); + const CElement *pParent = getParent(); if (isOfConfigurableElementType(pParent)) { - return static_cast<const CConfigurableElement*>(pParent)->belongsTo(pConfigurableDomain); + return static_cast<const CConfigurableElement *>(pParent)->belongsTo(pConfigurableDomain); } return false; } // Belonging subsystem -const CSubsystem* CConfigurableElement::getBelongingSubsystem() const +const CSubsystem *CConfigurableElement::getBelongingSubsystem() const { - const CElement* pParent = getParent(); + const CElement *pParent = getParent(); // Stop at system class if (!pParent->getParent()) { @@ -484,7 +633,7 @@ const CSubsystem* CConfigurableElement::getBelongingSubsystem() const return NULL; } - return static_cast<const CConfigurableElement*>(pParent)->getBelongingSubsystem(); + return static_cast<const CConfigurableElement *>(pParent)->getBelongingSubsystem(); } // Check element is a parameter @@ -493,9 +642,8 @@ bool CConfigurableElement::isParameter() const return false; } - // Check parent is still of current type (by structure knowledge) -bool CConfigurableElement::isOfConfigurableElementType(const CElement* pParent) const +bool CConfigurableElement::isOfConfigurableElementType(const CElement *pParent) const { assert(pParent); diff --git a/parameter/ConfigurableElement.h b/parameter/ConfigurableElement.h index 18256cf..e511447 100644 --- a/parameter/ConfigurableElement.h +++ b/parameter/ConfigurableElement.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,9 +29,12 @@ */ #pragma once +#include "parameter_export.h" + #include "Element.h" #include <list> +#include <vector> class CConfigurableDomain; class CSyncerSet; @@ -41,30 +44,32 @@ class CConfigurationAccessContext; class CParameterAccessContext; class CAreaConfiguration; -class CConfigurableElement : public CElement +class PARAMETER_EXPORT CConfigurableElement : public CElement { friend class CConfigurableDomain; friend class CDomainConfiguration; - typedef std::list<const CConfigurableDomain*>::const_iterator ConfigurableDomainListConstIterator; + typedef std::list<const CConfigurableDomain *>::const_iterator + ConfigurableDomainListConstIterator; + public: - CConfigurableElement(const std::string& strName = ""); - virtual ~CConfigurableElement(); + CConfigurableElement(const std::string &strName = ""); + virtual ~CConfigurableElement() = default; // Offset in main blackboard - void setOffset(uint32_t uiOffset); - uint32_t getOffset() const; + void setOffset(size_t offset); + size_t getOffset() const; // Allocation - virtual uint32_t getFootPrint() const; + virtual size_t getFootPrint() const; // Syncer set (me, ascendant or descendant ones) - void fillSyncerSet(CSyncerSet& syncerSet) const; + void fillSyncerSet(CSyncerSet &syncerSet) const; // Belonging domain - bool belongsTo(const CConfigurableDomain* pConfigurableDomain) const; + bool belongsTo(const CConfigurableDomain *pConfigurableDomain) const; // Belonging domains - void listBelongingDomains(std::string& strResult, bool bVertical = true) const; + void listBelongingDomains(std::string &strResult, bool bVertical = true) const; // Matching check for domain association bool hasNoDomainAssociated() const; @@ -73,81 +78,159 @@ public: bool hasNoValidDomainAssociated() const; // Owning domains - void listAssociatedDomains(std::string& strResult, bool bVertical = true) const; + void listAssociatedDomains(std::string &strResult, bool bVertical = true) const; size_t getBelongingDomainCount() const; // Elements with no domains - void listRogueElements(std::string& strResult) const; + void listRogueElements(std::string &strResult) const; - // Belonging to no domains + /** @return true if element is rogue, false otherwise + * + * An element is rogue if it is disjoint with all domains. + * + * Ie: An element is rogue if neither its descendants, ascendants + * nor itself are associated with any domain. + * + * Ie: An element is *not* rogue if any of its descendants, ascendants + * or itself are associated with at least one domain. + */ bool isRogue() const; // Footprint as string std::string getFootprintAsString() const; // Belonging subsystem - virtual const CSubsystem* getBelongingSubsystem() const; + virtual const CSubsystem *getBelongingSubsystem() const; // Check element is a parameter virtual bool isParameter() const; // AreaConfiguration creation - virtual CAreaConfiguration* createAreaConfiguration(const CSyncerSet* pSyncerSet) const; + virtual CAreaConfiguration *createAreaConfiguration(const CSyncerSet *pSyncerSet) const; // Parameter access - virtual bool accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + virtual bool accessValue(CPathNavigator &pathNavigator, std::string &strValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const; - /** - * Get the list of all the ancestors that have a mapping. + /** Gets the element as an array of bytes. + * + * This is like having a direct access to the blackboard. * - * The mapping is represented as a std::string of all the mapping data (key:value) defined in the - * context of the element. - * In this class, the method is generic and calls its parent getListOfElementsWithMappings(...) - * method. + * @param[out] bytes Where to store the result. + * @param[in] parameterAccessContext Context containing the blackboard to + * read from. + */ + void getSettingsAsBytes(std::vector<uint8_t> &bytes, + CParameterAccessContext ¶meterAccessContext) const; + /** Sets the element as if it was an array of bytes. * - * @param[in:out] configurableElementPath List of all the ConfigurableElements found - * that have a mapping. Elements are added at the end of the list, so the root Element will be - * the last one. + * This is like having a direct access to the blackboard. + * + * @param[out] bytes The content to be set. + * @param[in] parameterAccessContext Context containing the blackboard to + * write to. + */ + bool setSettingsAsBytes(const std::vector<uint8_t> &bytes, + CParameterAccessContext ¶meterAccessContext) const; + + /** @return List of all ConfigurableElements that have a mapping relevant in this context. + * Ie: return self and CConfigurableElement ancestor of this node. * */ - virtual void getListOfElementsWithMapping(std::list<const CConfigurableElement*>& - configurableElementPath) const; + std::list<const CConfigurableElement *> getConfigurableElementContext() const; // Used for simulation and virtual subsystems - virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const; + virtual void setDefaultValues(CParameterAccessContext ¶meterAccessContext) const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; + + /** + * Get the value associated to a mapping key in the object's mapping + * + * @param[in] strKey the mapping key + * @param[out] pStrValue the associated value + * + * @return true if @p strKey is found in the object's mapping, false if not + */ + virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const = 0; + /** Get the string representation of the mapping + * + * If applicable, amend values are applied to the leaf element. + */ + virtual std::string getFormattedMapping() const = 0; // XML configuration settings parsing - virtual bool serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const; + virtual bool serializeXmlSettings( + CXmlElement &xmlConfigurationSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) const; + + bool fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) override final; + + void toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const override final; + + /** Deserialize the structure from xml. */ + virtual bool structureFromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) + { + // Forward to Element::fromXml. + // This is unfortunate as Element::fromXml will call back + // fromXml on each children. + // Thus on each non leaf node of the tree, the code will test if + // the setting or the structure are to be serialized. + // This test could be avoided by several ways including: + // - split 2 roles fromXml in two function + // 1) construct the elements + // 2) recursive call on children + // - dispatch in with a virtual method. This would not not remove + // the branching rather hide it behind a virtual method override. + return CElement::fromXml(xmlElement, serializingContext); + } + + /** Serialize the structure to xml. */ + virtual void structureToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const + { + // See structureFromXml implementation comment. + CElement::toXml(xmlElement, serializingContext); + } + protected: // Syncer (me or ascendant) - virtual ISyncer* getSyncer() const; + virtual ISyncer *getSyncer() const; // Syncer set (descendant) - virtual void fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const; + virtual void fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const; // Configuration Domain local search - bool containsConfigurableDomain(const CConfigurableDomain* pConfigurableDomain) const; + bool containsConfigurableDomain(const CConfigurableDomain *pConfigurableDomain) const; private: + // Content dumping. Override and stop further deriving: Configurable + // Elements should be called with the overloaded version taking a + // "Parameter Access Context" (The name is misleading as it is actually + // used to access any Configurable Element). + std::string logValue(utility::ErrorContext &errorContext) const override final; + virtual std::string logValue(CParameterAccessContext &context) const; + // Configurable domain association - void addAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain); - void removeAttachedConfigurableDomain(const CConfigurableDomain* pConfigurableDomain); + void addAttachedConfigurableDomain(const CConfigurableDomain *pConfigurableDomain); + void removeAttachedConfigurableDomain(const CConfigurableDomain *pConfigurableDomain); // Belonging domain ascending search - bool belongsToDomainAscending(const CConfigurableDomain* pConfigurableDomain) const; + bool belongsToDomainAscending(const CConfigurableDomain *pConfigurableDomain) const; // Belonging domains - void getBelongingDomains(std::list<const CConfigurableDomain*>& configurableDomainList) const; - void listDomains(const std::list<const CConfigurableDomain*>& configurableDomainList, std::string& strResult, bool bVertical) const; + void getBelongingDomains(std::list<const CConfigurableDomain *> &configurableDomainList) const; + void listDomains(const std::list<const CConfigurableDomain *> &configurableDomainList, + std::string &strResult, bool bVertical) const; // Check parent is still of current type (by structure knowledge) - bool isOfConfigurableElementType(const CElement* pParent) const; + bool isOfConfigurableElementType(const CElement *pParent) const; // Offset in main blackboard - uint32_t _uiOffset; + size_t _offset{0}; // Associated configurable domains - std::list<const CConfigurableDomain*> _configurableDomainList; + std::list<const CConfigurableDomain *> _configurableDomainList; }; - diff --git a/parameter/ConfigurableElementAggregator.cpp b/parameter/ConfigurableElementAggregator.cpp index 75bce4b..a893f1a 100644 --- a/parameter/ConfigurableElementAggregator.cpp +++ b/parameter/ConfigurableElementAggregator.cpp @@ -30,19 +30,23 @@ #include "ConfigurableElementAggregator.h" #include "ConfigurableElement.h" -CConfigurableElementAggregator::CConfigurableElementAggregator(std::list<const CConfigurableElement*>& aggregateList, MatchesAggregationCriterion pfnMatchesAggregationCriterion) +CConfigurableElementAggregator::CConfigurableElementAggregator( + std::list<const CConfigurableElement *> &aggregateList, + MatchesAggregationCriterion pfnMatchesAggregationCriterion) : _aggregateList(aggregateList), _pfnMatchesAggregationCriterion(pfnMatchesAggregationCriterion) { } // Aggregate -void CConfigurableElementAggregator::aggegate(const CConfigurableElement* pConfigurableElement) +void CConfigurableElementAggregator::aggegate(const CConfigurableElement *pConfigurableElement) { doAggregate(pConfigurableElement, _aggregateList); } // Recursive aggregate -bool CConfigurableElementAggregator::doAggregate(const CConfigurableElement* pConfigurableElement, std::list<const CConfigurableElement*>& aggregateList) +bool CConfigurableElementAggregator::doAggregate( + const CConfigurableElement *pConfigurableElement, + std::list<const CConfigurableElement *> &aggregateList) { if (!(pConfigurableElement->*_pfnMatchesAggregationCriterion)()) { @@ -50,15 +54,15 @@ bool CConfigurableElementAggregator::doAggregate(const CConfigurableElement* pCo return false; } // Check children - std::list<const CConfigurableElement*> childAggregateElementList; + std::list<const CConfigurableElement *> childAggregateElementList; - size_t uiIndex; size_t uiNbChildren = pConfigurableElement->getNbChildren(); size_t uiNbMatchingChildren = 0; - for (uiIndex = 0; uiIndex < uiNbChildren; uiIndex++) { + for (size_t index = 0; index < uiNbChildren; index++) { - const CConfigurableElement* pChildConfigurableElement = static_cast<const CConfigurableElement*>(pConfigurableElement->getChild(uiIndex)); + const CConfigurableElement *pChildConfigurableElement = + static_cast<const CConfigurableElement *>(pConfigurableElement->getChild(index)); uiNbMatchingChildren += doAggregate(pChildConfigurableElement, childAggregateElementList); } @@ -71,7 +75,8 @@ bool CConfigurableElementAggregator::doAggregate(const CConfigurableElement* pCo return true; } else { // Add children if any - aggregateList.insert(aggregateList.end(), childAggregateElementList.begin(), childAggregateElementList.end()); + aggregateList.insert(aggregateList.end(), childAggregateElementList.begin(), + childAggregateElementList.end()); return false; } diff --git a/parameter/ConfigurableElementAggregator.h b/parameter/ConfigurableElementAggregator.h index 4c1119b..79dfc23 100644 --- a/parameter/ConfigurableElementAggregator.h +++ b/parameter/ConfigurableElementAggregator.h @@ -30,30 +30,32 @@ #pragma once #include "ConfigurableElement.h" +#include "NonCopyable.hpp" + #include <list> #include <string> - -class CConfigurableElementAggregator +class CConfigurableElementAggregator : private utility::NonCopyable { public: // Matching check method type typedef bool (CConfigurableElement::*MatchesAggregationCriterion)() const; // Constructor - CConfigurableElementAggregator(std::list<const CConfigurableElement*>& aggregateList, MatchesAggregationCriterion pfnMatchesAggregationCriterion); + CConfigurableElementAggregator(std::list<const CConfigurableElement *> &aggregateList, + MatchesAggregationCriterion pfnMatchesAggregationCriterion); // Aggregate - void aggegate(const CConfigurableElement* pConfigurableElement); + void aggegate(const CConfigurableElement *pConfigurableElement); private: // Recursive aggregate - bool doAggregate(const CConfigurableElement* pConfigurableElement, std::list<const CConfigurableElement*>& aggregateList); + bool doAggregate(const CConfigurableElement *pConfigurableElement, + std::list<const CConfigurableElement *> &aggregateList); // Aggegate list - std::list<const CConfigurableElement*>& _aggregateList; + std::list<const CConfigurableElement *> &_aggregateList; // Matching check method MatchesAggregationCriterion _pfnMatchesAggregationCriterion; }; - diff --git a/parameter/ConfigurationAccessContext.cpp b/parameter/ConfigurationAccessContext.cpp index f2f9042..5c09692 100644 --- a/parameter/ConfigurationAccessContext.cpp +++ b/parameter/ConfigurationAccessContext.cpp @@ -33,9 +33,18 @@ using std::string; -CConfigurationAccessContext::CConfigurationAccessContext(string& strError, bool bSerializeOut) : - base(strError), - _bSerializeOut(bSerializeOut) +CConfigurationAccessContext::CConfigurationAccessContext(std::string &strError, + CParameterBlackboard *pParameterBlackboard, + bool bValueSpaceIsRaw, + bool bOutputRawFormatIsHex, + bool bSerializeOut) + : base(strError, pParameterBlackboard, bValueSpaceIsRaw, bOutputRawFormatIsHex), + _bSerializeOut(bSerializeOut) +{ +} + +CConfigurationAccessContext::CConfigurationAccessContext(string &strError, bool bSerializeOut) + : base(strError), _bSerializeOut(bSerializeOut) { } diff --git a/parameter/ConfigurationAccessContext.h b/parameter/ConfigurationAccessContext.h index ef0ce31..10ffd4f 100644 --- a/parameter/ConfigurationAccessContext.h +++ b/parameter/ConfigurationAccessContext.h @@ -36,13 +36,18 @@ class CConfigurationAccessContext : public CParameterAccessContext { public: - CConfigurationAccessContext(std::string& strError, bool bSerializeOut); + CConfigurationAccessContext(std::string &strError, CParameterBlackboard *pParameterBlackboard, + bool bValueSpaceIsRaw, bool bOutputRawFormatIsHex, + bool bSerializeOut); + + CConfigurationAccessContext(std::string &strError, bool bSerializeOut); // Serialization direction bool serializeOut() const; + bool serializeSettings() const override final { return true; } + private: // Serialization direction bool _bSerializeOut; }; - diff --git a/parameter/DefaultElementLibrary.h b/parameter/DefaultElementLibrary.h index b6966c2..9223021 100644 --- a/parameter/DefaultElementLibrary.h +++ b/parameter/DefaultElementLibrary.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -34,6 +34,8 @@ #include <map> #include <string> +#include <memory> +#include <utility> /** Factory that creates an element given an xml element. If no matching builder is found, it uses * the default builder. @@ -41,24 +43,22 @@ * @tparam CDefaultElementBuilder is the class of the element builder to use if no corresponding * builder is found for a given xml element. */ -template<class CDefaultElementBuilder> -class CDefaultElementLibrary: public CElementLibrary +template <class CDefaultElementBuilder> +class CDefaultElementLibrary : public CElementLibrary { public: + virtual ~CDefaultElementLibrary() = default; - explicit CDefaultElementLibrary(bool bEnableDefaultMechanism = true); - virtual ~CDefaultElementLibrary() {} - - /** Enable the default builder fallback mechanism. + /** Set the default builder used in fallback mechanism. * @see createElement() for more detail on this mechanism. * - * @param[in] bEnable if true/false, activate/deactivate the default builder mechanism. + * @param[in] defaultBuilder if NULL default builder mechanism, else provided builder is used. */ - void enableDefaultMechanism(bool bEnable) { - _bEnableDefaultMechanism = bEnable; + void setDefaultBuilder(std::unique_ptr<CDefaultElementBuilder> defaultBuilder) + { + _defaultBuilder = std::move(defaultBuilder); } - /** Create and return an element instanciated depending on an xmlElement. * * @param[in] xmlElement: The xml element used to find a matching builder @@ -69,34 +69,28 @@ public: * create the elemen with the default element builder. * otherwise, return NULL. */ - CElement* createElement(const CXmlElement& xmlElement) const; + CElement *createElement(const CXmlElement &xmlElement) const; private: - bool _bEnableDefaultMechanism; - CDefaultElementBuilder _DefaultElementBuilder; + std::unique_ptr<CDefaultElementBuilder> _defaultBuilder; }; -template<class CDefaultElementBuilder> -CDefaultElementLibrary<CDefaultElementBuilder>::CDefaultElementLibrary(bool bEnableDefaultMechanism) : - _bEnableDefaultMechanism(bEnableDefaultMechanism), - _DefaultElementBuilder() {} - -template<class CDefaultElementBuilder> -CElement* CDefaultElementLibrary<CDefaultElementBuilder>::createElement(const CXmlElement& xmlElement) const +template <class CDefaultElementBuilder> +CElement *CDefaultElementLibrary<CDefaultElementBuilder>::createElement( + const CXmlElement &xmlElement) const { - CElement* builtElement = CElementLibrary::createElement(xmlElement); + CElement *builtElement = CElementLibrary::createElement(xmlElement); if (builtElement != NULL) { // The element was created, return it return builtElement; } - if (!_bEnableDefaultMechanism) { + if (_defaultBuilder == nullptr) { // The default builder mechanism is not enabled return NULL; } // Use the default builder - return _DefaultElementBuilder.createElement(xmlElement); + return _defaultBuilder->createElement(xmlElement); } - diff --git a/parameter/DomainConfiguration.cpp b/parameter/DomainConfiguration.cpp index ebf3056..a272c14 100644 --- a/parameter/DomainConfiguration.cpp +++ b/parameter/DomainConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -28,7 +28,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "DomainConfiguration.h" -#include "AreaConfiguration.h" #include "ConfigurableElement.h" #include "CompoundRule.h" #include "Subsystem.h" @@ -36,27 +35,21 @@ #include "XmlDomainImportContext.h" #include "XmlDomainExportContext.h" #include "ConfigurationAccessContext.h" +#include "AlwaysAssert.hpp" #include <assert.h> +#include <cstdlib> +#include <algorithm> +#include <numeric> #include "RuleParser.h" -#define base CBinarySerializableElement +#define base CElement using std::string; -CDomainConfiguration::CDomainConfiguration(const string& strName) : base(strName) +CDomainConfiguration::CDomainConfiguration(const string &strName) : base(strName) { } -CDomainConfiguration::~CDomainConfiguration() -{ - AreaConfigurationListIterator it; - - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - delete *it; - } -} - // Class kind string CDomainConfiguration::getKind() const { @@ -70,225 +63,213 @@ bool CDomainConfiguration::childrenAreDynamic() const } // XML configuration settings parsing -bool CDomainConfiguration::parseSettings(CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext) +bool CDomainConfiguration::parseSettings(CXmlElement &xmlConfigurationSettingsElement, + CXmlDomainImportContext &context) { - // Actual XML context - CXmlDomainImportContext& xmlDomainImportContext = static_cast<CXmlDomainImportContext&>(serializingContext); - - // Take care of configurable elements / area configurations ranks - std::list<CAreaConfiguration*> areaConfigurationList; - // Parse configurable element's configuration settings CXmlElement::CChildIterator it(xmlConfigurationSettingsElement); CXmlElement xmlConfigurableElementSettingsElement; + auto insertLocation = begin(mAreaConfigurationList); while (it.next(xmlConfigurableElementSettingsElement)) { // Retrieve area configuration - string strConfigurableElementPath = xmlConfigurableElementSettingsElement.getAttributeString("Path"); - - CAreaConfiguration* pAreaConfiguration = findAreaConfiguration(strConfigurableElementPath); + string configurableElementPath; + xmlConfigurableElementSettingsElement.getAttribute("Path", configurableElementPath); - if (!pAreaConfiguration) { + auto areaConfiguration = findAreaConfigurationByPath(configurableElementPath); + if (areaConfiguration == end(mAreaConfigurationList)) { - xmlDomainImportContext.setError("Configurable Element " + strConfigurableElementPath + " referred to by Configuration " + getPath() + " not associated to Domain"); + context.setError("Configurable Element " + configurableElementPath + + " referred to by Configuration " + getPath() + + " not associated to Domain"); return false; } - // Ranks - areaConfigurationList.push_back(pAreaConfiguration); - // Parse - if (!serializeConfigurableElementSettings(pAreaConfiguration, xmlConfigurableElementSettingsElement, xmlDomainImportContext, false)) { + if (!importOneConfigurableElementSettings(areaConfiguration->get(), + xmlConfigurableElementSettingsElement, context)) { return false; } + // Take into account the new configuration order by moving the configuration associated to + // the element to the n-th position of the configuration list. + // It will result in prepending to the configuration list wit the configuration of all + // elements found in XML, keeping the order of the processing of the XML file. + mAreaConfigurationList.splice(insertLocation, mAreaConfigurationList, areaConfiguration); + // areaConfiguration is still valid, but now refer to the reorderer list + insertLocation = std::next(areaConfiguration); } - - // Reorder area configurations according to XML content - reorderAreaConfigurations(areaConfigurationList); - return true; } // XML configuration settings composing -void CDomainConfiguration::composeSettings(CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext) const +void CDomainConfiguration::composeSettings(CXmlElement &xmlConfigurationSettingsElement, + CXmlDomainExportContext &context) const { // Go through all are configurations - AreaConfigurationListIterator it; - - for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) { - - const CAreaConfiguration* pAreaConfiguration = *it; + for (auto &areaConfiguration : mAreaConfigurationList) { // Retrieve configurable element - const CConfigurableElement* pConfigurableElement = pAreaConfiguration->getConfigurableElement(); + const CConfigurableElement *pConfigurableElement = + areaConfiguration->getConfigurableElement(); // Create configurable element child element CXmlElement xmlConfigurableElementSettingsElement; - xmlConfigurationSettingsElement.createChild(xmlConfigurableElementSettingsElement, "ConfigurableElement"); + xmlConfigurationSettingsElement.createChild(xmlConfigurableElementSettingsElement, + "ConfigurableElement"); // Set Path attribute - xmlConfigurableElementSettingsElement.setAttributeString("Path", pConfigurableElement->getPath()); + xmlConfigurableElementSettingsElement.setAttribute("Path", pConfigurableElement->getPath()); // Delegate composing to area configuration - ((CDomainConfiguration&)(*this)).serializeConfigurableElementSettings((CAreaConfiguration*)pAreaConfiguration, xmlConfigurableElementSettingsElement, serializingContext, true); + exportOneConfigurableElementSettings(areaConfiguration.get(), + xmlConfigurableElementSettingsElement, context); } } // Serialize one configuration for one configurable element -bool CDomainConfiguration::serializeConfigurableElementSettings(CAreaConfiguration* pAreaConfiguration, CXmlElement& xmlConfigurableElementSettingsElement, CXmlSerializingContext& serializingContext, bool bSerializeOut) +bool CDomainConfiguration::importOneConfigurableElementSettings( + CAreaConfiguration *areaConfiguration, CXmlElement &xmlConfigurableElementSettingsElement, + CXmlDomainImportContext &context) { - // Actual XML context - CXmlDomainExportContext& xmlDomainExportContext = - static_cast<CXmlDomainExportContext&>(serializingContext); - - // Configurable Element - const CConfigurableElement* pConfigurableElement = pAreaConfiguration->getConfigurableElement(); - - // Element content - CXmlElement xmlConfigurableElementSettingsElementContent; - - // Deal with element itself - if (!bSerializeOut) { + const CConfigurableElement *destination = areaConfiguration->getConfigurableElement(); - // Check structure - if (xmlConfigurableElementSettingsElement.getNbChildElements() != 1) { + // Check structure + if (xmlConfigurableElementSettingsElement.getNbChildElements() != 1) { - // Structure error - serializingContext.setError("Struture error encountered while parsing settings of " + pConfigurableElement->getKind() + " " + pConfigurableElement->getName() + " in Configuration " + getPath()); - - return false; - } + // Structure error + context.setError("Struture error encountered while parsing settings of " + + destination->getKind() + " " + destination->getName() + + " in Configuration " + getPath()); - // Check name and kind - if (!xmlConfigurableElementSettingsElement.getChildElement(pConfigurableElement->getKind(), pConfigurableElement->getName(), xmlConfigurableElementSettingsElementContent)) { + return false; + } - serializingContext.setError("Couldn't find settings for " + pConfigurableElement->getKind() + " " + pConfigurableElement->getName() + " for Configuration " + getPath()); + // Element content + CXmlElement xmlConfigurableElementSettingsElementContent; + // Check name and kind + if (!xmlConfigurableElementSettingsElement.getChildElement( + destination->getXmlElementName(), destination->getName(), + xmlConfigurableElementSettingsElementContent)) { + + // "Component" tag has been renamed to "ParameterBlock", but retro-compatibility shall + // be ensured. + // + // So checking if this case occurs, i.e. element name is "ParameterBlock" + // but found xml setting name is "Component". + bool compatibilityCase = + (destination->getXmlElementName() == "ParameterBlock") && + xmlConfigurableElementSettingsElement.getChildElement( + "Component", destination->getName(), xmlConfigurableElementSettingsElementContent); + + // Error if the compatibility case does not occur. + if (!compatibilityCase) { + context.setError("Couldn't find settings for " + destination->getXmlElementName() + + " " + destination->getName() + " for Configuration " + getPath()); return false; } - } else { - - // Create child XML element - xmlConfigurableElementSettingsElement.createChild(xmlConfigurableElementSettingsElementContent, pConfigurableElement->getKind()); - - // Set Name - xmlConfigurableElementSettingsElementContent.setNameAttribute(pConfigurableElement->getName()); } - // Change context type to parameter settings access - string strError; - // Create configuration access context - CConfigurationAccessContext configurationAccessContext(strError, bSerializeOut); - - // Provide current value space - configurationAccessContext.setValueSpaceRaw(xmlDomainExportContext.valueSpaceIsRaw()); + string error; + CConfigurationAccessContext configurationAccessContext(error, false); - // Provide current output raw format - configurationAccessContext.setOutputRawFormat(xmlDomainExportContext.outputRawFormatIsHex()); + // Have domain configuration parse settings for configurable element + bool success = areaConfiguration->serializeXmlSettings( + xmlConfigurableElementSettingsElementContent, configurationAccessContext); - // Get subsystem - const CSubsystem* pSubsystem = pConfigurableElement->getBelongingSubsystem(); + context.appendToError(error); + return success; +} - if (pSubsystem && pSubsystem != pConfigurableElement) { +bool CDomainConfiguration::exportOneConfigurableElementSettings( + CAreaConfiguration *areaConfiguration, CXmlElement &xmlConfigurableElementSettingsElement, + CXmlDomainExportContext &context) const +{ + const CConfigurableElement *source = areaConfiguration->getConfigurableElement(); - // Element is a descendant of subsystem + // Create child XML element + CXmlElement xmlConfigurableElementSettingsElementContent; + xmlConfigurableElementSettingsElement.createChild(xmlConfigurableElementSettingsElementContent, + source->getXmlElementName()); - // Deal with Endianness - configurationAccessContext.setBigEndianSubsystem(pSubsystem->isBigEndian()); - } + // Create configuration access context + string error; + CConfigurationAccessContext configurationAccessContext(error, true); + configurationAccessContext.setValueSpaceRaw(context.valueSpaceIsRaw()); + configurationAccessContext.setOutputRawFormat(context.outputRawFormatIsHex()); // Have domain configuration parse settings for configurable element - if (!pAreaConfiguration->serializeXmlSettings(xmlConfigurableElementSettingsElementContent, configurationAccessContext)) { - - // Forward error - xmlDomainExportContext.setError(strError); + bool success = areaConfiguration->serializeXmlSettings( + xmlConfigurableElementSettingsElementContent, configurationAccessContext); - return false; - } - return true; + context.appendToError(error); + return success; } -// Configurable Elements association -void CDomainConfiguration::addConfigurableElement(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet) +void CDomainConfiguration::addConfigurableElement(const CConfigurableElement *configurableElement, + const CSyncerSet *syncerSet) { - CAreaConfiguration* pAreaConfiguration = pConfigurableElement->createAreaConfiguration(pSyncerSet); - - _areaConfigurationList.push_back(pAreaConfiguration); - _orderedAreaConfigurationList.push_back(pAreaConfiguration); + mAreaConfigurationList.emplace_back(configurableElement->createAreaConfiguration(syncerSet)); } -void CDomainConfiguration::removeConfigurableElement(const CConfigurableElement* pConfigurableElement) +void CDomainConfiguration::removeConfigurableElement( + const CConfigurableElement *pConfigurableElement) { - CAreaConfiguration* pAreaConfigurationToRemove = getAreaConfiguration(pConfigurableElement); - - _areaConfigurationList.remove(pAreaConfigurationToRemove); - _orderedAreaConfigurationList.remove(pAreaConfigurationToRemove); + auto &areaConfigurationToRemove = getAreaConfiguration(pConfigurableElement); - delete pAreaConfigurationToRemove; + mAreaConfigurationList.remove(areaConfigurationToRemove); } -// Sequence management -bool CDomainConfiguration::setElementSequence(const std::vector<string>& astrNewElementSequence, string& strError) +bool CDomainConfiguration::setElementSequence(const std::vector<string> &newElementSequence, + string &error) { - // Build a new list of AreaConfiguration objects - std::list<CAreaConfiguration*> areaConfigurationList; + std::vector<string> elementSequenceSet; + auto insertLocation = begin(mAreaConfigurationList); - uint32_t uiConfigurableElement; + for (const std::string &elementPath : newElementSequence) { - for (uiConfigurableElement = 0; uiConfigurableElement < astrNewElementSequence.size(); uiConfigurableElement++) { + auto areaConfiguration = findAreaConfigurationByPath(elementPath); + if (areaConfiguration == end(mAreaConfigurationList)) { - string strConfigurableElementPath = astrNewElementSequence[uiConfigurableElement]; - - CAreaConfiguration* pAreaConfiguration = findAreaConfiguration(strConfigurableElementPath); - - if (!pAreaConfiguration) { - - strError = "Element " + strConfigurableElementPath + " not found in domain"; + error = "Element " + elementPath + " not found in domain"; return false; } - // Check not already present in the list - if (findAreaConfiguration(strConfigurableElementPath, areaConfigurationList)) { - - strError = "Element " + strConfigurableElementPath + " provided more than once"; - + auto it = find(begin(elementSequenceSet), end(elementSequenceSet), elementPath); + if (it != end(elementSequenceSet)) { + error = "Element " + elementPath + " provided more than once"; return false; } - - // Store new ordered area configuration - areaConfigurationList.push_back(pAreaConfiguration); + elementSequenceSet.push_back(elementPath); + // Take into account the new configuration order by moving the configuration associated to + // the element to the n-th position of the configuration list. + // It will result in prepending to the configuration list wit the configuration of all + // elements found in XML, keeping the order of the processing of the XML file. + mAreaConfigurationList.splice(insertLocation, mAreaConfigurationList, areaConfiguration); + // areaConfiguration is still valid, but now refer to the reorderer list + insertLocation = std::next(areaConfiguration); } - - // Reorder area configurations according to given path list - reorderAreaConfigurations(areaConfigurationList); - return true; } -void CDomainConfiguration::getElementSequence(string& strResult) const +void CDomainConfiguration::getElementSequence(string &strResult) const { - strResult = "\n"; - - AreaConfigurationListIterator it; - // List configurable element paths out of ordered area configuration list - for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) { - - const CAreaConfiguration* pAreaConfiguration = *it; - - const CConfigurableElement* pConfigurableElement = pAreaConfiguration->getConfigurableElement(); - - strResult += pConfigurableElement->getPath() + "\n"; - } + strResult = accumulate(begin(mAreaConfigurationList), end(mAreaConfigurationList), string("\n"), + [](const string &a, const AreaConfiguration &conf) { + return a + conf->getConfigurableElement()->getPath() + "\n"; + }); } // Application rule -bool CDomainConfiguration::setApplicationRule(const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError) +bool CDomainConfiguration::setApplicationRule( + const string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, string &strError) { // Parser CRuleParser ruleParser(strApplicationRule, pSelectionCriteriaDefinition); @@ -310,22 +291,10 @@ void CDomainConfiguration::clearApplicationRule() setRule(NULL); } -void CDomainConfiguration::getApplicationRule(string& strResult) const +string CDomainConfiguration::getApplicationRule() const { - // Rule - const CCompoundRule* pRule = getRule(); - - if (pRule) { - // Start clear - strResult.clear(); - - // Dump rule - pRule->dump(strResult); - - } else { - - strResult = "<none>"; - } + const CCompoundRule *pRule = getRule(); + return pRule ? pRule->dump() : "<none>"; } /** @@ -340,141 +309,126 @@ void CDomainConfiguration::getApplicationRule(string& strResult) const * * return Pointer to the Blackboard of the Configuration. */ -CParameterBlackboard* CDomainConfiguration::getBlackboard(const CConfigurableElement* pConfigurableElement) const +CParameterBlackboard *CDomainConfiguration::getBlackboard( + const CConfigurableElement *pConfigurableElement) const { - AreaConfigurationListIterator it; - - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - CAreaConfiguration* pAreaConfiguration = *it; - - // Check if the Element is associated with the Domain - if (pAreaConfiguration->getConfigurableElement() == pConfigurableElement) { - - return &pAreaConfiguration->getBlackboard(); - } - } - - assert(0); - return NULL; + const auto &it = find_if(begin(mAreaConfigurationList), end(mAreaConfigurationList), + [&](const AreaConfiguration &conf) { + return conf != nullptr && + conf->getConfigurableElement() == pConfigurableElement; + }); + ALWAYS_ASSERT(it != end(mAreaConfigurationList), "Configurable Element " + << pConfigurableElement->getName() + << " not found in any area Configuration"); + return &(*it)->getBlackboard(); } // Save data from current -void CDomainConfiguration::save(const CParameterBlackboard* pMainBlackboard) +void CDomainConfiguration::save(const CParameterBlackboard *pMainBlackboard) { - AreaConfigurationListIterator it; - // Just propagate to areas - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - CAreaConfiguration* pAreaConfiguration = *it; - - pAreaConfiguration->save(pMainBlackboard); + for (auto &areaConfiguration : mAreaConfigurationList) { + areaConfiguration->save(pMainBlackboard); } } // Apply data to current -bool CDomainConfiguration::restore(CParameterBlackboard* pMainBlackboard, bool bSync, std::list<string>* plstrError) const +bool CDomainConfiguration::restore(CParameterBlackboard *pMainBlackboard, bool bSync, + core::Results *errors) const { - bool bSuccess = true; - - AreaConfigurationListIterator it; - - // Just propagate to areas - for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) { - - const CAreaConfiguration* pAreaConfiguration = *it; - - bSuccess &= pAreaConfiguration->restore(pMainBlackboard, bSync, plstrError); - } - - return bSuccess; + return std::accumulate(begin(mAreaConfigurationList), end(mAreaConfigurationList), true, + [&](bool accumulator, const AreaConfiguration &conf) { + return conf->restore(pMainBlackboard, bSync, errors) && accumulator; + }); } // Ensure validity for configurable element area configuration -void CDomainConfiguration::validate(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard) +void CDomainConfiguration::validate(const CConfigurableElement *pConfigurableElement, + const CParameterBlackboard *pMainBlackboard) { - CAreaConfiguration* pAreaConfigurationToValidate = getAreaConfiguration(pConfigurableElement); + auto &areaConfigurationToValidate = getAreaConfiguration(pConfigurableElement); // Delegate - pAreaConfigurationToValidate->validate(pMainBlackboard); + areaConfigurationToValidate->validate(pMainBlackboard); } // Ensure validity of all area configurations -void CDomainConfiguration::validate(const CParameterBlackboard* pMainBlackboard) +void CDomainConfiguration::validate(const CParameterBlackboard *pMainBlackboard) { - AreaConfigurationListIterator it; - - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - CAreaConfiguration* pAreaConfiguration = *it; - - pAreaConfiguration->validate(pMainBlackboard); + for (auto &areaConfiguration : mAreaConfigurationList) { + areaConfiguration->validate(pMainBlackboard); } } // Return configuration validity for given configurable element -bool CDomainConfiguration::isValid(const CConfigurableElement* pConfigurableElement) const +bool CDomainConfiguration::isValid(const CConfigurableElement *pConfigurableElement) const { // Get child configurable elemnt's area configuration - CAreaConfiguration* pAreaConfiguration = getAreaConfiguration(pConfigurableElement); + auto &areaConfiguration = getAreaConfiguration(pConfigurableElement); - assert(pAreaConfiguration); + ALWAYS_ASSERT(areaConfiguration != nullptr, "Configurable Element " + << pConfigurableElement->getName() + << " not found in any area Configuration"); - return pAreaConfiguration->isValid(); + return areaConfiguration->isValid(); } // Ensure validity of configurable element's area configuration by copying in from a valid one -void CDomainConfiguration::validateAgainst(const CDomainConfiguration* pValidDomainConfiguration, const CConfigurableElement* pConfigurableElement) +void CDomainConfiguration::validateAgainst(const CDomainConfiguration *pValidDomainConfiguration, + const CConfigurableElement *pConfigurableElement) { // Retrieve related area configurations - CAreaConfiguration* pAreaConfigurationToValidate = getAreaConfiguration(pConfigurableElement); - const CAreaConfiguration* pAreaConfigurationToValidateAgainst = pValidDomainConfiguration->getAreaConfiguration(pConfigurableElement); + auto &areaConfigurationToValidate = getAreaConfiguration(pConfigurableElement); + const auto &areaConfigurationToValidateAgainst = + pValidDomainConfiguration->getAreaConfiguration(pConfigurableElement); // Delegate to area - pAreaConfigurationToValidate->validateAgainst(pAreaConfigurationToValidateAgainst); -} - -// Ensure validity of all configurable element's area configuration by copying in from a valid ones -void CDomainConfiguration::validateAgainst(const CDomainConfiguration* pValidDomainConfiguration) -{ - // Copy in configuration data from against domain - AreaConfigurationListIterator it, itAgainst; - - for (it = _areaConfigurationList.begin(), itAgainst = pValidDomainConfiguration->_areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it, ++itAgainst) { - - CAreaConfiguration* pAreaConfigurationToValidate = *it; - const CAreaConfiguration* pAreaConfigurationToValidateAgainst = *itAgainst; - + areaConfigurationToValidate->validateAgainst(areaConfigurationToValidateAgainst.get()); +} + +void CDomainConfiguration::validateAgainst(const CDomainConfiguration *validDomainConfiguration) +{ + ALWAYS_ASSERT(mAreaConfigurationList.size() == + validDomainConfiguration->mAreaConfigurationList.size(), + "Cannot validate domain configuration " + << getPath() << " since area configuration list does not have the same size" + "than the configuration list to check against"); + for (const auto &configurationToValidateAgainst : + validDomainConfiguration->mAreaConfigurationList) { + // Get the area configuration associated to the configurable element of the + // valid area configuration, it will assert if none found. + auto configurableElement = configurationToValidateAgainst->getConfigurableElement(); + auto &configurationToValidate = getAreaConfiguration(configurableElement); // Delegate to area - pAreaConfigurationToValidate->validateAgainst(pAreaConfigurationToValidateAgainst); + configurationToValidate->validateAgainst(configurationToValidateAgainst.get()); } } // Dynamic data application bool CDomainConfiguration::isApplicable() const { - const CCompoundRule* pRule = getRule(); + const CCompoundRule *pRule = getRule(); return pRule && pRule->matches(); } // Merge existing configurations to given configurable element ones -void CDomainConfiguration::merge(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement) +void CDomainConfiguration::merge(CConfigurableElement *pToConfigurableElement, + CConfigurableElement *pFromConfigurableElement) { // Retrieve related area configurations - CAreaConfiguration* pAreaConfigurationToMergeTo = getAreaConfiguration(pToConfigurableElement); - const CAreaConfiguration* pAreaConfigurationToMergeFrom = getAreaConfiguration(pFromConfigurableElement); + auto &areaConfigurationToMergeTo = getAreaConfiguration(pToConfigurableElement); + const auto &areaConfigurationToMergeFrom = getAreaConfiguration(pFromConfigurableElement); // Do the merge - pAreaConfigurationToMergeFrom->copyToOuter(pAreaConfigurationToMergeTo); + areaConfigurationToMergeFrom->copyToOuter(areaConfigurationToMergeTo.get()); } // Domain splitting -void CDomainConfiguration::split(CConfigurableElement* pFromConfigurableElement) +void CDomainConfiguration::split(CConfigurableElement *pFromConfigurableElement) { // Retrieve related area configuration - const CAreaConfiguration* pAreaConfigurationToSplitFrom = getAreaConfiguration(pFromConfigurableElement); + const auto &areaConfigurationToSplitFrom = getAreaConfiguration(pFromConfigurableElement); // Go through children areas to copy configuration data to them size_t uiNbConfigurableElementChildren = pFromConfigurableElement->getNbChildren(); @@ -482,140 +436,63 @@ void CDomainConfiguration::split(CConfigurableElement* pFromConfigurableElement) for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) { - CConfigurableElement* pToChildConfigurableElement = static_cast<CConfigurableElement*>(pFromConfigurableElement->getChild(uiChild)); + CConfigurableElement *pToChildConfigurableElement = + static_cast<CConfigurableElement *>(pFromConfigurableElement->getChild(uiChild)); // Get child configurable elemnt's area configuration - CAreaConfiguration* pChildAreaConfiguration = getAreaConfiguration(pToChildConfigurableElement); + auto &childAreaConfiguration = getAreaConfiguration(pToChildConfigurableElement); // Do the copy - pChildAreaConfiguration->copyFromOuter(pAreaConfigurationToSplitFrom); + childAreaConfiguration->copyFromOuter(areaConfigurationToSplitFrom.get()); } } -// AreaConfiguration retrieval from configurable element -CAreaConfiguration* CDomainConfiguration::getAreaConfiguration(const CConfigurableElement* pConfigurableElement) const +const CDomainConfiguration::AreaConfiguration &CDomainConfiguration::getAreaConfiguration( + const CConfigurableElement *pConfigurableElement) const { - AreaConfigurationListIterator it; - - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - CAreaConfiguration* pAreaConfiguration = *it; - - if (pAreaConfiguration->getConfigurableElement() == pConfigurableElement) { - - return pAreaConfiguration; - } - } - // Not found? - assert(0); - - return NULL; -} - -// AreaConfiguration retrieval from present area configurations -CAreaConfiguration* CDomainConfiguration::findAreaConfiguration(const string& strConfigurableElementPath) const -{ - return findAreaConfiguration(strConfigurableElementPath, _areaConfigurationList); -} - -// AreaConfiguration retrieval from given area configuration list -CAreaConfiguration* CDomainConfiguration::findAreaConfiguration(const string& strConfigurableElementPath, const std::list<CAreaConfiguration*>& areaConfigurationList) const -{ - AreaConfigurationListIterator it; - - for (it = areaConfigurationList.begin(); it != areaConfigurationList.end(); ++it) { - - CAreaConfiguration* pAreaConfiguration = *it; - - if (pAreaConfiguration->getConfigurableElement()->getPath() == strConfigurableElementPath) { - - return pAreaConfiguration; - } - } - - // Not found - return NULL; + const auto &it = find_if(begin(mAreaConfigurationList), end(mAreaConfigurationList), + [&](const AreaConfiguration &conf) { + return conf->getConfigurableElement() == pConfigurableElement; + }); + ALWAYS_ASSERT(it != end(mAreaConfigurationList), + "Configurable Element " << pConfigurableElement->getName() + << " not found in Domain Configuration list"); + return *it; } -// Area configuration ordering -void CDomainConfiguration::reorderAreaConfigurations(const std::list<CAreaConfiguration*>& areaConfigurationList) +CDomainConfiguration::AreaConfigurations::iterator CDomainConfiguration:: + findAreaConfigurationByPath(const std::string &configurableElementPath) { - // Ensure elements in provided list appear first and ordered the same way in internal one - - // Remove all elements present in the provided list from the internal one - AreaConfigurationListIterator it; - - for (it = areaConfigurationList.begin(); it != areaConfigurationList.end(); ++it) { - - _orderedAreaConfigurationList.remove(*it); - } - - // Prepended provided elements into internal list - _orderedAreaConfigurationList.insert(_orderedAreaConfigurationList.begin(), areaConfigurationList.begin(), areaConfigurationList.end()); -} - -// Find area configuration rank from regular list: for ordered list maintainance -uint32_t CDomainConfiguration::getAreaConfigurationRank(const CAreaConfiguration* pAreaConfiguration) const -{ - uint32_t uiAreaConfigurationRank; - AreaConfigurationListIterator it; - - // Propagate request to areas - for (it = _areaConfigurationList.begin(), uiAreaConfigurationRank = 0; it != _areaConfigurationList.end(); ++it, ++uiAreaConfigurationRank) { - - if (*it == pAreaConfiguration) { - - return uiAreaConfigurationRank; - } - } - - assert(0); - - return 0; -} - -// Find area configuration from regular list based on rank: for ordered list maintainance -CAreaConfiguration* CDomainConfiguration::getAreaConfiguration(uint32_t uiAreaConfigurationRank) const -{ - AreaConfigurationListIterator it; - uint32_t uiCurrentAreaConfigurationRank; - - // Propagate request to areas - for (it = _areaConfigurationList.begin(), uiCurrentAreaConfigurationRank = 0; it != _areaConfigurationList.end(); ++it, ++uiCurrentAreaConfigurationRank) { - - if (uiCurrentAreaConfigurationRank == uiAreaConfigurationRank) { - - return *it; - } - } - - assert(0); - - return NULL; + auto areaConfiguration = + find_if(begin(mAreaConfigurationList), end(mAreaConfigurationList), + [&](const AreaConfiguration &conf) { + return conf->getConfigurableElement()->getPath() == configurableElementPath; + }); + return areaConfiguration; } // Rule -const CCompoundRule* CDomainConfiguration::getRule() const +const CCompoundRule *CDomainConfiguration::getRule() const { if (getNbChildren()) { // Rule created - return static_cast<const CCompoundRule*>(getChild(ECompoundRule)); + return static_cast<const CCompoundRule *>(getChild(ECompoundRule)); } return NULL; } -CCompoundRule* CDomainConfiguration::getRule() +CCompoundRule *CDomainConfiguration::getRule() { if (getNbChildren()) { // Rule created - return static_cast<CCompoundRule*>(getChild(ECompoundRule)); + return static_cast<CCompoundRule *>(getChild(ECompoundRule)); } return NULL; } -void CDomainConfiguration::setRule(CCompoundRule* pRule) +void CDomainConfiguration::setRule(CCompoundRule *pRule) { - CCompoundRule* pOldRule = getRule(); + CCompoundRule *pOldRule = getRule(); if (pOldRule) { // Remove previous rule @@ -630,66 +507,3 @@ void CDomainConfiguration::setRule(CCompoundRule* pRule) addChild(pRule); } } - -// Serialization -void CDomainConfiguration::binarySerialize(CBinaryStream& binaryStream) -{ - AreaConfigurationListIterator it; - - // Area configurations order - if (binaryStream.isOut()) { - - for (it = _orderedAreaConfigurationList.begin(); it != _orderedAreaConfigurationList.end(); ++it) { - - // Get rank - uint32_t uiAreaConfigurationRank = getAreaConfigurationRank(*it); - - // Store it - binaryStream.write((const uint8_t*)&uiAreaConfigurationRank, sizeof(uiAreaConfigurationRank)); - } - } else { - - // Empty ordered list first - _orderedAreaConfigurationList.resize(0); - - uint32_t uiAreaConfiguration; - - for (uiAreaConfiguration = 0; uiAreaConfiguration < _areaConfigurationList.size(); uiAreaConfiguration++) { - - // Get rank - uint32_t uiAreaConfigurationRank; - - binaryStream.read((uint8_t*)&uiAreaConfigurationRank, sizeof(uiAreaConfigurationRank)); - - _orderedAreaConfigurationList.push_back(getAreaConfiguration(uiAreaConfigurationRank)); - } - } - - // Propagate to areas - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - CAreaConfiguration* pAreaConfiguration = *it; - - pAreaConfiguration->serialize(binaryStream); - } -} - -// Data size -size_t CDomainConfiguration::getDataSize() const -{ - size_t uiDataSize; - - // Add necessary size to store area configurations order - uiDataSize = _areaConfigurationList.size() * sizeof(uint32_t); - - // Propagate request to areas - AreaConfigurationListIterator it; - - for (it = _areaConfigurationList.begin(); it != _areaConfigurationList.end(); ++it) { - - const CAreaConfiguration* pAreaConfiguration = *it; - - uiDataSize += pAreaConfiguration->getSize(); - } - return uiDataSize; -} diff --git a/parameter/DomainConfiguration.h b/parameter/DomainConfiguration.h index e8b41ef..f45c155 100644 --- a/parameter/DomainConfiguration.h +++ b/parameter/DomainConfiguration.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,102 +29,132 @@ */ #pragma once -#include "BinarySerializableElement.h" +#include "AreaConfiguration.h" +#include "XmlDomainImportContext.h" +#include "XmlDomainExportContext.h" +#include "Element.h" +#include "Results.h" #include <list> #include <string> +#include <memory> class CConfigurableElement; -class CAreaConfiguration; class CParameterBlackboard; class CConfigurationAccessContext; class CCompoundRule; class CSyncerSet; class CSelectionCriteriaDefinition; -class CDomainConfiguration : public CBinarySerializableElement +class CDomainConfiguration : public CElement { - enum ChildElementType { + enum ChildElementType + { ECompoundRule }; - typedef std::list<CAreaConfiguration*>::const_iterator AreaConfigurationListIterator; + public: - CDomainConfiguration(const std::string& strName); - virtual ~CDomainConfiguration(); + CDomainConfiguration(const std::string &strName); // Configurable Elements association - void addConfigurableElement(const CConfigurableElement* pConfigurableElement, const CSyncerSet* pSyncerSet); - void removeConfigurableElement(const CConfigurableElement* pConfigurableElement); + void addConfigurableElement(const CConfigurableElement *configurableElement, + const CSyncerSet *syncerSet); + void removeConfigurableElement(const CConfigurableElement *pConfigurableElement); - // Sequence management - bool setElementSequence(const std::vector<std::string>& astrNewElementSequence, std::string& strError); - void getElementSequence(std::string& strResult) const; + /** + * Sequence management: Prepend provided elements into internal list in the same order than + * they appear in the sequence of element path. + * @param[in] newElementSequence sequence of path of new element + * @param[out] error human readable error + * @return true if the new sequence has been taken into account, false otherwise and error is + * set accordingly. + */ + bool setElementSequence(const std::vector<std::string> &newElementSequence, std::string &error); + void getElementSequence(std::string &strResult) const; // Application rule - bool setApplicationRule(const std::string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, std::string& strError); + bool setApplicationRule(const std::string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition, + std::string &strError); void clearApplicationRule(); - void getApplicationRule(std::string& strResult) const; + std::string getApplicationRule() const; // Get Blackboard for an element of the domain - CParameterBlackboard* getBlackboard(const CConfigurableElement* pConfigurableElement) const; + CParameterBlackboard *getBlackboard(const CConfigurableElement *pConfigurableElement) const; // Save data from current - void save(const CParameterBlackboard* pMainBlackboard); - // Apply data to current - bool restore(CParameterBlackboard* pMainBlackboard, bool bSync, std::list<std::string>* plstrError = NULL) const; + void save(const CParameterBlackboard *pMainBlackboard); + + /** Restore the configuration + * + * @param[in] pMainBlackboard the application main blackboard + * @param[in] bSync indicates if a synchronisation has to be done + * @param[out] errors, errors encountered during restoration + * @return true if success false otherwise + */ + bool restore(CParameterBlackboard *pMainBlackboard, bool bSync, + core::Results *errors = NULL) const; + // Ensure validity for configurable element area configuration - void validate(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard); + void validate(const CConfigurableElement *pConfigurableElement, + const CParameterBlackboard *pMainBlackboard); // Ensure validity of all area configurations - void validate(const CParameterBlackboard* pMainBlackboard); + void validate(const CParameterBlackboard *pMainBlackboard); // Return configuration validity for given configurable element - bool isValid(const CConfigurableElement* pConfigurableElement) const; + bool isValid(const CConfigurableElement *pConfigurableElement) const; // Ensure validity of configurable element's area configuration by copying in from a valid one - void validateAgainst(const CDomainConfiguration* pValidDomainConfiguration, const CConfigurableElement* pConfigurableElement); - // Ensure validity of all configurable element's area configuration by copying in from a valid ones - void validateAgainst(const CDomainConfiguration* pValidDomainConfiguration); + void validateAgainst(const CDomainConfiguration *pValidDomainConfiguration, + const CConfigurableElement *pConfigurableElement); + // Ensure validity of all configurable element's area configuration by copying in from a valid + // ones + void validateAgainst(const CDomainConfiguration *validDomainConfiguration); // Applicability checking bool isApplicable() const; // Merge existing configurations to given configurable element ones - void merge(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement); + void merge(CConfigurableElement *pToConfigurableElement, + CConfigurableElement *pFromConfigurableElement); // Domain splitting - void split(CConfigurableElement* pFromConfigurableElement); + void split(CConfigurableElement *pFromConfigurableElement); // XML configuration settings parsing/composing - bool parseSettings(CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext); - void composeSettings(CXmlElement& xmlConfigurationSettingsElement, CXmlSerializingContext& serializingContext) const; - - // Serialization - virtual void binarySerialize(CBinaryStream& binaryStream); - - // Data size - virtual size_t getDataSize() const; + bool parseSettings(CXmlElement &xmlConfigurationSettingsElement, + CXmlDomainImportContext &context); + void composeSettings(CXmlElement &xmlConfigurationSettingsElement, + CXmlDomainExportContext &context) const; // Class kind virtual std::string getKind() const; private: - // Returns true if children dynamic creation is to be dealt with (here, will allow child deletion upon clean) + using AreaConfiguration = std::unique_ptr<CAreaConfiguration>; + using AreaConfigurations = std::list<AreaConfiguration>; + + // Returns true if children dynamic creation is to be dealt with (here, will allow child + // deletion upon clean) virtual bool childrenAreDynamic() const; // XML configuration settings serializing - bool serializeConfigurableElementSettings(CAreaConfiguration* pAreaConfiguration, CXmlElement& xmlConfigurableElementSettingsElement, CXmlSerializingContext& serializingContext, bool bSerializeOut); + bool importOneConfigurableElementSettings(CAreaConfiguration *areaConfiguration, + CXmlElement &xmlConfigurableElementSettingsElement, + CXmlDomainImportContext &context); + bool exportOneConfigurableElementSettings(CAreaConfiguration *areaConfiguration, + CXmlElement &xmlConfigurableElementSettingsElement, + CXmlDomainExportContext &context) const; // AreaConfiguration retrieval from configurable element - CAreaConfiguration* getAreaConfiguration(const CConfigurableElement* pConfigurableElement) const; - // AreaConfiguration retrieval from present area configurations - CAreaConfiguration* findAreaConfiguration(const std::string& strConfigurableElementPath) const; - // AreaConfiguration retrieval from given area configuration std::list - CAreaConfiguration* findAreaConfiguration(const std::string& strConfigurableElementPath, const std::list<CAreaConfiguration*>& areaConfigurationList) const; - // Area configuration ordering - void reorderAreaConfigurations(const std::list<CAreaConfiguration*>& areaConfigurationList); - // Find area configuration rank from regular std::list: for ordered std::list maintainance - uint32_t getAreaConfigurationRank(const CAreaConfiguration* pAreaConfiguration) const; - // Find area configuration from regular std::list based on rank: for ordered std::list maintainance - CAreaConfiguration* getAreaConfiguration(uint32_t uiAreaConfigurationRank) const; + const AreaConfiguration &getAreaConfiguration( + const CConfigurableElement *pConfigurableElement) const; + + /** + * Returns the AreaConfiguration iterator associated to the Element refered by its path + * @param[in] configurableElementPath to check if found in current list of areaconfigurations + * @return iterator on the configuration associated to the Element with the given path, + * last if not found + */ + AreaConfigurations::iterator findAreaConfigurationByPath( + const std::string &configurableElementPath); // Rule - const CCompoundRule* getRule() const; - CCompoundRule* getRule(); - void setRule(CCompoundRule* pRule); + const CCompoundRule *getRule() const; + CCompoundRule *getRule(); + void setRule(CCompoundRule *pRule); - // AreaConfigurations - std::list<CAreaConfiguration*> _areaConfigurationList; - std::list<CAreaConfiguration*> _orderedAreaConfigurationList; + AreaConfigurations mAreaConfigurationList; }; diff --git a/parameter/Element.cpp b/parameter/Element.cpp index afd1f33..77dfd9d 100644 --- a/parameter/Element.cpp +++ b/parameter/Element.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -30,7 +30,8 @@ #include "Element.h" #include "XmlElementSerializingContext.h" #include "ElementLibrary.h" -#include "ErrorContext.h" +#include "ErrorContext.hpp" +#include <algorithm> #include <assert.h> #include <stdio.h> #include <stdarg.h> @@ -40,7 +41,7 @@ using std::string; const std::string CElement::gDescriptionPropertyName = "Description"; -CElement::CElement(const string& strName) : _strName(strName), _pParent(NULL) +CElement::CElement(const string &strName) : _strName(strName) { } @@ -49,87 +50,12 @@ CElement::~CElement() removeChildren(); } -// Logging -void CElement::log_info(const char* strMessage, ...) const -{ - char *pacBuffer; - va_list listPointer; - - va_start(listPointer, strMessage); - - vasprintf(&pacBuffer, strMessage, listPointer); - - va_end(listPointer); - - if (pacBuffer != NULL) { - doLog(false, pacBuffer); - } - - free(pacBuffer); -} - -void CElement::log_warning(const char* strMessage, ...) const -{ - char *pacBuffer; - va_list listPointer; - - va_start(listPointer, strMessage); - - vasprintf(&pacBuffer, strMessage, listPointer); - - va_end(listPointer); - - if (pacBuffer != NULL) { - doLog(true, pacBuffer); - } - - free(pacBuffer); -} - -// Log each element of the string list -void CElement::log_table(bool bIsWarning, const std::list<string> lstrMessage) const -{ - std::list<string>::const_iterator iterator(lstrMessage.begin()); - std::list<string>::const_iterator end(lstrMessage.end()); - - while (iterator != end) { - // Log current list element - doLog(bIsWarning, iterator->c_str()); - ++iterator; - } -} - -void CElement::doLog(bool bIsWarning, const string& strLog) const -{ - assert(_pParent); - - // Propagate till root - _pParent->doLog(bIsWarning, strLog); -} - -void CElement::nestLog() const -{ - assert(_pParent); - - // Propagate till root - _pParent->nestLog(); -} - -void CElement::unnestLog() const -{ - assert(_pParent); - - // Propagate till root - _pParent->unnestLog(); -} - - -void CElement::setDescription(const string& strDescription) +void CElement::setDescription(const string &strDescription) { _strDescription = strDescription; } -const string& CElement::getDescription() const +const string &CElement::getDescription() const { return _strDescription; } @@ -140,15 +66,12 @@ bool CElement::childrenAreDynamic() const return false; } -bool CElement::init(string& strError) +bool CElement::init(string &strError) { - uint32_t uiIndex; - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { + for (CElement *child : _childArray) { - CElement* pElement = _childArray[uiIndex];; - - if (!pElement->init(strError)) { + if (!child->init(strError)) { return false; } @@ -157,49 +80,48 @@ bool CElement::init(string& strError) return true; } -void CElement::dumpContent(string& strContent, CErrorContext& errorContext, const uint32_t uiDepth) const +string CElement::dumpContent(utility::ErrorContext &errorContext, const size_t depth) const { + string output; string strIndent; // Level - uint32_t uiNbIndents = uiDepth; + size_t indents = depth; - while (uiNbIndents--) { + while (indents--) { strIndent += " "; } // Type - strContent += strIndent + "- " + getKind(); + output += strIndent + "- " + getKind(); // Name if (!_strName.empty()) { - strContent += ": " + getName(); + output += ": " + getName(); } // Value - string strValue; - logValue(strValue, errorContext); + string strValue = logValue(errorContext); if (!strValue.empty()) { - strContent += " = " + strValue; + output += " = " + strValue; } - strContent += "\n"; - - uint32_t uiIndex; + output += "\n"; - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { + for (CElement *pChild : _childArray) { - _childArray[uiIndex]->dumpContent(strContent, errorContext, uiDepth + 1); + output += pChild->dumpContent(errorContext, depth + 1); } + + return output; } // Element properties -void CElement::showProperties(string& strResult) const +void CElement::showProperties(string &strResult) const { - strResult = "\n"; strResult += "Kind: " + getKind() + "\n"; showDescriptionProperty(strResult); } @@ -212,28 +134,24 @@ void CElement::showDescriptionProperty(std::string &strResult) const } // Content dumping -void CElement::logValue(string& strValue, CErrorContext& errorContext) const +string CElement::logValue(utility::ErrorContext & /*ctx*/) const { - (void)strValue; - (void)errorContext; + return ""; } // From IXmlSink -bool CElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CElement::fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) { - setDescription(getXmlDescriptionAttribute(xmlElement)); + xmlElement.getAttribute(gDescriptionPropertyName, _strDescription); // Propagate through children CXmlElement::CChildIterator childIterator(xmlElement); - // Context - CXmlElementSerializingContext& elementSerializingContext = static_cast<CXmlElementSerializingContext&>(serializingContext); - CXmlElement childElement; while (childIterator.next(childElement)) { - CElement* pChild; + CElement *pChild; if (!childrenAreDynamic()) { @@ -241,7 +159,8 @@ bool CElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& se if (!pChild) { - elementSerializingContext.setError("Unable to handle XML element: " + childElement.getPath()); + serializingContext.setError("Unable to handle XML element: " + + childElement.getPath()); return false; } @@ -257,7 +176,7 @@ bool CElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& se } // Dig - if (!pChild->fromXml(childElement, elementSerializingContext)) { + if (!pChild->fromXml(childElement, serializingContext)) { return false; } @@ -266,48 +185,38 @@ bool CElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& se return true; } -void CElement::childrenToXml(CXmlElement& xmlElement, - CXmlSerializingContext& serializingContext) const +void CElement::childrenToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Browse children and propagate - size_t uiNbChildren = getNbChildren(); - size_t uiChild; - - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - - const CElement* pChild = _childArray[uiChild]; + for (CElement *pChild : _childArray) { // Create corresponding child element CXmlElement xmlChildElement; - xmlElement.createChild(xmlChildElement, pChild->getKind()); + xmlElement.createChild(xmlChildElement, pChild->getXmlElementName()); // Propagate pChild->toXml(xmlChildElement, serializingContext); } } -void CElement::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CElement::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const { setXmlNameAttribute(xmlElement); setXmlDescriptionAttribute(xmlElement); childrenToXml(xmlElement, serializingContext); } -void CElement::setXmlDescriptionAttribute(CXmlElement& xmlElement) const +void CElement::setXmlDescriptionAttribute(CXmlElement &xmlElement) const { const string &description = getDescription(); if (!description.empty()) { - xmlElement.setAttributeString(gDescriptionPropertyName, description); + xmlElement.setAttribute(gDescriptionPropertyName, description); } } -string CElement::getXmlDescriptionAttribute(const CXmlElement& xmlElement) const -{ - return xmlElement.getAttributeString(gDescriptionPropertyName); -} - -void CElement::setXmlNameAttribute(CXmlElement& xmlElement) const +void CElement::setXmlNameAttribute(CXmlElement &xmlElement) const { // By default, set Name attribute if any string strName = getName(); @@ -319,27 +228,22 @@ void CElement::setXmlNameAttribute(CXmlElement& xmlElement) const } // Name -void CElement::setName(const string& strName) +void CElement::setName(const string &strName) { _strName = strName; } -const string& CElement::getName() const +const string &CElement::getName() const { return _strName; } -bool CElement::rename(const string& strName, string& strError) +bool CElement::rename(const string &strName, string &strError) { // Check for conflict with brotherhood if relevant if (_pParent && _pParent->childrenAreDynamic()) { - size_t uiParentChild; - size_t uiParentNbChildren = _pParent->getNbChildren(); - - for (uiParentChild = 0; uiParentChild < uiParentNbChildren; uiParentChild++) { - - const CElement* pParentChild = _pParent->getChild(uiParentChild); + for (CElement *pParentChild : _pParent->_childArray) { if (pParentChild != this && pParentChild->getName() == strName) { @@ -368,41 +272,41 @@ string CElement::getPathName() const } // Hierarchy -void CElement::addChild(CElement* pChild) +void CElement::addChild(CElement *pChild) { _childArray.push_back(pChild); pChild->_pParent = this; } -CElement* CElement::getChild(size_t uiIndex) +CElement *CElement::getChild(size_t index) { - assert(uiIndex <= _childArray.size()); + assert(index <= _childArray.size()); - return _childArray[uiIndex]; + return _childArray[index]; } -const CElement* CElement::getChild(size_t uiIndex) const +const CElement *CElement::getChild(size_t index) const { - assert(uiIndex <= _childArray.size()); + assert(index <= _childArray.size()); - return _childArray[uiIndex]; + return _childArray[index]; } -CElement* CElement::createChild(const CXmlElement& childElement, - CXmlSerializingContext& serializingContext) +CElement *CElement::createChild(const CXmlElement &childElement, + CXmlSerializingContext &serializingContext) { // Context - CXmlElementSerializingContext& elementSerializingContext = - static_cast<CXmlElementSerializingContext&>(serializingContext); + CXmlElementSerializingContext &elementSerializingContext = + static_cast<CXmlElementSerializingContext &>(serializingContext); // Child needs creation - CElement* pChild = elementSerializingContext.getElementLibrary()->createElement(childElement); + CElement *pChild = elementSerializingContext.getElementLibrary()->createElement(childElement); if (!pChild) { - elementSerializingContext.setError( - "Unable to create XML element " + childElement.getPath()); + elementSerializingContext.setError("Unable to create XML element " + + childElement.getPath()); return NULL; } @@ -412,74 +316,50 @@ CElement* CElement::createChild(const CXmlElement& childElement, return pChild; } -bool CElement::removeChild(CElement* pChild) +bool CElement::removeChild(CElement *pChild) { - ChildArrayIterator it; - - for (it = _childArray.begin(); it != _childArray.end(); ++it) { + auto childIt = find(begin(_childArray), end(_childArray), pChild); + if (childIt != end(_childArray)) { - CElement* pElement = *it; - - if (pElement == pChild) { - - _childArray.erase(it); - - return true; - } + _childArray.erase(childIt); + return true; } return false; } -void CElement::listChildren(string& strChildList) const +void CElement::listChildren(string &strChildList) const { - strChildList = "\n"; - // Get list of children names - size_t uiNbChildren = getNbChildren(); - size_t uiChild; - - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - - const CElement* pChild = _childArray[uiChild]; + for (CElement *pChild : _childArray) { strChildList += pChild->getName() + "\n"; } } -string CElement::listQualifiedPaths(bool bDive, uint32_t uiLevel) const +string CElement::listQualifiedPaths(bool bDive, size_t level) const { - size_t uiNbChildren = getNbChildren(); string strResult; // Dive Will cause only leaf nodes to be printed - if (!bDive || !uiNbChildren) { + if (!bDive || !getNbChildren()) { strResult = getQualifiedPath() + "\n"; } - if (bDive || !uiLevel) { + if (bDive || !level) { // Get list of children paths - size_t uiChild; + for (CElement *pChild : _childArray) { - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - - const CElement* pChild = _childArray[uiChild]; - - strResult += pChild->listQualifiedPaths(bDive, uiLevel + 1); + strResult += pChild->listQualifiedPaths(bDive, level + 1); } } return strResult; } -void CElement::listChildrenPaths(string& strChildList) const +void CElement::listChildrenPaths(string &strChildList) const { // Get list of children paths - size_t uiNbChildren = getNbChildren(); - size_t uiChild; - - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - - const CElement* pChild = _childArray[uiChild]; + for (CElement *pChild : _childArray) { strChildList += pChild->getPath() + "\n"; } @@ -490,12 +370,12 @@ size_t CElement::getNbChildren() const return _childArray.size(); } -const CElement* CElement::getParent() const +const CElement *CElement::getParent() const { return _pParent; } -CElement* CElement::getParent() +CElement *CElement::getParent() { return _pParent; } @@ -507,11 +387,9 @@ void CElement::clean() removeChildren(); } else { // Just propagate - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { + for (CElement *pChild : _childArray) { - _childArray[uiIndex]->clean(); + pChild->clean(); } } } @@ -528,16 +406,16 @@ void CElement::removeChildren() _childArray.clear(); } -const CElement* CElement::findDescendant(CPathNavigator& pathNavigator) const +const CElement *CElement::findDescendant(CPathNavigator &pathNavigator) const { - string* pStrChildName = pathNavigator.next(); + string *pStrChildName = pathNavigator.next(); if (!pStrChildName) { return this; } - const CElement* pChild = findChild(*pStrChildName); + const CElement *pChild = findChild(*pStrChildName); if (!pChild) { @@ -547,16 +425,16 @@ const CElement* CElement::findDescendant(CPathNavigator& pathNavigator) const return pChild->findDescendant(pathNavigator); } -CElement* CElement::findDescendant(CPathNavigator& pathNavigator) +CElement *CElement::findDescendant(CPathNavigator &pathNavigator) { - string* pStrChildName = pathNavigator.next(); + string *pStrChildName = pathNavigator.next(); if (!pStrChildName) { return this; } - CElement* pChild = findChild(*pStrChildName); + CElement *pChild = findChild(*pStrChildName); if (!pChild) { @@ -566,7 +444,7 @@ CElement* CElement::findDescendant(CPathNavigator& pathNavigator) return pChild->findDescendant(pathNavigator); } -bool CElement::isDescendantOf(const CElement* pCandidateAscendant) const +bool CElement::isDescendantOf(const CElement *pCandidateAscendant) const { if (!_pParent) { @@ -579,68 +457,52 @@ bool CElement::isDescendantOf(const CElement* pCandidateAscendant) const return _pParent->isDescendantOf(pCandidateAscendant); } -CElement* CElement::findChild(const string& strName) +CElement *CElement::findChild(const string &strName) { - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { + for (CElement *pChild : _childArray) { - CElement* pElement = _childArray[uiIndex]; + if (pChild->getPathName() == strName) { - if (pElement->getPathName() == strName) { - - return pElement; + return pChild; } } return NULL; } -const CElement* CElement::findChild(const string& strName) const +const CElement *CElement::findChild(const string &strName) const { - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { + for (CElement *pChild : _childArray) { - const CElement* pElement = _childArray[uiIndex]; + if (pChild->getPathName() == strName) { - if (pElement->getPathName() == strName) { - - return pElement; + return pChild; } } return NULL; } -CElement* CElement::findChildOfKind(const string& strKind) +CElement *CElement::findChildOfKind(const string &strKind) { - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { - - CElement* pElement = _childArray[uiIndex]; + for (CElement *pChild : _childArray) { - if (pElement->getKind() == strKind) { + if (pChild->getKind() == strKind) { - return pElement; + return pChild; } } return NULL; } -const CElement* CElement::findChildOfKind(const string& strKind) const +const CElement *CElement::findChildOfKind(const string &strKind) const { - uint32_t uiIndex; + for (CElement *pChild : _childArray) { - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { + if (pChild->getKind() == strKind) { - const CElement* pElement = _childArray[uiIndex];; - - if (pElement->getKind() == strKind) { - - return pElement; + return pChild; } } @@ -662,41 +524,8 @@ string CElement::getQualifiedPath() const return getPath() + " [" + getKind() + "]"; } -uint32_t CElement::getDepth() const -{ - if (_pParent) { - - return _pParent->getDepth() + 1; - } - - return 0; -} - -// Checksum for integrity checks -uint8_t CElement::computeStructureChecksum() const +string CElement::getXmlElementName() const { - // Base checksum computation on element kind - string strKind = getKind(); - - // Get element kind - const char* pcData = strKind.c_str(); - - // Cumulate - uint8_t uiChecksum = 0; - - while (*pcData) { - - uiChecksum += *pcData++; - } - - // Propagate - uint32_t uiIndex; - for (uiIndex = 0; uiIndex < _childArray.size(); uiIndex++) { - - const CElement* pChild = _childArray[uiIndex]; - - uiChecksum += pChild->computeStructureChecksum(); - } - - return uiChecksum; + // Default to element kind + return getKind(); } diff --git a/parameter/Element.h b/parameter/Element.h index d3844e6..11d41b5 100644 --- a/parameter/Element.h +++ b/parameter/Element.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,89 +29,87 @@ */ #pragma once +#include "parameter_export.h" + #include <string> #include <vector> #include <stdint.h> -#include <list> #include "XmlSink.h" #include "XmlSource.h" #include "PathNavigator.h" class CXmlElementSerializingContext; -class CErrorContext; +namespace utility +{ +class ErrorContext; +} -class CElement : public IXmlSink, public IXmlSource +class PARAMETER_EXPORT CElement : public IXmlSink, public IXmlSource { - friend class CAutoLog; public: - CElement(const std::string& strName = ""); + CElement(const std::string &strName = ""); virtual ~CElement(); - // Logging - void log_info(const char* strMessage, ...) const; - void log_warning(const char* strMessage, ...) const; - void log_table(bool bIsWarning, const std::list<std::string> lstrMessage) const; - // Description - void setDescription(const std::string& strDescription); - const std::string& getDescription() const; + void setDescription(const std::string &strDescription); + const std::string &getDescription() const; // Name / Path - const std::string& getName() const; - void setName(const std::string& strName); - bool rename(const std::string& strName, std::string& strError); + const std::string &getName() const; + void setName(const std::string &strName); + bool rename(const std::string &strName, std::string &strError); std::string getPath() const; std::string getQualifiedPath() const; // Creation / build - virtual bool init(std::string& strError); + virtual bool init(std::string &strError); virtual void clean(); // Children management - void addChild(CElement* pChild); - bool removeChild(CElement* pChild); - void listChildren(std::string& strChildList) const; - std::string listQualifiedPaths(bool bDive, uint32_t uiLevel = 0) const; - void listChildrenPaths(std::string& strChildPathList) const; + void addChild(CElement *pChild); + bool removeChild(CElement *pChild); + void listChildren(std::string &strChildList) const; + std::string listQualifiedPaths(bool bDive, size_t level = 0) const; + void listChildrenPaths(std::string &strChildPathList) const; // Hierarchy query size_t getNbChildren() const; - CElement* findChildOfKind(const std::string& strKind); - const CElement* findChildOfKind(const std::string& strKind) const; - const CElement* getParent() const; + CElement *findChildOfKind(const std::string &strKind); + const CElement *findChildOfKind(const std::string &strKind) const; + const CElement *getParent() const; /** * Get a child element (const) * * Note: this method will assert if given a wrong child index (>= number of children) * - * @param[in] uiIndex the index of the child element from 0 to number of children - 1 + * @param[in] index the index of the child element from 0 to number of children - 1 * @return the child element */ - const CElement* getChild(size_t uiIndex) const; + const CElement *getChild(size_t index) const; /** * Get a child element * * Note: this method will assert if given a wrong child index (>= number of children) * - * @param[in] uiIndex the index of the child element from 0 to number of children - 1 + * @param[in] index the index of the child element from 0 to number of children - 1 * @return the child element */ - CElement* getChild(size_t uiIndex); + CElement *getChild(size_t index); - const CElement* findChild(const std::string& strName) const; - CElement* findChild(const std::string& strName); - const CElement* findDescendant(CPathNavigator& pathNavigator) const; - CElement* findDescendant(CPathNavigator& pathNavigator); - bool isDescendantOf(const CElement* pCandidateAscendant) const; + const CElement *findChild(const std::string &strName) const; + CElement *findChild(const std::string &strName); + const CElement *findDescendant(CPathNavigator &pathNavigator) const; + CElement *findDescendant(CPathNavigator &pathNavigator); + bool isDescendantOf(const CElement *pCandidateAscendant) const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; /** * Serialize the children to XML @@ -124,17 +122,14 @@ public: * object upon which this method is called) * @param[in,out] serializingContext information about the serialization */ - virtual void childrenToXml(CXmlElement& xmlElement, - CXmlSerializingContext& serializingContext) const; + virtual void childrenToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const; // Content structure dump - void dumpContent(std::string& strContent, CErrorContext& errorContext, const uint32_t uiDepth = 0) const; + std::string dumpContent(utility::ErrorContext &errorContext, const size_t depth = 0) const; // Element properties - virtual void showProperties(std::string& strResult) const; - - // Checksum for integrity checks - uint8_t computeStructureChecksum() const; + virtual void showProperties(std::string &strResult) const; // Class kind virtual std::string getKind() const = 0; @@ -144,16 +139,7 @@ public: * * @param[in,out] xmlElement to fill with the description */ - void setXmlDescriptionAttribute(CXmlElement& xmlElement) const; - - /** - * Extract the Description field from the Xml Element during XML decomposing. - * - * @param[in] xmlElement to extract the description from. - * - * @return description represented as a string, empty if not found - */ - std::string getXmlDescriptionAttribute(const CXmlElement &xmlElement) const; + void setXmlDescriptionAttribute(CXmlElement &xmlElement) const; /** * Appends if found human readable description property. @@ -162,12 +148,17 @@ public: */ void showDescriptionProperty(std::string &strResult) const; + /** + * Returns Xml element name used for element XML importing/exporting functionalities + */ + virtual std::string getXmlElementName() const; + protected: // Content dumping - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + virtual std::string logValue(utility::ErrorContext &errorContext) const; // Hierarchy - CElement* getParent(); + CElement *getParent(); /** * Creates a child CElement from a child XML Element @@ -177,24 +168,20 @@ protected: * * @return child a pointer on the CElement object that has been added to the tree */ - CElement* createChild(const CXmlElement& childElement, - CXmlSerializingContext& elementSerializingContext); + CElement *createChild(const CXmlElement &childElement, + CXmlSerializingContext &elementSerializingContext); + + static const std::string gDescriptionPropertyName; private: - // Logging (done by root) - virtual void doLog(bool bIsWarning, const std::string& strLog) const; - virtual void nestLog() const; - virtual void unnestLog() const; // Returns Name or Kind if no Name std::string getPathName() const; // Returns true if children dynamic creation is to be dealt with virtual bool childrenAreDynamic() const; // House keeping void removeChildren(); - // For logging - uint32_t getDepth() const; // Fill XmlElement during XML composing - void setXmlNameAttribute(CXmlElement& xmlElement) const; + void setXmlNameAttribute(CXmlElement &xmlElement) const; // Name std::string _strName; @@ -203,12 +190,10 @@ private: std::string _strDescription; // Child iterators - typedef std::vector<CElement*>::iterator ChildArrayIterator; - typedef std::vector<CElement*>::reverse_iterator ChildArrayReverseIterator; + typedef std::vector<CElement *>::iterator ChildArrayIterator; + typedef std::vector<CElement *>::reverse_iterator ChildArrayReverseIterator; // Children - std::vector<CElement*> _childArray; + std::vector<CElement *> _childArray; // Parent - CElement* _pParent; - - static const std::string gDescriptionPropertyName; + CElement *_pParent{nullptr}; }; diff --git a/parameter/ElementBuilder.h b/parameter/ElementBuilder.h index 819387f..ff1ae0a 100644 --- a/parameter/ElementBuilder.h +++ b/parameter/ElementBuilder.h @@ -30,11 +30,12 @@ #pragma once #include "Element.h" +#include <NonCopyable.hpp> -class CElementBuilder +class CElementBuilder : private utility::NonCopyable { public: - virtual ~CElementBuilder() {} + virtual ~CElementBuilder() = default; - virtual CElement* createElement(const CXmlElement& xmlElement) const = 0; + virtual CElement *createElement(const CXmlElement &xmlElement) const = 0; }; diff --git a/parameter/ElementBuilderTemplate.h b/parameter/ElementBuilderTemplate.h index 0fb1212..8f7c44f 100644 --- a/parameter/ElementBuilderTemplate.h +++ b/parameter/ElementBuilderTemplate.h @@ -35,10 +35,5 @@ template <class ElementType> class TElementBuilderTemplate : public CElementBuilder { public: - - virtual CElement* createElement(const CXmlElement& xmlElement) const - { - (void)xmlElement; - return new ElementType; - } + virtual CElement *createElement(const CXmlElement & /*elem*/) const { return new ElementType; } }; diff --git a/parameter/ElementHandle.cpp b/parameter/ElementHandle.cpp new file mode 100644 index 0000000..ecf1bcf --- /dev/null +++ b/parameter/ElementHandle.cpp @@ -0,0 +1,386 @@ +/* + * 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; +} diff --git a/parameter/ElementLibrary.cpp b/parameter/ElementLibrary.cpp index 7709f0c..bde9b91 100644 --- a/parameter/ElementLibrary.cpp +++ b/parameter/ElementLibrary.cpp @@ -30,11 +30,6 @@ #include "ElementLibrary.h" #include "ElementBuilder.h" - -CElementLibrary::CElementLibrary() -{ -} - CElementLibrary::~CElementLibrary() { clean(); @@ -51,7 +46,7 @@ void CElementLibrary::clean() _elementBuilderMap.clear(); } -CElement* CElementLibrary::createElement(const CXmlElement& xmlElement) const +CElement *CElementLibrary::createElement(const CXmlElement &xmlElement) const { ElementBuilderMapConstIterator it = _elementBuilderMap.find(getBuilderType(xmlElement)); @@ -62,12 +57,13 @@ CElement* CElementLibrary::createElement(const CXmlElement& xmlElement) const return NULL; } -void CElementLibrary::addElementBuilder(const std::string& type, const CElementBuilder *pElementBuilder) +void CElementLibrary::addElementBuilder(const std::string &type, + const CElementBuilder *pElementBuilder) { _elementBuilderMap[type] = pElementBuilder; } -std::string CElementLibrary::getBuilderType(const CXmlElement& xmlElement) const +std::string CElementLibrary::getBuilderType(const CXmlElement &xmlElement) const { // Defaulting to xml element name return xmlElement.getType(); diff --git a/parameter/ElementLibrary.h b/parameter/ElementLibrary.h index e50be95..943fc8a 100644 --- a/parameter/ElementLibrary.h +++ b/parameter/ElementLibrary.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,6 +29,8 @@ */ #pragma once +#include "parameter_export.h" + #include <map> #include <string> @@ -36,31 +38,30 @@ class CElementBuilder; -class CElementLibrary +class PARAMETER_EXPORT CElementLibrary { - typedef std::map<std::string, const CElementBuilder*> ElementBuilderMap; + typedef std::map<std::string, const CElementBuilder *> ElementBuilderMap; typedef ElementBuilderMap::iterator ElementBuilderMapIterator; typedef ElementBuilderMap::const_iterator ElementBuilderMapConstIterator; public: - CElementLibrary(); virtual ~CElementLibrary(); /** Add a xml tag and it's corresponding builder in the library. * - * @param[in] xmlTag is the tag of an xml element that can be given to the builder to - * create a new element. + * @param[in] type is the tag of an xml element that can be given to the builder to + * create a new element. * @param[in] pElementBuilder is the tag associated element builder. */ - void addElementBuilder(const std::string& type, const CElementBuilder *pElementBuilder); + void addElementBuilder(const std::string &type, const CElementBuilder *pElementBuilder); void clean(); // Instantiation - CElement* createElement(const CXmlElement& xmlElement) const; + CElement *createElement(const CXmlElement &xmlElement) const; private: // Builder type - virtual std::string getBuilderType(const CXmlElement& xmlElement) const; + virtual std::string getBuilderType(const CXmlElement &xmlElement) const; // Builders ElementBuilderMap _elementBuilderMap; diff --git a/parameter/ElementLibrarySet.cpp b/parameter/ElementLibrarySet.cpp index e420d8c..1eaa2c5 100644 --- a/parameter/ElementLibrarySet.cpp +++ b/parameter/ElementLibrarySet.cpp @@ -30,28 +30,23 @@ #include "ElementLibrarySet.h" #include <assert.h> -CElementLibrarySet::CElementLibrarySet() -{ -} - CElementLibrarySet::~CElementLibrarySet() { - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _elementLibraryArray.size(); uiIndex++) { + // FIXME: use an array of unique_ptr + for (auto *elementLibrary : _elementLibraryArray) { - delete _elementLibraryArray[uiIndex]; + delete elementLibrary; } } -void CElementLibrarySet::addElementLibrary(CElementLibrary* pElementLibrary) +void CElementLibrarySet::addElementLibrary(CElementLibrary *pElementLibrary) { _elementLibraryArray.push_back(pElementLibrary); } -CElementLibrary* CElementLibrarySet::getElementLibrary(uint32_t uiIndex) const +CElementLibrary *CElementLibrarySet::getElementLibrary(size_t index) const { - assert(uiIndex <= _elementLibraryArray.size()); + assert(index <= _elementLibraryArray.size()); - return _elementLibraryArray[uiIndex]; + return _elementLibraryArray[index]; } diff --git a/parameter/ElementLibrarySet.h b/parameter/ElementLibrarySet.h index cdcfdfe..d92ace9 100644 --- a/parameter/ElementLibrarySet.h +++ b/parameter/ElementLibrarySet.h @@ -34,13 +34,11 @@ class CElementLibrarySet { public: - CElementLibrarySet(); ~CElementLibrarySet(); - void addElementLibrary(CElementLibrary* pElementLibrary); - CElementLibrary* getElementLibrary(uint32_t uiIndex) const; + void addElementLibrary(CElementLibrary *pElementLibrary); + CElementLibrary *getElementLibrary(size_t index) const; private: - typedef std::vector<CElementLibrary*>::iterator CElementLibraryArrayIterator; - std::vector<CElementLibrary*> _elementLibraryArray; + std::vector<CElementLibrary *> _elementLibraryArray; }; diff --git a/parameter/ElementLocator.cpp b/parameter/ElementLocator.cpp index 4c2fa99..b7721b3 100644 --- a/parameter/ElementLocator.cpp +++ b/parameter/ElementLocator.cpp @@ -32,12 +32,13 @@ using std::string; -CElementLocator::CElementLocator(CElement* pSubRootElement, bool bStrict) : _pSubRootElement(pSubRootElement), _bStrict(bStrict) +CElementLocator::CElementLocator(CElement *pSubRootElement, bool bStrict) + : _pSubRootElement(pSubRootElement), _bStrict(bStrict) { } // Locate element -bool CElementLocator::locate(const string& strPath, CElement** ppElement, string& strError) +bool CElementLocator::locate(const string &strPath, CElement **ppElement, string &strError) { CPathNavigator pathNavigator(strPath); @@ -49,7 +50,7 @@ bool CElementLocator::locate(const string& strPath, CElement** ppElement, string } // Sub root element? - string* pStrChildName = pathNavigator.next(); + string *pStrChildName = pathNavigator.next(); if (!pStrChildName) { @@ -82,4 +83,3 @@ bool CElementLocator::locate(const string& strPath, CElement** ppElement, string return true; } - diff --git a/parameter/ElementLocator.h b/parameter/ElementLocator.h index c35eb5c..eca6fa9 100644 --- a/parameter/ElementLocator.h +++ b/parameter/ElementLocator.h @@ -36,16 +36,15 @@ class CElementLocator { public: - CElementLocator(CElement* pSubRootElement, bool bStrict = true); + CElementLocator(CElement *pSubRootElement, bool bStrict = true); // Locate element - bool locate(const std::string& strPath, CElement** ppElement, std::string& strError); + bool locate(const std::string &strPath, CElement **ppElement, std::string &strError); private: // Subroot element - CElement* _pSubRootElement; + CElement *_pSubRootElement; // Strict means empty path will cause path not found error to be returned bool _bStrict; }; - diff --git a/parameter/EnumParameterType.cpp b/parameter/EnumParameterType.cpp index 147ee95..6eea694 100644 --- a/parameter/EnumParameterType.cpp +++ b/parameter/EnumParameterType.cpp @@ -28,21 +28,15 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "EnumParameterType.h" -#include <stdlib.h> -#include <sstream> -#include <iomanip> -#include <ctype.h> -#include <assert.h> -#include "ParameterAccessContext.h" #include "EnumValuePair.h" -#include "Utility.h" -#include <errno.h> +#include "ParameterAccessContext.h" +#include "convert.hpp" #define base CParameterType using std::string; -CEnumParameterType::CEnumParameterType(const string& strName) : base(strName) +CEnumParameterType::CEnumParameterType(const string &strName) : base(strName) { } @@ -57,7 +51,7 @@ bool CEnumParameterType::childrenAreDynamic() const } // Element properties -void CEnumParameterType::showProperties(string& strResult) const +void CEnumParameterType::showProperties(string &strResult) const { base::showProperties(strResult); @@ -69,7 +63,7 @@ void CEnumParameterType::showProperties(string& strResult) const for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CEnumValuePair* pValuePair = static_cast<const CEnumValuePair*>(getChild(uiChild)); + const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild)); strResult += "\tLiteral: \""; strResult += pValuePair->getName(); @@ -79,182 +73,108 @@ void CEnumParameterType::showProperties(string& strResult) const } } -bool CEnumParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CEnumParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Size in bits - uint32_t uiSizeInBits = xmlElement.getAttributeInteger("Size"); + size_t sizeInBits = 0; + if (not xmlElement.getAttribute("Size", sizeInBits)) { + return false; + } // Size - setSize(uiSizeInBits / 8); + setSize(sizeInBits / 8); // Base return base::fromXml(xmlElement, serializingContext); } // Conversion (tuning) -bool CEnumParameterType::toBlackboard(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CEnumParameterType::toBlackboard(const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { - int64_t iData; - - if (isNumber(strValue)) { - - /// Numerical value provided - - // Hexa - bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); - - errno = 0; - char *pcStrEnd; - - // Get value - iData = strtoll(strValue.c_str(), &pcStrEnd, 0); - - // Conversion error when the input string does not contain any digit or the number is out of range (int32_t type) - bool bConversionSucceeded = !errno && (strValue.c_str() != pcStrEnd); - - // Check validity against type - if (!checkValueAgainstRange(strValue, iData, parameterAccessContext, bValueProvidedAsHexa, bConversionSucceeded)) { - - return false; - } - - if (bValueProvidedAsHexa) { - - // Sign extend - signExtend(iData); - } + int32_t iParsedUserValue = 0; - // Check validity against lexical space - string strError; - if (!isValid(iData, parameterAccessContext)) { + // Try to read the user-provided string as an integer + if (not convertTo(strValue, iParsedUserValue)) { + // If it fails to parse as an integer, first try to convert it from + // lexical to numerical space. + int32_t iNumerical; + if (not getNumerical(strValue, iNumerical)) { - parameterAccessContext.setError(strError); - - return false; - } - } else { - /// Literal value provided - - // Check validity against lexical space - int iNumerical; - if (!getNumerical(strValue, iNumerical)) { - - parameterAccessContext.setError("Provided value not part of lexical space"); - - return false; - } - iData = iNumerical; - - // Check validity against type - if (!checkValueAgainstRange(strValue, iData, parameterAccessContext, false, isEncodable((uint64_t)iData, true))) { + parameterAccessContext.setError("Provided value '" + strValue + + "' is not part of the lexical space" + " or not within the numerical range."); return false; } + iParsedUserValue = iNumerical; } - // Return data - uiValue = (uint32_t)iData; - - return true; + // Once it has been converted to a number (either through parsing or + // through lexical->numerical conversion), call the numerical overload of + // toBlackboard. + return toBlackboard(iParsedUserValue, uiValue, parameterAccessContext); } -// Range checking -bool CEnumParameterType::checkValueAgainstRange(const string& strValue, int64_t value, CParameterAccessContext& parameterAccessContext, bool bHexaValue, bool bConversionSucceeded) const +int32_t CEnumParameterType::getMin() const { // Enums are always signed, it means we have one less util bit - int64_t maxValue = getMaxValue<uint64_t>(); - int64_t minValue = -maxValue - 1; - - if (!bConversionSucceeded || value < minValue || value > maxValue) { - - std::ostringstream strStream; - - strStream << "Value " << strValue << " standing out of admitted range ["; - - if (bHexaValue) { - - // Format Min - strStream << "0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << makeEncodable(minValue); - // Format Max - strStream << ", 0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << makeEncodable(maxValue); - - } else { - - strStream << minValue << ", " << maxValue; - } - - strStream << "] for " << getKind(); - - parameterAccessContext.setError(strStream.str()); - - return false; - } - return true; + return -getMax() - 1; } -bool CEnumParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +int32_t CEnumParameterType::getMax() const { - // Take care of format - if (parameterAccessContext.valueSpaceIsRaw()) { - - // Format - std::ostringstream strStream; - - // Numerical format requested - if (parameterAccessContext.outputRawFormatIsHex()) { - - // Hexa display with unecessary bits cleared out - strStream << "0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << makeEncodable(uiValue); - - strValue = strStream.str(); - } else { - - // Integer display - int32_t iValue = uiValue; - - // Sign extend - signExtend(iValue); + return getMaxValue<int32_t>(); +} - strStream << iValue; +bool CEnumParameterType::fromBlackboard(string &userValue, const uint32_t &value, + CParameterAccessContext & /*ctx*/) const +{ + // Convert the raw value from the blackboard + int32_t signedValue = static_cast<int32_t>(value); + signExtend(signedValue); - strValue = strStream.str(); - } - } else { + // Convert from numerical space to literal space + return getLiteral(signedValue, userValue); +} - // Integer display - int32_t iValue = uiValue; +// Value access +bool CEnumParameterType::toBlackboard(int32_t userValue, uint32_t &value, + CParameterAccessContext ¶meterAccessContext) const +{ + if (!checkValueAgainstSpace(userValue)) { - // Sign extend - signExtend(iValue); + parameterAccessContext.setError(std::to_string(userValue) + + " is not part of numerical space."); - // Literal display requested (should succeed) - getLiteral(iValue, strValue); + return false; } - return true; -} -// Value access -bool CEnumParameterType::toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const -{ - if (!isValid(iUserValue, parameterAccessContext)) { + if (userValue < getMin() or userValue > getMax()) { + // FIXME: values provided as hexa (either on command line or in a config + // file will appear in decimal base instead of hexa base... + parameterAccessContext.setError( + "Value " + std::to_string(userValue) + " standing out of admitted range [" + + std::to_string(getMin()) + ", " + std::to_string(getMax()) + "] for " + getKind()); return false; } - uiValue = iUserValue; + + value = static_cast<uint32_t>(userValue); return true; } -bool CEnumParameterType::fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CEnumParameterType::fromBlackboard(int32_t &userValue, uint32_t value, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - - int32_t iValue = uiValue; + int32_t signedValue = static_cast<int32_t>(value); // Sign extend - signExtend(iValue); + signExtend(signedValue); - iUserValue = iValue; + userValue = signedValue; return true; } @@ -268,26 +188,18 @@ uint32_t CEnumParameterType::getDefaultValue() const } // Return first available numerical - return static_cast<const CEnumValuePair*>(getChild(0))->getNumerical(); -} - -// Check string is a number -bool CEnumParameterType::isNumber(const string& strValue) -{ - char cFirst = strValue[0]; - - return isdigit(cFirst) || cFirst == '+' || cFirst == '-'; + return static_cast<const CEnumValuePair *>(getChild(0))->getNumerical(); } // Literal - numerical conversions -bool CEnumParameterType::getLiteral(int32_t iNumerical, string& strLiteral) const +bool CEnumParameterType::getLiteral(int32_t iNumerical, string &strLiteral) const { size_t uiChild; size_t uiNbChildren = getNbChildren(); for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CEnumValuePair* pValuePair = static_cast<const CEnumValuePair*>(getChild(uiChild)); + const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild)); if (pValuePair->getNumerical() == iNumerical) { @@ -300,14 +212,14 @@ bool CEnumParameterType::getLiteral(int32_t iNumerical, string& strLiteral) cons return false; } -bool CEnumParameterType::getNumerical(const string& strLiteral, int& iNumerical) const +bool CEnumParameterType::getNumerical(const string &strLiteral, int32_t &iNumerical) const { size_t uiChild; size_t uiNbChildren = getNbChildren(); for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CEnumValuePair* pValuePair = static_cast<const CEnumValuePair*>(getChild(uiChild)); + const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild)); if (pValuePair->getName() == strLiteral) { @@ -321,7 +233,7 @@ bool CEnumParameterType::getNumerical(const string& strLiteral, int& iNumerical) } // Numerical validity of the enum value -bool CEnumParameterType::isValid(int iNumerical, CParameterAccessContext& parameterAccessContext) const +bool CEnumParameterType::checkValueAgainstSpace(int32_t iNumerical) const { // Check that the value is part of the allowed values for this kind of enum size_t uiChild; @@ -329,7 +241,7 @@ bool CEnumParameterType::isValid(int iNumerical, CParameterAccessContext& parame for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CEnumValuePair* pValuePair = static_cast<const CEnumValuePair*>(getChild(uiChild)); + const CEnumValuePair *pValuePair = static_cast<const CEnumValuePair *>(getChild(uiChild)); if (pValuePair->getNumerical() == iNumerical) { @@ -337,15 +249,15 @@ bool CEnumParameterType::isValid(int iNumerical, CParameterAccessContext& parame } } - parameterAccessContext.setError("Provided value not part of numerical space"); - return false; } + // From IXmlSource -void CEnumParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CEnumParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Size - xmlElement.setAttributeString("Size", CUtility::toString(getSize() * 8)); + xmlElement.setAttribute("Size", getSize() * 8); base::toXml(xmlElement, serializingContext); } diff --git a/parameter/EnumParameterType.h b/parameter/EnumParameterType.h index 681f9b9..b8f67f4 100644 --- a/parameter/EnumParameterType.h +++ b/parameter/EnumParameterType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,49 +31,56 @@ #include "ParameterType.h" -#include <list> #include <string> class CEnumParameterType : public CParameterType { public: - CEnumParameterType(const std::string& strName); + CEnumParameterType(const std::string &strName); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; /// Conversion // String - virtual bool toBlackboard(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(std::string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Integer - virtual bool toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(int32_t iUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(int32_t &iUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Default value handling (simulation only) virtual uint32_t getDefaultValue() const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // CElement virtual std::string getKind() const; + private: + // Specialized version of toBlackboard in case the access context is in raw + // value space + bool toBlackboardFromRaw(const std::string &strUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + // Returns true if children dynamic creation is to be dealt with virtual bool childrenAreDynamic() const; - // Check std::string is a number - static bool isNumber(const std::string& strValue); // Literal - numerical conversions - bool getLiteral(int32_t iNumerical, std::string& strLiteral) const; - bool getNumerical(const std::string& strLiteral, int& iNumerical) const; + bool getLiteral(int32_t iNumerical, std::string &strLiteral) const; + bool getNumerical(const std::string &strLiteral, int &iNumerical) const; // Numerical validity - bool isValid(int iNumerical, CParameterAccessContext& parameterAccessContext) const; + bool checkValueAgainstSpace(int32_t iNumerical) const; - // Range validity - bool checkValueAgainstRange(const std::string& strValue, int64_t value, CParameterAccessContext& parameterAccessContext, bool bHexaValue, bool bConversionSucceeded) const; + int32_t getMin() const; + int32_t getMax() const; }; diff --git a/parameter/EnumValuePair.cpp b/parameter/EnumValuePair.cpp index 35f4cd2..b5e967b 100644 --- a/parameter/EnumValuePair.cpp +++ b/parameter/EnumValuePair.cpp @@ -28,16 +28,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "EnumValuePair.h" -#include "Utility.h" #define base CElement using std::string; -CEnumValuePair::CEnumValuePair() : _iNumerical(0) -{ -} - // CElement string CEnumValuePair::getKind() const { @@ -52,38 +47,43 @@ int32_t CEnumValuePair::getNumerical() const string CEnumValuePair::getNumericalAsString() const { - return CUtility::toString(_iNumerical); + return std::to_string(_iNumerical); } // From IXmlSink -bool CEnumValuePair::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CEnumValuePair::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Literal - setName(xmlElement.getAttributeString("Literal")); + std::string name; + xmlElement.getAttribute("Literal", name); + setName(name); // Numerical - _iNumerical = xmlElement.getAttributeSignedInteger("Numerical"); + xmlElement.getAttribute("Numerical", _iNumerical); // Base return base::fromXml(xmlElement, serializingContext); } // Content dumping -void CEnumValuePair::logValue(string& strValue, CErrorContext& errorContext) const +string CEnumValuePair::logValue(utility::ErrorContext & /*ctx*/) const { - (void)errorContext; // Convert value - strValue = getNumericalAsString(); + return getNumericalAsString(); } // From IXmlSource -void CEnumValuePair::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CEnumValuePair::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Literal - xmlElement.setAttributeString("Literal", this->getName()); + xmlElement.setAttribute("Literal", this->getName()); // Numerical - xmlElement.setAttributeString("Numerical", getNumericalAsString()); + xmlElement.setAttribute("Numerical", getNumericalAsString()); - base::toXml(xmlElement, serializingContext); + // Ask for children processing only so as to avoid setting the Name attribute + // which does not exist for this element + base::childrenToXml(xmlElement, serializingContext); } diff --git a/parameter/EnumValuePair.h b/parameter/EnumValuePair.h index b29fea0..46d5578 100644 --- a/parameter/EnumValuePair.h +++ b/parameter/EnumValuePair.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -34,25 +34,24 @@ class CEnumValuePair : public CElement { public: - CEnumValuePair(); - // Numerical int32_t getNumerical() const; std::string getNumericalAsString() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // CElement virtual std::string getKind() const; + protected: // Content dumping - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + std::string logValue(utility::ErrorContext &errorContext) const override; + private: // Numerical - int32_t _iNumerical; + int32_t _iNumerical{0}; }; - diff --git a/parameter/FileIncluderElementBuilder.h b/parameter/FileIncluderElementBuilder.h index bccb227..d66065c 100644 --- a/parameter/FileIncluderElementBuilder.h +++ b/parameter/FileIncluderElementBuilder.h @@ -41,17 +41,19 @@ class CFileIncluderElementBuilder : public CElementBuilder { public: - CFileIncluderElementBuilder(bool bValidateWithSchemas) : - CElementBuilder(), - _bValidateWithSchemas(bValidateWithSchemas) - {} + CFileIncluderElementBuilder(bool bValidateWithSchemas, const std::string &schemaBaseUri) + : CElementBuilder(), _bValidateWithSchemas(bValidateWithSchemas), + _schemaBaseUri(schemaBaseUri) + { + } virtual CElement *createElement(const CXmlElement &xmlElement) const { - return new CXmlFileIncluderElement(xmlElement.getNameAttribute(), - xmlElement.getType(), _bValidateWithSchemas); + return new CXmlFileIncluderElement(xmlElement.getNameAttribute(), xmlElement.getType(), + _bValidateWithSchemas, _schemaBaseUri); } private: bool _bValidateWithSchemas; + const std::string _schemaBaseUri; }; diff --git a/parameter/FixedPointParameterType.cpp b/parameter/FixedPointParameterType.cpp index 5189a07..830ac64 100644 --- a/parameter/FixedPointParameterType.cpp +++ b/parameter/FixedPointParameterType.cpp @@ -44,7 +44,7 @@ using std::string; -CFixedPointParameterType::CFixedPointParameterType(const string& strName) : base(strName), _uiIntegral(0), _uiFractional(0) +CFixedPointParameterType::CFixedPointParameterType(const string &strName) : base(strName) { } @@ -54,73 +54,78 @@ string CFixedPointParameterType::getKind() const } // Element properties -void CFixedPointParameterType::showProperties(string& strResult) const +void CFixedPointParameterType::showProperties(string &strResult) const { base::showProperties(strResult); // Notation strResult += "Notation: Q"; - strResult += CUtility::toString(_uiIntegral); + strResult += std::to_string(_uiIntegral); strResult += "."; - strResult += CUtility::toString(_uiFractional); + strResult += std::to_string(_uiFractional); strResult += "\n"; } // XML Serialization value space handling // Value space handling for configuration import -void CFixedPointParameterType::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const +void CFixedPointParameterType::handleValueSpaceAttribute( + CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const { // Direction? if (!configurationAccessContext.serializeOut()) { - // Get Value space from XML - if (xmlConfigurableElementSettingsElement.hasAttribute("ValueSpace")) { - - configurationAccessContext.setValueSpaceRaw(xmlConfigurableElementSettingsElement.getAttributeBoolean("ValueSpace", "Raw")); - } else { - - configurationAccessContext.setValueSpaceRaw(false); - } + string strValueSpace; + xmlConfigurableElementSettingsElement.getAttribute("ValueSpace", strValueSpace); + configurationAccessContext.setValueSpaceRaw(strValueSpace == "Raw"); } else { // Provide value space only if not the default one if (configurationAccessContext.valueSpaceIsRaw()) { - xmlConfigurableElementSettingsElement.setAttributeString("ValueSpace", "Raw"); + xmlConfigurableElementSettingsElement.setAttribute("ValueSpace", "Raw"); } } } -bool CFixedPointParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CFixedPointParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Size - uint32_t uiSizeInBits = xmlElement.getAttributeInteger("Size"); + size_t sizeInBits = 0; + xmlElement.getAttribute("Size", sizeInBits); // Q notation - _uiIntegral = xmlElement.getAttributeInteger("Integral"); - _uiFractional = xmlElement.getAttributeInteger("Fractional"); + xmlElement.getAttribute("Integral", _uiIntegral); + xmlElement.getAttribute("Fractional", _uiFractional); // Size vs. Q notation integrity check - if (uiSizeInBits < getUtilSizeInBits()) { + if (sizeInBits < getUtilSizeInBits()) { - serializingContext.setError("Inconsistent Size vs. Q notation for " + getKind() + " " + xmlElement.getPath() + ": Summing (Integral + _uiFractional + 1) should not exceed given Size (" + xmlElement.getAttributeString("Size") + ")"); + std::string size; + xmlElement.getAttribute("Size", size); + serializingContext.setError( + "Inconsistent Size vs. Q notation for " + getKind() + " " + xmlElement.getPath() + + ": Summing (Integral + _uiFractional + 1) should not exceed given Size (" + size + ")"); return false; } // Set the size - setSize(uiSizeInBits / 8); + setSize(sizeInBits / 8); return base::fromXml(xmlElement, serializingContext); } -bool CFixedPointParameterType::toBlackboard(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::toBlackboard(const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { - bool bValueProvidedAsHexa = isHexadecimal(strValue); + bool bValueProvidedAsHexa = utility::isHexadecimal(strValue); // Check data integrity if (bValueProvidedAsHexa && !parameterAccessContext.valueSpaceIsRaw()) { - parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + " when selected value space is real:"); + parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + + " when selected value space is real:"); return false; } @@ -130,18 +135,18 @@ bool CFixedPointParameterType::toBlackboard(const string& strValue, uint32_t& ui if (bValueProvidedAsHexa) { return convertFromHexadecimal(strValue, uiValue, parameterAccessContext); - } return convertFromDecimal(strValue, uiValue, parameterAccessContext); } return convertFromQnm(strValue, uiValue, parameterAccessContext); } -void CFixedPointParameterType::setOutOfRangeError(const string& strValue, CParameterAccessContext& parameterAccessContext) const +void CFixedPointParameterType::setOutOfRangeError( + const string &strValue, CParameterAccessContext ¶meterAccessContext) const { - std::ostringstream strStream; + std::ostringstream stream; - strStream << "Value " << strValue << " standing out of admitted "; + stream << "Value " << strValue << " standing out of admitted "; if (!parameterAccessContext.valueSpaceIsRaw()) { @@ -150,79 +155,81 @@ void CFixedPointParameterType::setOutOfRangeError(const string& strValue, CParam double dMax = 0; getRange(dMin, dMax); - strStream << std::fixed << std::setprecision(_uiFractional) - << "real range [" << dMin << ", " << dMax << "]"; + stream << std::fixed << std::setprecision(_uiFractional) << "real range [" << dMin << ", " + << dMax << "]"; } else { // Min/Max computation int32_t iMax = getMaxValue<uint32_t>(); int32_t iMin = -iMax - 1; - strStream << "raw range ["; + stream << "raw range ["; - if (isHexadecimal(strValue)) { + if (utility::isHexadecimal(strValue)) { + + stream << std::hex << std::uppercase << std::setw(static_cast<int>(getSize()) * 2) + << std::setfill('0'); // Format Min - strStream << "0x" << std::hex << std::uppercase << - std::setw(getSize() * 2) << std::setfill('0') << makeEncodable(iMin); + stream << "0x" << makeEncodable(iMin); // Format Max - strStream << ", 0x" << std::hex << std::uppercase << - std::setw(getSize() * 2) << std::setfill('0') << makeEncodable(iMax); + stream << ", 0x" << makeEncodable(iMax); } else { - strStream << iMin << ", " << iMax; + stream << iMin << ", " << iMax; } - strStream << "]"; + stream << "]"; } - strStream << " for " << getKind(); + stream << " for " << getKind(); - parameterAccessContext.setError(strStream.str()); + parameterAccessContext.setError(stream.str()); } -bool CFixedPointParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::fromBlackboard(string &strValue, const uint32_t &value, + CParameterAccessContext ¶meterAccessContext) const { - int32_t iData = uiValue; - // Check encodability - assert(isEncodable((uint32_t)iData, false)); + assert(isEncodable(value, false)); // Format - std::ostringstream strStream; + std::ostringstream stream; // Raw formatting? if (parameterAccessContext.valueSpaceIsRaw()) { - // Hexa formatting? if (parameterAccessContext.outputRawFormatIsHex()) { + uint32_t data = static_cast<uint32_t>(value); - strStream << "0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << (uint32_t)iData; + stream << "0x" << std::hex << std::uppercase + << std::setw(static_cast<int>(getSize() * 2)) << std::setfill('0') << data; } else { + int32_t data = value; // Sign extend - signExtend(iData); + signExtend(data); - strStream << iData; + stream << data; } } else { + int32_t data = value; // Sign extend - signExtend(iData); + signExtend(data); // Conversion - double dData = binaryQnmToDouble(iData); - - strStream << std::fixed << std::setprecision(_uiFractional) << dData; + stream << std::fixed << std::setprecision(_uiFractional) << binaryQnmToDouble(data); } - strValue = strStream.str(); + strValue = stream.str(); return true; } // Value access -bool CFixedPointParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::toBlackboard(double dUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { // Check that the value is within the allowed range for this type if (!checkValueAgainstRange(dUserValue)) { @@ -244,10 +251,9 @@ bool CFixedPointParameterType::toBlackboard(double dUserValue, uint32_t& uiValue return true; } -bool CFixedPointParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - int32_t iData = uiValue; // Check unsigned value is encodable @@ -262,59 +268,52 @@ bool CFixedPointParameterType::fromBlackboard(double& dUserValue, uint32_t uiVal } // Util size -uint32_t CFixedPointParameterType::getUtilSizeInBits() const +size_t CFixedPointParameterType::getUtilSizeInBits() const { return _uiIntegral + _uiFractional + 1; } // Compute the range for the type (minimum and maximum values) -void CFixedPointParameterType::getRange(double& dMin, double& dMax) const -{ - dMax = (double)((1UL << (_uiIntegral + _uiFractional)) - 1) / (1UL << _uiFractional); - dMin = -(double)(1UL << (_uiIntegral + _uiFractional)) / (1UL << _uiFractional); -} - -bool CFixedPointParameterType::isHexadecimal(const string& strValue) const +void CFixedPointParameterType::getRange(double &dMin, double &dMax) const { - return !strValue.compare(0, 2, "0x"); + dMax = ((1U << (_uiIntegral + _uiFractional)) - 1) / double(1U << _uiFractional); + dMin = -((1U << (_uiIntegral + _uiFractional)) / double(1U << _uiFractional)); } -bool CFixedPointParameterType::convertFromHexadecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::convertFromHexadecimal( + const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { // For hexadecimal representation, we need full 32 bit range conversion. - uint32_t uiData; - if (!convertTo(strValue, uiData) || !isEncodable(uiData, false)) { + if (!convertTo(strValue, uiValue) || !isEncodable(uiValue, false)) { setOutOfRangeError(strValue, parameterAccessContext); return false; } - signExtend((int32_t&)uiData); + signExtend(reinterpret_cast<int32_t &>(uiValue)); // check that the data is encodable and can been safely written to the blackboard - assert(isEncodable(uiData, true)); - uiValue = uiData; + assert(isEncodable(uiValue, true)); return true; } -bool CFixedPointParameterType::convertFromDecimal(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::convertFromDecimal( + const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { - int32_t iData; - - if (!convertTo(strValue, iData) || !isEncodable((uint32_t)iData, true)) { + if (!convertTo(strValue, reinterpret_cast<int32_t &>(uiValue)) || !isEncodable(uiValue, true)) { setOutOfRangeError(strValue, parameterAccessContext); return false; } - uiValue = static_cast<uint32_t>(iData); - return true; } -bool CFixedPointParameterType::convertFromQnm(const string& strValue, uint32_t& uiValue, - CParameterAccessContext& parameterAccessContext) const +bool CFixedPointParameterType::convertFromQnm(const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { - double dData; + double dData = 0; if (!convertTo(strValue, dData) || !checkValueAgainstRange(dData)) { @@ -343,7 +342,7 @@ bool CFixedPointParameterType::checkValueAgainstRange(double dValue) const int32_t CFixedPointParameterType::doubleToBinaryQnm(double dValue) const { // For Qn.m number, multiply by 2^n and round to the nearest integer - int32_t iData = static_cast<int32_t>(round(dValue * (1UL << _uiFractional))); + int32_t iData = static_cast<int32_t>(round(dValue * double(1UL << _uiFractional))); // Left justify // For a Qn.m number, shift 32 - (n + m + 1) bits to the left (the rest of // the bits aren't used) @@ -352,25 +351,25 @@ int32_t CFixedPointParameterType::doubleToBinaryQnm(double dValue) const return iData; } - double CFixedPointParameterType::binaryQnmToDouble(int32_t iValue) const { // Unjustify iValue >>= getSize() * 8 - getUtilSizeInBits(); - return static_cast<double>(iValue) / (1UL << _uiFractional); + return static_cast<double>(iValue) / double(1UL << _uiFractional); } // From IXmlSource -void CFixedPointParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CFixedPointParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Size - xmlElement.setAttributeString("Size", CUtility::toString(getSize() * 8)); + xmlElement.setAttribute("Size", getSize() * 8); // Integral - xmlElement.setAttributeString("Integral", CUtility::toString(_uiIntegral)); + xmlElement.setAttribute("Integral", _uiIntegral); // Fractional - xmlElement.setAttributeString("Fractional", CUtility::toString(_uiFractional)); + xmlElement.setAttribute("Fractional", _uiFractional); base::toXml(xmlElement, serializingContext); } diff --git a/parameter/FixedPointParameterType.h b/parameter/FixedPointParameterType.h index c2f5f47..d4e96b6 100644 --- a/parameter/FixedPointParameterType.h +++ b/parameter/FixedPointParameterType.h @@ -36,46 +36,43 @@ class CFixedPointParameterType : public CParameterType { public: - CFixedPointParameterType(const std::string& strName); + CFixedPointParameterType(const std::string &strName); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // XML Serialization value space handling // Value space handling for configuration import - virtual void handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const; + virtual void handleValueSpaceAttribute( + CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const; /// Conversion // String - virtual bool toBlackboard(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(std::string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Double - virtual bool toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(double dUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // CElement virtual std::string getKind() const; + private: // Util size - uint32_t getUtilSizeInBits() const; + size_t getUtilSizeInBits() const; // Range computation - void getRange(double& dMin, double& dMax) const; - - /** - * Checks if a string has the written representation of an hexadecimal number (Which is - * the prefix "Ox" in C++). - * - * @param[in] strValue Parameter read from the XML file representated as a string. - * - * @return true if the string is written as hexa, false otherwise. - */ - bool isHexadecimal(const std::string& strValue) const; + void getRange(double &dMin, double &dMax) const; /** * Convert a decimal raw represented string into an unsigned long integer. @@ -85,11 +82,12 @@ private: * @param[in] strValue Parameter read from the XML file representated as a string in decimal * raw format * @param[out] uiValue Parameter representated as a long unsigned integer. - * @param[in:out] parameterAccessContext Parameter access context. + * @param[in,out] parameterAccessContext Parameter access context. * * @return true if the string was successfully converted, false otherwise. */ - bool convertFromDecimal(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + bool convertFromDecimal(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; /** * Convert an hexadecimal raw represented string into an unsigned long integer. @@ -99,11 +97,12 @@ private: * @param[in] strValue Parameter read from the XML file representated as a string in hexadecimal * raw format * @param[out] uiValue Parameter representated as a long unsigned integer. - * @param[in:out] parameterAccessContext Parameter access context. + * @param[in,out] parameterAccessContext Parameter access context. * * @return true if the string was successfully converted, false otherwise. */ - bool convertFromHexadecimal(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + bool convertFromHexadecimal(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; /** * Convert a Qn.m represented string into an unsigned long integer. @@ -113,11 +112,12 @@ private: * @param[in] strValue Parameter read from the XML file representated as a string in Qn.m * representation. * @param[out] uiValue Parameter representated as a long unsigned integer. - * @param[in:out] parameterAccessContext Parameter access context. + * @param[in,out] parameterAccessContext Parameter access context. * * @return true if the string was successfully converted, false otherwise. */ - bool convertFromQnm(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + bool convertFromQnm(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; /** * Set the out of range error. @@ -125,9 +125,10 @@ private: * illegal value provided and gives the range allowed for the parameter. * * @param[in] strValue Parameter read from the XML file representated as a string - * @param[in:out] parameterAccessContext Parameter Access Context + * @param[in,out] parameterAccessContext Parameter Access Context */ - void setOutOfRangeError(const std::string& strValue, CParameterAccessContext& parameterAccessContext) const; + void setOutOfRangeError(const std::string &strValue, + CParameterAccessContext ¶meterAccessContext) const; // Check if data is encodable bool checkValueAgainstRange(double dValue) const; @@ -152,7 +153,7 @@ private: double binaryQnmToDouble(int32_t iValue) const; // Integral part in Q notation - uint32_t _uiIntegral; + uint32_t _uiIntegral{0}; // Fractional part in Q notation - uint32_t _uiFractional; + uint32_t _uiFractional{0}; }; diff --git a/parameter/FloatingPointParameterType.cpp b/parameter/FloatingPointParameterType.cpp new file mode 100644 index 0000000..44de9e2 --- /dev/null +++ b/parameter/FloatingPointParameterType.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2014-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, Value, 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 "FloatingPointParameterType.h" +#include <sstream> +#include <iomanip> +#include "ParameterAccessContext.h" +#include "ConfigurationAccessContext.h" +#include <limits> +#include <climits> +#include "convert.hpp" +#include "Utility.h" +#include "BinaryCopy.hpp" + +using std::string; + +CFloatingPointParameterType::CFloatingPointParameterType(const string &strName) : base(strName) +{ +} + +string CFloatingPointParameterType::getKind() const +{ + return "FloatingPointParameter"; +} + +// Element properties +void CFloatingPointParameterType::showProperties(string &strResult) const +{ + base::showProperties(strResult); + + strResult += "Min:" + std::to_string(_fMin) + "\n" + "Max:" + std::to_string(_fMax) + "\n"; +} + +void CFloatingPointParameterType::handleValueSpaceAttribute( + CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const +{ + if (!configurationAccessContext.serializeOut()) { + + string strValueSpace; + + if (xmlConfigurableElementSettingsElement.getAttribute("ValueSpace", strValueSpace)) { + + configurationAccessContext.setValueSpaceRaw(strValueSpace == "Raw"); + } else { + + configurationAccessContext.setValueSpaceRaw(false); + } + } else { + // Set the value space only if it is raw (i.e. not the default one) + if (configurationAccessContext.valueSpaceIsRaw()) { + + xmlConfigurableElementSettingsElement.setAttribute("ValueSpace", "Raw"); + } + } +} + +bool CFloatingPointParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) +{ + // Size. The XSD fixes it to 32 + size_t sizeInBits = 32; + xmlElement.getAttribute("Size", sizeInBits); + + // Size support check: only floats are supported + // (e.g. doubles are not supported) + if (sizeInBits != sizeof(float) * CHAR_BIT) { + + serializingContext.setError("Unsupported size (" + std::to_string(sizeInBits) + ") for " + + getKind() + " " + xmlElement.getPath() + + ". For now, only 32 is supported."); + + return false; + } + + setSize(sizeInBits / CHAR_BIT); + + xmlElement.getAttribute("Min", _fMin); + xmlElement.getAttribute("Max", _fMax); + + if (_fMin > _fMax) { + serializingContext.setError("Min (" + std::to_string(_fMin) + + ") can't be greater than Max (" + std::to_string(_fMax) + ")"); + return false; + } + + return base::fromXml(xmlElement, serializingContext); +} + +bool CFloatingPointParameterType::toBlackboard( + const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const +{ + // Check Value integrity + if (utility::isHexadecimal(strValue) && !parameterAccessContext.valueSpaceIsRaw()) { + + parameterAccessContext.setError("Hexadecimal values are not supported for " + getKind() + + " when selected value space is real: " + strValue); + + return false; + } + + if (parameterAccessContext.valueSpaceIsRaw()) { + // Raw value: interpret the user input as the memory content of the + // parameter + if (!convertTo(strValue, uiValue)) { + + parameterAccessContext.setError("Value '" + strValue + "' is invalid"); + return false; + } + + auto fData = utility::binaryCopy<float>(uiValue); + + // Check against NaN or infinity + if (!std::isfinite(fData)) { + + parameterAccessContext.setError("Value " + strValue + " is not a finite number"); + return false; + } + + if (!checkValueAgainstRange(fData)) { + + setOutOfRangeError(strValue, parameterAccessContext); + return false; + } + return true; + } else { + + float fValue = 0.0f; + + // Interpret the user input as float + if (!convertTo(strValue, fValue)) { + + parameterAccessContext.setError("Value " + strValue + " is invalid"); + return false; + } + + if (!checkValueAgainstRange(fValue)) { + + setOutOfRangeError(strValue, parameterAccessContext); + return false; + } + + // Move to the "raw memory" value space + uiValue = utility::binaryCopy<decltype(uiValue)>(fValue); + return true; + } +} + +void CFloatingPointParameterType::setOutOfRangeError( + const string &strValue, CParameterAccessContext ¶meterAccessContext) const +{ + // error message buffer + std::ostringstream ostrStream; + + ostrStream << "Value " << strValue << " standing out of admitted "; + + if (!parameterAccessContext.valueSpaceIsRaw()) { + + ostrStream << "real range [" << _fMin << ", " << _fMax << "]"; + } else { + + auto uiMin = utility::binaryCopy<uint32_t>(_fMin); + auto uiMax = utility::binaryCopy<uint32_t>(_fMax); + + if (utility::isHexadecimal(strValue)) { + + ostrStream << std::showbase << std::hex << std::setw(static_cast<int>(getSize() * 2)) + << std::setfill('0'); + } + + ostrStream << "raw range [" << uiMin << ", " << uiMax << "]"; + } + ostrStream << " for " << getKind(); + + parameterAccessContext.setError(ostrStream.str()); +} + +bool CFloatingPointParameterType::fromBlackboard( + string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const +{ + std::ostringstream ostrStream; + + if (parameterAccessContext.valueSpaceIsRaw()) { + + if (parameterAccessContext.outputRawFormatIsHex()) { + + ostrStream << std::showbase << std::hex << std::setw(static_cast<int>(getSize() * 2)) + << std::setfill('0'); + } + + ostrStream << uiValue; + } else { + + // Move from "raw memory" value space to real space + auto fValue = utility::binaryCopy<float>(uiValue); + + ostrStream << fValue; + } + + strValue = ostrStream.str(); + + return true; +} + +// Value access +bool CFloatingPointParameterType::toBlackboard( + double dUserValue, uint32_t &uiValue, CParameterAccessContext ¶meterAccessContext) const +{ + if (!checkValueAgainstRange(dUserValue)) { + + parameterAccessContext.setError("Value out of range"); + return false; + } + + // Cast is fine because dValue has been checked against the value range + float fValue = static_cast<float>(dUserValue); + uiValue = utility::binaryCopy<decltype(uiValue)>(fValue); + return true; +} + +bool CFloatingPointParameterType::fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext & /*ctx*/) const +{ + // Move from "raw memory" value space to real space + auto fValue = utility::binaryCopy<float>(uiValue); + + dUserValue = fValue; + return true; +} + +bool CFloatingPointParameterType::checkValueAgainstRange(double dValue) const +{ + // Check that dValue can safely be cast to a float + // (otherwise, behaviour is undefined) + if ((dValue < -std::numeric_limits<float>::max()) || + (dValue > std::numeric_limits<float>::max())) { + return false; + } + + return checkValueAgainstRange(static_cast<float>(dValue)); +} + +bool CFloatingPointParameterType::checkValueAgainstRange(float fValue) const +{ + return fValue <= _fMax && fValue >= _fMin; +} + +void CFloatingPointParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const +{ + xmlElement.setAttribute("Size", getSize() * CHAR_BIT); + xmlElement.setAttribute("Min", _fMin); + xmlElement.setAttribute("Max", _fMax); + + base::toXml(xmlElement, serializingContext); +} diff --git a/parameter/FloatingPointParameterType.h b/parameter/FloatingPointParameterType.h new file mode 100644 index 0000000..aafb5e2 --- /dev/null +++ b/parameter/FloatingPointParameterType.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014-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. + */ +#pragma once + +#include "ParameterType.h" +#include <string> + +class CFloatingPointParameterType : public CParameterType +{ +public: + CFloatingPointParameterType(const std::string &strName); + + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; + + virtual void handleValueSpaceAttribute( + CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const; + + virtual bool toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool toBlackboard(double dUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; + + virtual void showProperties(std::string &strResult) const; + + virtual std::string getKind() const; + +private: + typedef CParameterType base; + + /** + * Format an out of range error. + * + * @param[in] strValue the user provided value + * @param[in,out] parameterAccessContext Parameter Access Context + */ + void setOutOfRangeError(const std::string &strValue, + CParameterAccessContext ¶meterAccessContext) const; + + /** + * Check value validity against range. + * + * @param[in] fValue the user interpreted value + * @return true if data is valid against range, false otherwise + */ + bool checkValueAgainstRange(float fValue) const; + /** + * Check value validity against range. + * + * @param[in] dValue the user interpreted value (as double) + * @return true if data is valid against range, false otherwise + */ + bool checkValueAgainstRange(double dValue) const; + + /** Bounds */ + float _fMin{std::numeric_limits<float>::lowest()}; + float _fMax{std::numeric_limits<float>::max()}; +}; diff --git a/parameter/FormattedSubsystemObject.cpp b/parameter/FormattedSubsystemObject.cpp index 591ef90..dc7dded 100644 --- a/parameter/FormattedSubsystemObject.cpp +++ b/parameter/FormattedSubsystemObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -38,39 +38,31 @@ using std::string; CFormattedSubsystemObject::CFormattedSubsystemObject( - CInstanceConfigurableElement* pInstanceConfigurableElement) - : base(pInstanceConfigurableElement) + CInstanceConfigurableElement *pInstanceConfigurableElement, core::log::Logger &logger) + : base(pInstanceConfigurableElement, logger) { } CFormattedSubsystemObject::CFormattedSubsystemObject( - CInstanceConfigurableElement* pInstanceConfigurableElement, - const string& strMappingValue) - : base(pInstanceConfigurableElement), _strFormattedMappingValue(strMappingValue) + CInstanceConfigurableElement *pInstanceConfigurableElement, core::log::Logger &logger, + const string &strMappingValue) + : base(pInstanceConfigurableElement, logger), _strFormattedMappingValue(strMappingValue) { - } - CFormattedSubsystemObject::CFormattedSubsystemObject( - CInstanceConfigurableElement* pInstanceConfigurableElement, - const string& strMappingValue, - uint32_t uiFirstAmendKey, - uint32_t uiNbAmendKeys, - const CMappingContext& context) - : base(pInstanceConfigurableElement), _strFormattedMappingValue(strMappingValue) + CInstanceConfigurableElement *pInstanceConfigurableElement, core::log::Logger &logger, + const string &strMappingValue, size_t firstAmendKey, size_t nbAmendKeys, + const CMappingContext &context) + : base(pInstanceConfigurableElement, logger), _strFormattedMappingValue(strMappingValue) { // Cope with quotes in the name if (strMappingValue[0] == '\'' && strMappingValue.length() >= 2) { _strFormattedMappingValue = strMappingValue.substr(1, strMappingValue.length() - 2); } - _strFormattedMappingValue = formatMappingValue(_strFormattedMappingValue, uiFirstAmendKey, - uiNbAmendKeys, context); -} - -CFormattedSubsystemObject::~CFormattedSubsystemObject() -{ + _strFormattedMappingValue = + formatMappingValue(_strFormattedMappingValue, firstAmendKey, nbAmendKeys, context); } string CFormattedSubsystemObject::getFormattedMappingValue() const @@ -78,16 +70,15 @@ string CFormattedSubsystemObject::getFormattedMappingValue() const return _strFormattedMappingValue; } -bool CFormattedSubsystemObject::isAmendKeyValid(uint32_t uiAmendKey) +bool CFormattedSubsystemObject::isAmendKeyValid(size_t uiAmendKey) { return (uiAmendKey > 0) && (uiAmendKey <= 9); } -string CFormattedSubsystemObject::formatMappingValue(const string& strMappingValue, - uint32_t uiFirstAmendKey, - uint32_t uiNbAmendKeys, - const CMappingContext& context) +string CFormattedSubsystemObject::formatMappingValue(const string &strMappingValue, + size_t firstAmendKey, size_t nbAmendKeys, + const CMappingContext &context) { string strFormattedValue = strMappingValue; @@ -95,36 +86,34 @@ string CFormattedSubsystemObject::formatMappingValue(const string& strMappingVal string::size_type uiPercentPos = strFormattedValue.find('%', 0); // Amendment limited to one digit (values from 1 to 9) - assert(isAmendKeyValid(uiNbAmendKeys)); + assert(isAmendKeyValid(nbAmendKeys)); // Check we found one and that there's room for value if (uiPercentPos != string::npos && uiPercentPos < strFormattedValue.size() - 1) { // Get Amend number - uint32_t uiAmendNumber = strFormattedValue[uiPercentPos + 1] - '0'; + size_t uiAmendNumber = strFormattedValue[uiPercentPos + 1] - '0'; // Check if current Amend number is Valid - if ((uiAmendNumber > 0) && (uiAmendNumber <= uiNbAmendKeys)) { + if ((uiAmendNumber > 0) && (uiAmendNumber <= nbAmendKeys)) { - uint32_t uiAmendType = uiFirstAmendKey + uiAmendNumber - 1; + size_t uiAmendType = firstAmendKey + uiAmendNumber - 1; // Check if current Amend type is Set in the context if (context.iSet(uiAmendType)) { // Make the amendment on the part of the string after the current Amend - string strEndOfLine = strFormattedValue.substr(uiPercentPos + 2, - strFormattedValue.size() - - uiPercentPos - 2); - string strEndOfLineAmended = formatMappingValue(strEndOfLine, uiFirstAmendKey, - uiNbAmendKeys, context); + string strEndOfLine = strFormattedValue.substr( + uiPercentPos + 2, strFormattedValue.size() - uiPercentPos - 2); + string strEndOfLineAmended = + formatMappingValue(strEndOfLine, firstAmendKey, nbAmendKeys, context); // Get current Amend value string strAmendValue = context.getItem(uiAmendType); // Make the amendment - strFormattedValue = strFormattedValue.substr(0, uiPercentPos) + strAmendValue - + strEndOfLineAmended; - + strFormattedValue = + strFormattedValue.substr(0, uiPercentPos) + strAmendValue + strEndOfLineAmended; } } } diff --git a/parameter/FormattedSubsystemObject.h b/parameter/FormattedSubsystemObject.h index c04583b..4793635 100644 --- a/parameter/FormattedSubsystemObject.h +++ b/parameter/FormattedSubsystemObject.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,44 +29,49 @@ */ #pragma once +#include "parameter_export.h" + #include "SubsystemObject.h" -class CFormattedSubsystemObject : public CSubsystemObject +class PARAMETER_EXPORT CFormattedSubsystemObject : public CSubsystemObject { public: /** * Builds a new CFormattedSubsystemObject instance, without any mapping information. * * @param[in] pInstanceConfigurableElement Instance of the element linked to the SubsytemObject. + * @param[in] logger the logger provided by the client */ - CFormattedSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement); + CFormattedSubsystemObject(CInstanceConfigurableElement *pInstanceConfigurableElement, + core::log::Logger &logger); /** * Builds a new CFormattedSubsystemObject instance, using a simple mapping value without Amends. * * @param[in] pInstanceConfigurableElement Instance of the element linked to the SubsytemObject. + * @param[in] logger the logger provided by the client * @param[in] strFormattedMapping A std::string corresponding to the mapping of the element. The * std::string does not contain any Amend (%) and does not need to be formatted. */ - CFormattedSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement, - const std::string& strFormattedMapping); + CFormattedSubsystemObject(CInstanceConfigurableElement *pInstanceConfigurableElement, + core::log::Logger &logger, const std::string &strFormattedMapping); /** * Builds a new CFormattedSubsystemObject instance, using a mapping value containing Amends. * * @param[in] pInstanceConfigurableElement Instance of the element linked to the SubsytemObject. + * @param[in] logger the logger provided by the client * @param[in] strMappingValue A std::string corresponding to the mapping of the element. The * std::string contains Amend (%) and needs to be formatted with information from the context. - * @param[in] uiFirstAmendKey Index of the first Amend key - * @param[in] uiNbAmendKeys Number of Amends + * @param[in] firstAmendKey Index of the first Amend key + * @param[in] nbAmendKeys Number of Amends * @param[in] context Contains values associated to Amend keys */ - CFormattedSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement, - const std::string& strMappingValue, - uint32_t uiFirstAmendKey, - uint32_t uiNbAmendKeys, - const CMappingContext& context); - virtual ~CFormattedSubsystemObject(); + CFormattedSubsystemObject(CInstanceConfigurableElement *pInstanceConfigurableElement, + core::log::Logger &logger, const std::string &strMappingValue, + size_t firstAmendKey, size_t nbAmendKeys, + const CMappingContext &context); + virtual ~CFormattedSubsystemObject() = default; /** * Returns the formatted mapping value associated to the element. @@ -76,7 +81,6 @@ public: virtual std::string getFormattedMappingValue() const; private: - /** * Check if the index of Amend key is valid. * @@ -84,7 +88,7 @@ private: * * @return true if the index of the Amend key is > 0 and <= 9. */ - static bool isAmendKeyValid(uint32_t uiAmendKey); + static bool isAmendKeyValid(size_t uiAmendKey); /** * Generic mapping formatting @@ -92,18 +96,17 @@ private: * Format a std::string from mapping data and its context, replacing amendments by their value * * @param[in] strMappingValue The input mapping std::string containing amendments - * @param[in] context uiFirstAmendKey The index of the first Amend key in the key list of the + * @param[in] context firstAmendKey The index of the first Amend key in the key list of the * context - * @param[in] uiNbAmendKeys Number of Amend keys in the context + * @param[in] nbAmendKeys Number of Amend keys in the context * @param[in] context The context containing Amend values * - * @return The formatted std::string, corresponding to the input strMappingValue where %n have been + * @return The formatted std::string, corresponding to the input strMappingValue where %n have + * been * replaced by their value */ - static std::string formatMappingValue(const std::string& strMappingValue, - uint32_t uiFirstAmendKey, - uint32_t uiNbAmendKeys, - const CMappingContext& context); + static std::string formatMappingValue(const std::string &strMappingValue, size_t firstAmendKey, + size_t nbAmendKeys, const CMappingContext &context); /** * std::string containing the formatted mapping value diff --git a/parameter/FrameworkConfigurationGroup.h b/parameter/FrameworkConfigurationGroup.h index e4da540..551cb5e 100644 --- a/parameter/FrameworkConfigurationGroup.h +++ b/parameter/FrameworkConfigurationGroup.h @@ -36,15 +36,11 @@ class CFrameworkConfigurationGroup : public CKindElement { public: - CFrameworkConfigurationGroup(const std::string& strName, const std::string& strKind) : CKindElement(strName, strKind) + CFrameworkConfigurationGroup(const std::string &strName, const std::string &strKind) + : CKindElement(strName, strKind) { } private: - virtual bool childrenAreDynamic() const - { - return true; - } - - + virtual bool childrenAreDynamic() const { return true; } }; diff --git a/parameter/FrameworkConfigurationLocation.cpp b/parameter/FrameworkConfigurationLocation.cpp index 6983f16..23c27e3 100644 --- a/parameter/FrameworkConfigurationLocation.cpp +++ b/parameter/FrameworkConfigurationLocation.cpp @@ -27,21 +27,25 @@ * (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 "XmlDocSource.h" #include "FrameworkConfigurationLocation.h" #include <assert.h> #define base CKindElement -CFrameworkConfigurationLocation::CFrameworkConfigurationLocation(const std::string& strName, const std::string& strKind) : base(strName, strKind) +CFrameworkConfigurationLocation::CFrameworkConfigurationLocation(const std::string &strName, + const std::string &strKind) + : base(strName, strKind) { } // From IXmlSink -bool CFrameworkConfigurationLocation::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CFrameworkConfigurationLocation::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { - _strPath = xmlElement.getAttributeString("Path"); + xmlElement.getAttribute("Path", _configurationUri); - if (_strPath.empty()) { + if (_configurationUri.empty()) { serializingContext.setError("Empty Path attribute in element " + xmlElement.getPath()); @@ -50,41 +54,7 @@ bool CFrameworkConfigurationLocation::fromXml(const CXmlElement& xmlElement, CXm return true; } -// File path -std::string CFrameworkConfigurationLocation::getFilePath(const std::string& strBaseFolder) const +const std::string &CFrameworkConfigurationLocation::getUri() const { - if (isPathRelative()) { - - return strBaseFolder + "/" + _strPath; - } - return _strPath; -} - -// Folder path -std::string CFrameworkConfigurationLocation::getFolderPath(const std::string& strBaseFolder) const -{ - uint32_t uiSlashPos = _strPath.rfind('/', -1); - - if (isPathRelative()) { - - if (uiSlashPos != (uint32_t)-1) { - - return strBaseFolder + "/" + _strPath.substr(0, uiSlashPos); - - } else { - - return strBaseFolder; - } - } else { - - assert(uiSlashPos != (uint32_t)-1); - - return _strPath.substr(0, uiSlashPos); - } -} - -// Detect relative path -bool CFrameworkConfigurationLocation::isPathRelative() const -{ - return _strPath[0] != '/'; + return _configurationUri; } diff --git a/parameter/FrameworkConfigurationLocation.h b/parameter/FrameworkConfigurationLocation.h index 56cc5f6..7182db9 100644 --- a/parameter/FrameworkConfigurationLocation.h +++ b/parameter/FrameworkConfigurationLocation.h @@ -36,20 +36,15 @@ class CFrameworkConfigurationLocation : public CKindElement { public: - CFrameworkConfigurationLocation(const std::string& strName, const std::string& strKind); + CFrameworkConfigurationLocation(const std::string &strName, const std::string &strKind); - // File path - std::string getFilePath(const std::string& strBaseFolder) const; - - // Folder path - std::string getFolderPath(const std::string& strBaseFolder) const; + /** Get Configuration file URI + */ + const std::string &getUri() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); -private: - // Detect relative path - bool isPathRelative() const; + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); - // Path - std::string _strPath; +private: + std::string _configurationUri; }; diff --git a/parameter/HardwareBackSynchronizer.cpp b/parameter/HardwareBackSynchronizer.cpp index b16ea79..dbc23eb 100644 --- a/parameter/HardwareBackSynchronizer.cpp +++ b/parameter/HardwareBackSynchronizer.cpp @@ -32,15 +32,16 @@ #define base CBackSynchronizer -CHardwareBackSynchronizer::CHardwareBackSynchronizer(const CConfigurableElement* pConfigurableElement, CParameterBlackboard* pParameterBlackboard) +CHardwareBackSynchronizer::CHardwareBackSynchronizer( + const CConfigurableElement *pConfigurableElement, CParameterBlackboard *pParameterBlackboard) : base(pConfigurableElement), _pParameterBlackboard(pParameterBlackboard) { // Fill back syncer set - std::list<const CConfigurableElement*>::const_iterator it; + std::list<const CConfigurableElement *>::const_iterator it; for (it = _needingBackSyncList.begin(); it != _needingBackSyncList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; pConfigurableElement->fillSyncerSet(_backSyncerSet); } diff --git a/parameter/HardwareBackSynchronizer.h b/parameter/HardwareBackSynchronizer.h index 9572017..fd2e70d 100644 --- a/parameter/HardwareBackSynchronizer.h +++ b/parameter/HardwareBackSynchronizer.h @@ -35,7 +35,8 @@ class CHardwareBackSynchronizer : public CBackSynchronizer { public: - CHardwareBackSynchronizer(const CConfigurableElement* pConfigurableElement, CParameterBlackboard* pParameterBlackboard); + CHardwareBackSynchronizer(const CConfigurableElement *pConfigurableElement, + CParameterBlackboard *pParameterBlackboard); // Back synchronization virtual void sync(); @@ -44,6 +45,5 @@ private: // Back syncer set CSyncerSet _backSyncerSet; // Parameter blackboard - CParameterBlackboard* _pParameterBlackboard; + CParameterBlackboard *_pParameterBlackboard; }; - diff --git a/parameter/InstanceConfigurableElement.cpp b/parameter/InstanceConfigurableElement.cpp index b59cffd..f9afa20 100644 --- a/parameter/InstanceConfigurableElement.cpp +++ b/parameter/InstanceConfigurableElement.cpp @@ -35,9 +35,11 @@ #include "ParameterAccessContext.h" #include <assert.h> -#define base CConfigurableElementWithMapping +#define base CConfigurableElement -CInstanceConfigurableElement::CInstanceConfigurableElement(const std::string& strName, const CTypeElement* pTypeElement) : base(strName), _pTypeElement(pTypeElement), _pSyncer(NULL) +CInstanceConfigurableElement::CInstanceConfigurableElement(const std::string &strName, + const CTypeElement *pTypeElement) + : base(strName), _pTypeElement(pTypeElement) { } @@ -47,14 +49,21 @@ std::string CInstanceConfigurableElement::getKind() const return _pTypeElement->getKind(); } +std::string CInstanceConfigurableElement::getXmlElementName() const +{ + // Delegate + return _pTypeElement->getXmlElementName(); +} + // Type element -const CTypeElement* CInstanceConfigurableElement::getTypeElement() const +const CTypeElement *CInstanceConfigurableElement::getTypeElement() const { return _pTypeElement; } // Mapping -bool CInstanceConfigurableElement::getMappingData(const std::string& strKey, const std::string*& pStrValue) const +bool CInstanceConfigurableElement::getMappingData(const std::string &strKey, + const std::string *&pStrValue) const { // Delegate return getTypeElement()->getMappingData(strKey, pStrValue); @@ -67,7 +76,7 @@ std::string CInstanceConfigurableElement::getFormattedMapping() const return getTypeElement()->getFormattedMapping(); } -bool CInstanceConfigurableElement::map(IMapper& mapper, std::string& strError) +bool CInstanceConfigurableElement::map(IMapper &mapper, std::string &strError) { bool bHasMappingData = getTypeElement()->hasMappingData(); bool bKeepDiving = true; @@ -87,8 +96,8 @@ bool CInstanceConfigurableElement::map(IMapper& mapper, std::string& strError) for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - CInstanceConfigurableElement* pInstanceConfigurableChildElement = - static_cast<CInstanceConfigurableElement*>(getChild(uiChild)); + CInstanceConfigurableElement *pInstanceConfigurableChildElement = + static_cast<CInstanceConfigurableElement *>(getChild(uiChild)); if (!pInstanceConfigurableChildElement->map(mapper, strError)) { @@ -105,21 +114,8 @@ bool CInstanceConfigurableElement::map(IMapper& mapper, std::string& strError) return true; } -void CInstanceConfigurableElement::getListOfElementsWithMapping( - std::list<const CConfigurableElement*>& configurableElementPath) const -{ - const CTypeElement* pTypeElement = getTypeElement(); - - if (pTypeElement && pTypeElement->hasMappingData()) { - - configurableElementPath.push_back(this); - } - - base::getListOfElementsWithMapping(configurableElementPath); -} - // Element properties -void CInstanceConfigurableElement::showProperties(std::string& strResult) const +void CInstanceConfigurableElement::showProperties(std::string &strResult) const { base::showProperties(strResult); @@ -134,13 +130,13 @@ bool CInstanceConfigurableElement::isScalar() const } // Array Length -uint32_t CInstanceConfigurableElement::getArrayLength() const +size_t CInstanceConfigurableElement::getArrayLength() const { return _pTypeElement->getArrayLength(); } // Sync to HW -void CInstanceConfigurableElement::setSyncer(ISyncer* pSyncer) +void CInstanceConfigurableElement::setSyncer(ISyncer *pSyncer) { assert(!_pSyncer); @@ -153,7 +149,7 @@ void CInstanceConfigurableElement::unsetSyncer() } // Syncer -ISyncer* CInstanceConfigurableElement::getSyncer() const +ISyncer *CInstanceConfigurableElement::getSyncer() const { if (_pSyncer) { @@ -164,7 +160,7 @@ ISyncer* CInstanceConfigurableElement::getSyncer() const } // Syncer set (descendant) -void CInstanceConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const +void CInstanceConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const { if (_pSyncer) { @@ -175,7 +171,7 @@ void CInstanceConfigurableElement::fillSyncerSetFromDescendant(CSyncerSet& synce } } -bool CInstanceConfigurableElement::sync(CParameterAccessContext& parameterAccessContext) const +bool CInstanceConfigurableElement::sync(CParameterAccessContext ¶meterAccessContext) const { if (!parameterAccessContext.getAutoSync()) { @@ -183,11 +179,12 @@ bool CInstanceConfigurableElement::sync(CParameterAccessContext& parameterAccess // This is not an error, but the expected behavior so return true anyway. return true; } - ISyncer* pSyncer = getSyncer(); + ISyncer *pSyncer = getSyncer(); if (!pSyncer) { - parameterAccessContext.setError("Unable to synchronize modification. No Syncer object associated to configurable element:"); + parameterAccessContext.setError("Unable to synchronize modification. No Syncer object " + "associated to configurable element:"); return false; } @@ -203,9 +200,10 @@ bool CInstanceConfigurableElement::sync(CParameterAccessContext& parameterAccess } // Check parameter access path well formed for leaf elements -bool CInstanceConfigurableElement::checkPathExhausted(CPathNavigator& pathNavigator, CErrorContext& errorContext) +bool CInstanceConfigurableElement::checkPathExhausted(CPathNavigator &pathNavigator, + utility::ErrorContext &errorContext) { - std::string* pStrChildName = pathNavigator.next(); + std::string *pStrChildName = pathNavigator.next(); if (pStrChildName) { @@ -217,9 +215,10 @@ bool CInstanceConfigurableElement::checkPathExhausted(CPathNavigator& pathNaviga return true; } -void CInstanceConfigurableElement::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const +void CInstanceConfigurableElement::structureToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { - base::toXml(xmlElement, serializingContext); + base::structureToXml(xmlElement, serializingContext); // Since Description belongs to the Type of Element, delegate it to the type element. getTypeElement()->setXmlDescriptionAttribute(xmlElement); } diff --git a/parameter/InstanceConfigurableElement.h b/parameter/InstanceConfigurableElement.h index eea3df6..0b4a7f9 100644 --- a/parameter/InstanceConfigurableElement.h +++ b/parameter/InstanceConfigurableElement.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,7 +29,9 @@ */ #pragma once -#include "ConfigurableElementWithMapping.h" +#include "parameter_export.h" + +#include "ConfigurableElement.h" #include "TypeElement.h" #include <list> @@ -39,10 +41,11 @@ class IMapper; class CParameterBlackboard; class CParameterAccessContext; -class CInstanceConfigurableElement : public CConfigurableElementWithMapping +class PARAMETER_EXPORT CInstanceConfigurableElement : public CConfigurableElement { public: - enum Type { + enum Type + { EBitParameter, EBitParameterBlock, EParameter, @@ -51,12 +54,12 @@ public: EComponent }; - CInstanceConfigurableElement(const std::string& strName, const CTypeElement* pTypeElement); + CInstanceConfigurableElement(const std::string &strName, const CTypeElement *pTypeElement); // Instantiated type - const CTypeElement* getTypeElement() const; + const CTypeElement *getTypeElement() const; - virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const; + virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const; /** * Returns the mapping data associated to the type element of the current @@ -64,71 +67,59 @@ public: * * @return A std::string containing the formatted mapping */ - std::string getFormattedMapping() const; + std::string getFormattedMapping() const override; // From CElement virtual std::string getKind() const; + std::string getXmlElementName() const override; // Syncer to/from HW - void setSyncer(ISyncer* pSyncer); + void setSyncer(ISyncer *pSyncer); void unsetSyncer(); // Type virtual Type getType() const = 0; // Mapping execution - bool map(IMapper& mapper, std::string& strError); + bool map(IMapper &mapper, std::string &strError); // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // Scalar or Array? bool isScalar() const; // Array Length - uint32_t getArrayLength() const; - - /** - * Get the list of all the ancestors that have a mapping. - * - * The mapping is represented as a std::string of all the mapping data (key:value) defined in the - * context of the element. - * In this class, the method is generic and calls its parent getListOfElementsWithMappings(...) - * method. - * - * @param[in:out] configurableElementPath List of all the ConfigurableElements found - * that have a mapping. Elements are added at the end of the list, so the root Element will be - * the last one. - */ - virtual void getListOfElementsWithMapping(std::list<const CConfigurableElement*>& - configurableElementPath) const; + size_t getArrayLength() const; - virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; + virtual void structureToXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const; protected: // Syncer - virtual ISyncer* getSyncer() const; + virtual ISyncer *getSyncer() const; // Syncer set (descendant) - virtual void fillSyncerSetFromDescendant(CSyncerSet& syncerSet) const; + virtual void fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const; /** * Performs the sync if the AutoSync is enabled. * If AutoSync is disabled, any call to sync will returns true, even if synchronization has not * been done. It will happen when the AutoSync will be switched back on. * - * @param[in:out] parameterAccessContext Parameter access context object + * @param[in,out] parameterAccessContext Parameter access context object * * @return true if the synchronization succeded or if the AutoSync is off, false otherwise. */ - bool sync(CParameterAccessContext& parameterAccessContext) const; + bool sync(CParameterAccessContext ¶meterAccessContext) const; // Check parameter access path well formed for leaf elements - static bool checkPathExhausted(CPathNavigator& pathNavigator, CErrorContext& errorContext); + static bool checkPathExhausted(CPathNavigator &pathNavigator, + utility::ErrorContext &errorContext); + private: // Type Element - const CTypeElement* _pTypeElement; + const CTypeElement *_pTypeElement; // Sync to HW - ISyncer* _pSyncer; + ISyncer *_pSyncer{nullptr}; }; - diff --git a/parameter/InstanceDefinition.cpp b/parameter/InstanceDefinition.cpp index 74498ac..e461fa4 100644 --- a/parameter/InstanceDefinition.cpp +++ b/parameter/InstanceDefinition.cpp @@ -32,10 +32,6 @@ #define base CTypeElement -CInstanceDefinition::CInstanceDefinition() -{ -} - std::string CInstanceDefinition::getKind() const { return "InstanceDefinition"; @@ -46,7 +42,7 @@ bool CInstanceDefinition::childrenAreDynamic() const return true; } -CInstanceConfigurableElement* CInstanceDefinition::doInstantiate() const +CInstanceConfigurableElement *CInstanceDefinition::doInstantiate() const { // Element not supposed to be instantiated direcly assert(0); @@ -54,7 +50,7 @@ CInstanceConfigurableElement* CInstanceDefinition::doInstantiate() const return NULL; } -void CInstanceDefinition::createInstances(CElement* pFatherElement) +void CInstanceDefinition::createInstances(CElement *pFatherElement) { populate(pFatherElement); } diff --git a/parameter/InstanceDefinition.h b/parameter/InstanceDefinition.h index 046f76c..212c535 100644 --- a/parameter/InstanceDefinition.h +++ b/parameter/InstanceDefinition.h @@ -36,12 +36,11 @@ class CInstanceDefinition : public CTypeElement { public: - CInstanceDefinition(); - - void createInstances(CElement* pFatherElement); + void createInstances(CElement *pFatherElement); virtual std::string getKind() const; + private: virtual bool childrenAreDynamic() const; - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; }; diff --git a/parameter/IntegerParameterType.cpp b/parameter/IntegerParameterType.cpp index 2d48d53..4899514 100644 --- a/parameter/IntegerParameterType.cpp +++ b/parameter/IntegerParameterType.cpp @@ -42,7 +42,7 @@ using std::string; using std::ostringstream; -CIntegerParameterType::CIntegerParameterType(const string& strName) : base(strName), _uiMin(0), _uiMax(uint32_t(-1)) +CIntegerParameterType::CIntegerParameterType(const string &strName) : base(strName) { } @@ -59,7 +59,7 @@ bool CIntegerParameterType::childrenAreDynamic() const } // Element properties -void CIntegerParameterType::showProperties(string& strResult) const +void CIntegerParameterType::showProperties(string &strResult) const { base::showProperties(strResult); @@ -70,16 +70,16 @@ void CIntegerParameterType::showProperties(string& strResult) const // Min strResult += "Min: "; - strResult += _bSigned ? CUtility::toString((int32_t)_uiMin) : CUtility::toString(_uiMin); + strResult += _bSigned ? std::to_string((int32_t)_uiMin) : std::to_string(_uiMin); strResult += "\n"; // Max strResult += "Max: "; - strResult += _bSigned ? CUtility::toString((int32_t)_uiMax) : CUtility::toString(_uiMax); + strResult += _bSigned ? std::to_string((int32_t)_uiMax) : std::to_string(_uiMax); strResult += "\n"; // Check if there's an adaptation object available - const CParameterAdaptation* pParameterAdaption = getParameterAdaptation(); + const CParameterAdaptation *pParameterAdaption = getParameterAdaptation(); if (pParameterAdaption) { @@ -90,56 +90,46 @@ void CIntegerParameterType::showProperties(string& strResult) const } } -bool CIntegerParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CIntegerParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Sign - _bSigned = xmlElement.getAttributeBoolean("Signed"); + xmlElement.getAttribute("Signed", _bSigned); // Size in bits - uint32_t uiSizeInBits = xmlElement.getAttributeInteger("Size"); + size_t sizeInBits = 0; + xmlElement.getAttribute("Size", sizeInBits); // Size - setSize(uiSizeInBits / 8); + setSize(sizeInBits / 8); // Min / Max + // TODO: Make IntegerParameter template if (_bSigned) { // Signed means we have one less util bit - uiSizeInBits--; + sizeInBits--; - if (xmlElement.hasAttribute("Min")) { - - _uiMin = (uint32_t)xmlElement.getAttributeSignedInteger("Min"); - } else { - - _uiMin = 1UL << uiSizeInBits; + if (!xmlElement.getAttribute("Min", (int32_t &)_uiMin)) { + _uiMin = 1U << sizeInBits; } - signExtend((int32_t&)_uiMin); - - if (xmlElement.hasAttribute("Max")) { - _uiMax = (uint32_t)xmlElement.getAttributeSignedInteger("Max"); + if (!xmlElement.getAttribute("Max", (int32_t &)_uiMax)) { - signExtend((int32_t&)_uiMax); - } else { - - _uiMax = (1UL << uiSizeInBits) - 1; + _uiMax = (1U << sizeInBits) - 1; } + signExtend((int32_t &)_uiMin); + signExtend((int32_t &)_uiMax); } else { - if (xmlElement.hasAttribute("Min")) { - - _uiMin = xmlElement.getAttributeInteger("Min"); - } else { + if (!xmlElement.getAttribute("Min", _uiMin)) { _uiMin = 0; } - if (xmlElement.hasAttribute("Max")) { - _uiMax = xmlElement.getAttributeInteger("Max"); - } else { + if (!xmlElement.getAttribute("Max", _uiMax)) { - _uiMax = (uint32_t)-1L >> (8 * sizeof(uint32_t) - uiSizeInBits); + _uiMax = ~0U >> (8 * sizeof(size_t) - sizeInBits); } } @@ -148,10 +138,11 @@ bool CIntegerParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializi } // Conversion (tuning) -bool CIntegerParameterType::toBlackboard(const string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::toBlackboard(const string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { // Hexa - bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); + bool bValueProvidedAsHexa = utility::isHexadecimal(strValue); // Get integer value from the string provided int64_t iData; @@ -170,13 +161,15 @@ bool CIntegerParameterType::toBlackboard(const string& strValue, uint32_t& uiVal signExtend(iData); } - if (!checkValueAgainstRange<int64_t>(strValue, iData, (int32_t)_uiMin, (int32_t)_uiMax, parameterAccessContext, bValueProvidedAsHexa)) { + if (!checkValueAgainstRange<int64_t>(strValue, iData, (int32_t)_uiMin, (int32_t)_uiMax, + parameterAccessContext, bValueProvidedAsHexa)) { return false; } } else { - if (!checkValueAgainstRange<uint64_t>(strValue, iData, _uiMin, _uiMax, parameterAccessContext, bValueProvidedAsHexa)) { + if (!checkValueAgainstRange<uint64_t>(strValue, iData, _uiMin, _uiMax, + parameterAccessContext, bValueProvidedAsHexa)) { return false; } @@ -187,43 +180,46 @@ bool CIntegerParameterType::toBlackboard(const string& strValue, uint32_t& uiVal return true; } -bool CIntegerParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::fromBlackboard(string &strValue, const uint32_t &value, + CParameterAccessContext ¶meterAccessContext) const { // Check unsigned value is encodable - assert(isEncodable(uiValue, false)); + assert(isEncodable(value, false)); // Format - ostringstream strStream; + ostringstream stream; // Take care of format if (parameterAccessContext.valueSpaceIsRaw() && parameterAccessContext.outputRawFormatIsHex()) { // Hexa display with unecessary bits cleared out - strStream << "0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << uiValue; + stream << "0x" << std::hex << std::uppercase << std::setw(static_cast<int>(getSize() * 2)) + << std::setfill('0') << value; } else { if (_bSigned) { - int32_t iValue = uiValue; + int32_t iValue = value; // Sign extend signExtend(iValue); - strStream << iValue; + stream << iValue; } else { - strStream << uiValue; + stream << value; } } - strValue = strStream.str(); + strValue = stream.str(); return true; } // Value access // Integer -bool CIntegerParameterType::toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::toBlackboard(uint32_t uiUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { if (uiUserValue < _uiMin || uiUserValue > _uiMax) { @@ -237,10 +233,9 @@ bool CIntegerParameterType::toBlackboard(uint32_t uiUserValue, uint32_t& uiValue return true; } -bool CIntegerParameterType::fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::fromBlackboard(uint32_t &uiUserValue, uint32_t uiValue, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - // Do assign uiUserValue = uiValue; @@ -248,7 +243,8 @@ bool CIntegerParameterType::fromBlackboard(uint32_t& uiUserValue, uint32_t uiVal } // Signed Integer -bool CIntegerParameterType::toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::toBlackboard(int32_t iUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { if (iUserValue < (int32_t)_uiMin || iUserValue > (int32_t)_uiMax) { @@ -262,10 +258,9 @@ bool CIntegerParameterType::toBlackboard(int32_t iUserValue, uint32_t& uiValue, return true; } -bool CIntegerParameterType::fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::fromBlackboard(int32_t &iUserValue, uint32_t uiValue, + CParameterAccessContext & /*ctx*/) const { - (void)parameterAccessContext; - int32_t iValue = uiValue; // Sign extend @@ -278,10 +273,11 @@ bool CIntegerParameterType::fromBlackboard(int32_t& iUserValue, uint32_t uiValue } // Double -bool CIntegerParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::toBlackboard(double dUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const { // Check if there's an adaptation object available - const CParameterAdaptation* pParameterAdaption = getParameterAdaptation(); + const CParameterAdaptation *pParameterAdaption = getParameterAdaptation(); if (!pParameterAdaption) { @@ -317,10 +313,11 @@ bool CIntegerParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, C return true; } -bool CIntegerParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CIntegerParameterType::fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const { // Check if there's an adaptation object available - const CParameterAdaptation* pParameterAdaption = getParameterAdaptation(); + const CParameterAdaptation *pParameterAdaption = getParameterAdaptation(); if (!pParameterAdaption) { @@ -366,7 +363,9 @@ int CIntegerParameterType::toPlainInteger(int iSizeOptimizedData) const } // Convert value provided by the user as a string into an int64 -bool CIntegerParameterType::convertValueFromString(const string& strValue, int64_t& iData, CParameterAccessContext& parameterAccessContext) const { +bool CIntegerParameterType::convertValueFromString( + const string &strValue, int64_t &iData, CParameterAccessContext ¶meterAccessContext) const +{ // Reset errno to check if it is updated during the conversion (strtol/strtoul) errno = 0; @@ -381,11 +380,12 @@ bool CIntegerParameterType::convertValueFromString(const string& strValue, int64 iData = strtoull(strValue.c_str(), &pcStrEnd, 0); } - // Conversion error when the input string does not contain only digits or the number is out of range (int32_t type) + // Conversion error when the input string does not contain only digits or the number is out of + // range (int32_t type) if (errno || (*pcStrEnd != '\0')) { string strError; - strError = "Impossible to convert value " + strValue + " for " + getKind(); + strError = "Impossible to convert value " + strValue + " for " + getKind(); parameterAccessContext.setError(strError); @@ -396,29 +396,35 @@ bool CIntegerParameterType::convertValueFromString(const string& strValue, int64 } // Range checking -template <typename type> bool CIntegerParameterType::checkValueAgainstRange(const string& strValue, type value, type minValue, type maxValue, CParameterAccessContext& parameterAccessContext, bool bHexaValue) const +template <typename type> +bool CIntegerParameterType::checkValueAgainstRange(const string &strValue, type value, + type minValue, type maxValue, + CParameterAccessContext ¶meterAccessContext, + bool bHexaValue) const { if (value < minValue || value > maxValue) { - ostringstream strStream; + ostringstream stream; - strStream << "Value " << strValue << " standing out of admitted range ["; + stream << "Value " << strValue << " standing out of admitted range ["; if (bHexaValue) { + stream << "0x" << std::hex << std::uppercase + << std::setw(static_cast<int>(getSize() * 2)) << std::setfill('0'); // Format Min - strStream << "0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << makeEncodable(minValue); + stream << minValue; // Format Max - strStream << ", 0x" << std::hex << std::uppercase << std::setw(getSize()*2) << std::setfill('0') << makeEncodable(maxValue); + stream << maxValue; } else { - strStream << minValue << ", " << maxValue; + stream << minValue << ", " << maxValue; } - strStream << "] for " << getKind(); + stream << "] for " << getKind(); - parameterAccessContext.setError(strStream.str()); + parameterAccessContext.setError(stream.str()); return false; } @@ -426,37 +432,37 @@ template <typename type> bool CIntegerParameterType::checkValueAgainstRange(cons } // Adaptation element retrieval -const CParameterAdaptation* CIntegerParameterType::getParameterAdaptation() const +const CParameterAdaptation *CIntegerParameterType::getParameterAdaptation() const { - return static_cast<const CParameterAdaptation*>(findChildOfKind("Adaptation")); + return static_cast<const CParameterAdaptation *>(findChildOfKind("Adaptation")); } // From IXmlSource -void CIntegerParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CIntegerParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Sign - xmlElement.setAttributeBoolean("Signed", _bSigned); + xmlElement.setAttribute("Signed", _bSigned); if (_bSigned) { // Mininmum - xmlElement.setAttributeString("Min", CUtility::toString((int32_t)_uiMin)); + xmlElement.setAttribute("Min", (int32_t)_uiMin); // Maximum - xmlElement.setAttributeString("Max", CUtility::toString((int32_t)_uiMax)); + xmlElement.setAttribute("Max", (int32_t)_uiMax); } else { // Minimum - xmlElement.setAttributeString("Min", CUtility::toString(_uiMin)); + xmlElement.setAttribute("Min", _uiMin); // Maximum - xmlElement.setAttributeString("Max", CUtility::toString(_uiMax)); + xmlElement.setAttribute("Max", _uiMax); } // Size - xmlElement.setAttributeString("Size", CUtility::toString(getSize() * 8)); + xmlElement.setAttribute("Size", getSize() * 8); base::toXml(xmlElement, serializingContext); - } diff --git a/parameter/IntegerParameterType.h b/parameter/IntegerParameterType.h index 53bd4a8..5eea40b 100644 --- a/parameter/IntegerParameterType.h +++ b/parameter/IntegerParameterType.h @@ -32,39 +32,48 @@ #include "ParameterType.h" #include <string> +#include <limits> class CParameterAdaptation; class CIntegerParameterType : public CParameterType { public: - CIntegerParameterType(const std::string& strName); + CIntegerParameterType(const std::string &strName); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; /// Conversion // String - virtual bool toBlackboard(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(std::string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Integer - virtual bool toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(uint32_t uiUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(uint32_t &uiUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Signed Integer - virtual bool toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(int32_t iUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(int32_t &iUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Double - virtual bool toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(double dUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Default value handling (simulation only) virtual uint32_t getDefaultValue() const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // Integer conversion virtual int toPlainInteger(int iSizeOptimizedData) const; @@ -77,17 +86,21 @@ private: virtual bool childrenAreDynamic() const; // Conversion from std::string - bool convertValueFromString(const std::string& strValue, int64_t& iData, CParameterAccessContext& parameterAccessContext) const; + bool convertValueFromString(const std::string &strValue, int64_t &iData, + CParameterAccessContext ¶meterAccessContext) const; // Range checking - template <typename type> bool checkValueAgainstRange(const std::string& strValue, type value, type minValue, type maxValue, CParameterAccessContext& parameterAccessContext, bool bHexaValue) const; + template <typename type> + bool checkValueAgainstRange(const std::string &strValue, type value, type minValue, + type maxValue, CParameterAccessContext ¶meterAccessContext, + bool bHexaValue) const; // Adaptation element retrieval - const CParameterAdaptation* getParameterAdaptation() const; + const CParameterAdaptation *getParameterAdaptation() const; // Signing - bool _bSigned; + bool _bSigned{false}; // Range - uint32_t _uiMin; - uint32_t _uiMax; + uint32_t _uiMin{0}; + uint32_t _uiMax{std::numeric_limits<uint32_t>::max()}; }; diff --git a/parameter/KindElement.h b/parameter/KindElement.h index df826ff..848180a 100644 --- a/parameter/KindElement.h +++ b/parameter/KindElement.h @@ -36,15 +36,12 @@ class CKindElement : public CElement { public: - CKindElement(const std::string& strName, const std::string& strKind) : CElement(strName), _strKind(strKind) + CKindElement(const std::string &strName, const std::string &strKind) + : CElement(strName), _strKind(strKind) { } - virtual std::string getKind() const - { - return _strKind; - } + virtual std::string getKind() const { return _strKind; } private: - std::string _strKind; }; diff --git a/parameter/KindElementBuilderTemplate.h b/parameter/KindElementBuilderTemplate.h index dc576db..ffce475 100644 --- a/parameter/KindElementBuilderTemplate.h +++ b/parameter/KindElementBuilderTemplate.h @@ -37,7 +37,7 @@ class TKindElementBuilderTemplate : public CElementBuilder public: TKindElementBuilderTemplate() : CElementBuilder() {} - virtual CElement* createElement(const CXmlElement& xmlElement) const + virtual CElement *createElement(const CXmlElement &xmlElement) const { return new ElementType(xmlElement.getNameAttribute(), xmlElement.getType()); } diff --git a/parameter/LinearParameterAdaptation.cpp b/parameter/LinearParameterAdaptation.cpp index ae925a7..5c8002d 100644 --- a/parameter/LinearParameterAdaptation.cpp +++ b/parameter/LinearParameterAdaptation.cpp @@ -28,65 +28,50 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "LinearParameterAdaptation.h" -#include "Utility.h" #define base CParameterAdaptation using std::string; -CLinearParameterAdaptation::CLinearParameterAdaptation() : base("Linear"), _dSlopeNumerator(1), _dSlopeDenominator(1) +CLinearParameterAdaptation::CLinearParameterAdaptation() : base("Linear") { } -CLinearParameterAdaptation::CLinearParameterAdaptation(const string& strType) : - base(strType), _dSlopeNumerator(1), _dSlopeDenominator(1) +CLinearParameterAdaptation::CLinearParameterAdaptation(const string &strType) : base(strType) { } // Element properties -void CLinearParameterAdaptation::showProperties(string& strResult) const +void CLinearParameterAdaptation::showProperties(string &strResult) const { base::showProperties(strResult); // SlopeNumerator strResult += " - SlopeNumerator: "; - strResult += CUtility::toString(_dSlopeNumerator); + strResult += std::to_string(_dSlopeNumerator); strResult += "\n"; // SlopeDenominator strResult += " - SlopeDenominator: "; - strResult += CUtility::toString(_dSlopeDenominator); + strResult += std::to_string(_dSlopeDenominator); strResult += "\n"; } // From IXmlSink -bool CLinearParameterAdaptation::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CLinearParameterAdaptation::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Get SlopeNumerator - if (xmlElement.hasAttribute("SlopeNumerator")) { + xmlElement.getAttribute("SlopeNumerator", _dSlopeNumerator); - _dSlopeNumerator = xmlElement.getAttributeDouble("SlopeNumerator"); - - } else { - // Default - _dSlopeNumerator = 1; - } // Get SlopeDenominator - if (xmlElement.hasAttribute("SlopeDenominator")) { - - _dSlopeDenominator = xmlElement.getAttributeDouble("SlopeDenominator"); + if (xmlElement.getAttribute("SlopeDenominator", _dSlopeDenominator) && + (_dSlopeDenominator == 0)) { // Avoid by 0 division errors - if (_dSlopeDenominator == 0) { - - serializingContext.setError("SlopeDenominator attribute can't be 0 on element" + xmlElement.getPath()); - - return false; - } - - } else { - // Default - _dSlopeDenominator = 1; + serializingContext.setError("SlopeDenominator attribute can't be 0 on element" + + xmlElement.getPath()); + return false; } // Base diff --git a/parameter/LinearParameterAdaptation.h b/parameter/LinearParameterAdaptation.h index 8037c31..0c6ff5e 100644 --- a/parameter/LinearParameterAdaptation.h +++ b/parameter/LinearParameterAdaptation.h @@ -37,19 +37,20 @@ class CLinearParameterAdaptation : public CParameterAdaptation { public: CLinearParameterAdaptation(); - CLinearParameterAdaptation(const std::string& strType); + CLinearParameterAdaptation(const std::string &strType); // Conversions virtual int64_t fromUserValue(double dValue) const; virtual double toUserValue(int64_t iValue) const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); + private: // Slope attributes - double _dSlopeNumerator; - double _dSlopeDenominator; + double _dSlopeNumerator{1}; + double _dSlopeDenominator{1}; }; diff --git a/parameter/LogarithmicParameterAdaptation.cpp b/parameter/LogarithmicParameterAdaptation.cpp index bca4948..128ab07 100644 --- a/parameter/LogarithmicParameterAdaptation.cpp +++ b/parameter/LogarithmicParameterAdaptation.cpp @@ -29,59 +29,54 @@ */ #include "LogarithmicParameterAdaptation.h" -#include "Utility.h" -#include <math.h> +#include <cmath> +#include <limits> +#include <algorithm> #define base CLinearParameterAdaptation -// M_E is the base of the natural logarithm for 'e' from math.h -CLogarithmicParameterAdaptation::CLogarithmicParameterAdaptation() : base("Logarithmic"), - _dLogarithmBase(M_E), _dFloorValue(-INFINITY) +CLogarithmicParameterAdaptation::CLogarithmicParameterAdaptation() : base("Logarithmic") { + static_assert(std::numeric_limits<double>::is_iec559, + "Only double-precision floating points that are compliant with" + " IEC 559 (aka IEEE 754) are supported"); } // Element properties -void CLogarithmicParameterAdaptation::showProperties(std::string& strResult) const +void CLogarithmicParameterAdaptation::showProperties(std::string &strResult) const { base::showProperties(strResult); strResult += " - LogarithmBase: "; - strResult += CUtility::toString(_dLogarithmBase); + strResult += std::to_string(_dLogarithmBase); strResult += "\n"; strResult += " - FloorValue: "; - strResult += CUtility::toString(_dFloorValue); + strResult += std::to_string(_dFloorValue); strResult += "\n"; } -bool CLogarithmicParameterAdaptation::fromXml(const CXmlElement& xmlElement, - CXmlSerializingContext& serializingContext) +bool CLogarithmicParameterAdaptation::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { - - if (xmlElement.hasAttribute("LogarithmBase")) { - - _dLogarithmBase = xmlElement.getAttributeDouble("LogarithmBase"); - + if (xmlElement.getAttribute("LogarithmBase", _dLogarithmBase) && + (_dLogarithmBase <= 0 || _dLogarithmBase == 1)) { // Avoid negative and 1 values - if (_dLogarithmBase <= 0 || _dLogarithmBase == 1) { - serializingContext.setError("LogarithmBase attribute cannot be negative or 1 on element" - + xmlElement.getPath()); + serializingContext.setError("LogarithmBase attribute cannot be negative or 1 on element" + + xmlElement.getPath()); - return false; - } + return false; } - if (xmlElement.hasAttribute("FloorValue")) { - _dFloorValue = xmlElement.getAttributeDouble("FloorValue"); - } + xmlElement.getAttribute("FloorValue", _dFloorValue); + // Base return base::fromXml(xmlElement, serializingContext); } - -int64_t CLogarithmicParameterAdaptation::fromUserValue(double dValue) const +int64_t CLogarithmicParameterAdaptation::fromUserValue(double value) const { - return fmax(round(base::fromUserValue(log(dValue) / log(_dLogarithmBase))), - _dFloorValue); + return std::max(base::fromUserValue(log(value) / log(_dLogarithmBase)), + static_cast<int64_t>(_dFloorValue)); } double CLogarithmicParameterAdaptation::toUserValue(int64_t iValue) const diff --git a/parameter/LogarithmicParameterAdaptation.h b/parameter/LogarithmicParameterAdaptation.h index 3b7fd4d..9c2553b 100644 --- a/parameter/LogarithmicParameterAdaptation.h +++ b/parameter/LogarithmicParameterAdaptation.h @@ -31,6 +31,8 @@ #pragma once #include "LinearParameterAdaptation.h" +#include <cmath> +#include <limits> /** * This class is used to perform a logarithmic adapation of type: @@ -54,18 +56,23 @@ public: virtual int64_t fromUserValue(double dValue) const; virtual double toUserValue(int64_t iValue) const; - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; + + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); private: /** * _dLogarithmBase characterizes the new logarithm logB(x) with * the following property: logB(x) = log(x) / log(_dLogarithmBase). * log being the base-e logarithm. + * + * std::exp(1) == e^1 == e == natural logarithm base + * Make sure there is no precision lose by using std::exp overload that + * return the same type as _dLogarithmBase */ - double _dLogarithmBase; + double _dLogarithmBase{std::exp(decltype(_dLogarithmBase){1})}; /** * _dFloorValue reflects the lower bound for volume attenuation */ - double _dFloorValue; + double _dFloorValue{-std::numeric_limits<double>::infinity()}; }; diff --git a/remote-processor/ListeningSocket.h b/parameter/LoggingElementBuilderTemplate.cpp index 3b5b614..8c87a47 100644 --- a/remote-processor/ListeningSocket.h +++ b/parameter/LoggingElementBuilderTemplate.cpp @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2015, Intel Corporation +/* + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,19 +27,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma once -#include "Socket.h" +#include "LoggingElementBuilderTemplate.h" +#include <XmlElement.h> -class CListeningSocket : public CSocket +namespace details { -public: - CListeningSocket(); - - // Listen - bool listen(uint16_t uiPort, std::string &strError); - - // Accept - CSocket* accept(); -}; - +std::string getName(const CXmlElement &xmlElement) +{ + return xmlElement.getNameAttribute(); +} +} diff --git a/parameter/LoggingElementBuilderTemplate.h b/parameter/LoggingElementBuilderTemplate.h new file mode 100644 index 0000000..1bfff06 --- /dev/null +++ b/parameter/LoggingElementBuilderTemplate.h @@ -0,0 +1,96 @@ +/* + * 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. + */ +#pragma once + +#include <parameter_export.h> + +#include "ElementBuilder.h" +#include <log/Logger.h> + +namespace details +{ +/** Part of the implementation of `TLoggingElementBuilderTemplate` + * that does not need to be template. + * + * If this was implemented in this header, the xmlElement implementation + * would leak to sources including this header. + * + * Plugins are including this header. As a result they would include + * the xmlElement implementation if it was not hidden in a cpp. + * + * FIXME: The xml concept (forward declared) is still leaked to the plugin. + * A solution would be have two level of builders: + * - a PluginBuilder that wraps the plugin + * - and an ElementBuilder that wraps the PluginBuilder + * This way the plugin can only see the PluginBuilder and is not + * contaminated by any core specific concept. + * + * @param[in] xmlElement the XML element + * @return the "Name" attribute value of an xml element or + * empty string if attribute is not present + * + */ +std::string PARAMETER_EXPORT getName(const CXmlElement &xmlElement); +} + +/** + * Builder for elements which need logger at construction + * + * @tparam ElementType the type of the element to build + */ +template <class ElementType> +class TLoggingElementBuilderTemplate : public CElementBuilder +{ +public: + /** + * Class Constructor + * + * @param[in] logger the logger provided by the client + */ + TLoggingElementBuilderTemplate(core::log::Logger &logger) : CElementBuilder(), mLogger(logger) + { + } + + /** + * Create a new element + * + * @param[in] xmlElement the description of the object to create + * + * @return pointer to the generated element + */ + virtual CElement *createElement(const CXmlElement &xmlElement) const + { + return new ElementType(details::getName(xmlElement), mLogger); + } + +private: + /** Application Logger */ + core::log::Logger &mLogger; +}; diff --git a/parameter/Mapper.h b/parameter/Mapper.h index fcf751a..d2d76d0 100644 --- a/parameter/Mapper.h +++ b/parameter/Mapper.h @@ -36,9 +36,10 @@ class CInstanceConfigurableElement; class IMapper { public: - virtual bool mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, std::string& strError) = 0; + virtual bool mapBegin(CInstanceConfigurableElement *pInstanceConfigurableElement, + bool &bKeepDiving, std::string &strError) = 0; virtual void mapEnd() = 0; protected: - virtual ~IMapper() {} + virtual ~IMapper() = default; }; diff --git a/parameter/MappingContext.cpp b/parameter/MappingContext.cpp index 045fbd7..1235e31 100644 --- a/parameter/MappingContext.cpp +++ b/parameter/MappingContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -28,113 +28,53 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "MappingContext.h" -#include <assert.h> -#include <string.h> -#include <stdlib.h> +#include <cassert> +#include <algorithm> +#include <cstdlib> using std::string; -CMappingContext::CMappingContext(size_t uiNbItemTypes) : _pstItemArray(new CMappingContext::SItem[uiNbItemTypes]), _uiNbItemTypes(uiNbItemTypes) -{ - // Clear items - memset(_pstItemArray, 0, sizeof(*_pstItemArray) * uiNbItemTypes); -} - -CMappingContext::~CMappingContext() -{ - delete [] _pstItemArray; -} - -// Copy constructor -CMappingContext::CMappingContext(const CMappingContext& from) : _pstItemArray(new CMappingContext::SItem[from._uiNbItemTypes]), _uiNbItemTypes(from._uiNbItemTypes) -{ - // Copy content items - memcpy(_pstItemArray, from._pstItemArray, sizeof(*_pstItemArray) * _uiNbItemTypes); -} - -// Affectation -CMappingContext& CMappingContext::operator=(const CMappingContext& right) -{ - if (&right != this) { - - // Size - _uiNbItemTypes = right._uiNbItemTypes; - - // Content - // Delete previous array - delete [] _pstItemArray; - - // Reallocate it - _pstItemArray = new CMappingContext::SItem[_uiNbItemTypes]; - - // Copy content items - memcpy(_pstItemArray, right._pstItemArray, sizeof(*_pstItemArray) * _uiNbItemTypes); - } - return *this; -} - // Item access -bool CMappingContext::setItem(uint32_t uiItemType, const string* pStrKey, const string* pStrItem) +bool CMappingContext::setItem(size_t itemType, const string *pStrKey, const string *pStrItem) { - size_t uiIndex; - - // Do some checks - for (uiIndex = 0; uiIndex < _uiNbItemTypes; uiIndex++) { - - // Does key already exist ? - assert(_pstItemArray[uiIndex].strKey != pStrKey); - } - - if (_pstItemArray[uiItemType].bSet) { - + if (iSet(itemType)) { // Already set! return false; } // Set item key - _pstItemArray[uiItemType].strKey = pStrKey; + mItems[itemType].strKey = pStrKey; // Set item value - _pstItemArray[uiItemType].strItem = pStrItem; - - // Now is set - _pstItemArray[uiItemType].bSet = true; + mItems[itemType].strItem = pStrItem; return true; } -const string& CMappingContext::getItem(uint32_t uiItemType) const +const string &CMappingContext::getItem(size_t itemType) const { - return *_pstItemArray[uiItemType].strItem; + return *mItems[itemType].strItem; } -uint32_t CMappingContext::getItemAsInteger(uint32_t uiItemType) const +size_t CMappingContext::getItemAsInteger(size_t itemType) const { - if (!_pstItemArray[uiItemType].strItem) { + if (!mItems[itemType].strItem) { return 0; } - return strtoul(_pstItemArray[uiItemType].strItem->c_str(), NULL, 0); + return strtoul(mItems[itemType].strItem->c_str(), NULL, 0); } -const string* CMappingContext::getItem(const string& strKey) const +const string *CMappingContext::getItem(const string &strKey) const { - size_t uiItemType; - - for (uiItemType = 0; uiItemType < _uiNbItemTypes; uiItemType++) { - - if (_pstItemArray[uiItemType].strKey != NULL && - strKey == *_pstItemArray[uiItemType].strKey) { - - return _pstItemArray[uiItemType].strItem; - } - } - - return NULL; + auto itemFound = find_if(begin(mItems), end(mItems), [&](const SItem &item) { + return item.strKey != NULL && strKey == *item.strKey; + }); + return (itemFound != end(mItems)) ? itemFound->strKey : NULL; } -bool CMappingContext::iSet(uint32_t uiItemType) const +bool CMappingContext::iSet(size_t itemType) const { - return _pstItemArray[uiItemType].bSet; + return mItems[itemType].strItem != nullptr; } diff --git a/parameter/MappingContext.h b/parameter/MappingContext.h index 91fd1f4..03b3317 100644 --- a/parameter/MappingContext.h +++ b/parameter/MappingContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,42 +29,38 @@ */ #pragma once +#include "parameter_export.h" + #include <stdint.h> #include <string> +#include <vector> -class CMappingContext +class PARAMETER_EXPORT CMappingContext { +private: // Item structure - struct SItem { - const std::string* strKey; - const std::string* strItem; - bool bSet; + struct SItem + { + const std::string *strKey{nullptr}; + const std::string *strItem{nullptr}; }; public: - // Regular Constructor - CMappingContext(size_t uiNbItemTypes); - ~CMappingContext(); - - // Copy constructor - CMappingContext(const CMappingContext& from); - - // Affectation - CMappingContext& operator=(const CMappingContext& right); + CMappingContext(size_t uiNbItemTypes) : mItems(uiNbItemTypes) {} // Item access /** * Set context mapping item key and value. * - * @param[in] uiItemType Mapping item index. + * @param[in] itemType Mapping item index. * @param[in] pStrKey Mapping item key name. * @param[in] pStrItem Mapping item value. * * @return False if already set, true else. */ - bool setItem(uint32_t uiItemType, const std::string* pStrKey, const std::string* pStrItem); - const std::string& getItem(uint32_t uiItemType) const; - uint32_t getItemAsInteger(uint32_t uiItemType) const; + bool setItem(size_t itemType, const std::string *pStrKey, const std::string *pStrItem); + const std::string &getItem(size_t itemType) const; + size_t getItemAsInteger(size_t itemType) const; /** * Get mapping item value from its key name. * @@ -72,13 +68,12 @@ public: * * @return Mapping item value pointer if found, NULL else. */ - const std::string* getItem(const std::string& strKey) const; - bool iSet(uint32_t uiItemType) const; + const std::string *getItem(const std::string &strKey) const; + bool iSet(size_t itemType) const; private: - // Item array - SItem* _pstItemArray; - // Items array size - size_t _uiNbItemTypes; -}; + size_t getNbItems() const { return mItems.size(); } + using Items = std::vector<SItem>; + Items mItems; +}; diff --git a/parameter/MappingData.cpp b/parameter/MappingData.cpp index b7a1a2a..cc34103 100644 --- a/parameter/MappingData.cpp +++ b/parameter/MappingData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -32,21 +32,13 @@ #include "Utility.h" #include <assert.h> -CMappingData::CMappingData() +bool CMappingData::init(const std::string &rawMapping, std::string &error) { -} - -bool CMappingData::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) -{ - assert(xmlElement.hasAttribute("Mapping")); - - std::string strMapping = xmlElement.getAttributeString("Mapping"); - - Tokenizer mappingTok(strMapping, ","); + Tokenizer mappingTok(rawMapping, ","); std::string strMappingElement; - while (!(strMappingElement = mappingTok.next()).empty()) { + for (const auto &strMappingElement : mappingTok.split()) { std::string::size_type iFistDelimiterOccurrence = strMappingElement.find_first_of(':'); @@ -66,12 +58,12 @@ bool CMappingData::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext // Get mapping value strValue = strMappingElement.substr(iFistDelimiterOccurrence + 1); - } if (!addValue(strKey, strValue)) { - serializingContext.setError("Duplicate Mapping data: Unable to process Mapping element key = " + strKey + ", value = " + strValue + " from XML element " + xmlElement.getPath()); + error = "Unable to process Mapping element key = " + strKey + ", value = " + strValue + + ": Duplicate Mapping data"; return false; } @@ -79,7 +71,7 @@ bool CMappingData::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext return true; } -bool CMappingData::getValue(const std::string& strkey, const std::string*& pStrValue) const +bool CMappingData::getValue(const std::string &strkey, const std::string *&pStrValue) const { KeyToValueMapConstIterator it = _keyToValueMap.find(strkey); @@ -94,14 +86,10 @@ bool CMappingData::getValue(const std::string& strkey, const std::string*& pStrV std::string CMappingData::asString() const { - std::string strValue; - - CUtility::asString(_keyToValueMap, strValue, ", ", ":"); - - return strValue; + return utility::asString(_keyToValueMap, ", ", ":"); } -bool CMappingData::addValue(const std::string& strkey, const std::string& strValue) +bool CMappingData::addValue(const std::string &strkey, const std::string &strValue) { if (_keyToValueMap.find(strkey) != _keyToValueMap.end()) { @@ -111,4 +99,3 @@ bool CMappingData::addValue(const std::string& strkey, const std::string& strVal return true; } - diff --git a/parameter/MappingData.h b/parameter/MappingData.h index 45908b6..bd76b79 100644 --- a/parameter/MappingData.h +++ b/parameter/MappingData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,21 +29,25 @@ */ #pragma once -#include "XmlSink.h" #include <string> #include <map> -class CMappingData : public IXmlSink +class CMappingData { typedef std::map<std::string, std::string>::const_iterator KeyToValueMapConstIterator; -public: - CMappingData(); - // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); +public: + /** Initialize mapping data through a raw value + * + * @param[in] rawMapping the raw mapping data which has to be parsed. + * This raw value is a succession of pair "key:value" separated with comma. + * @param[out] error description of the error if there is one, empty otherwise + * @return true on success, false otherwise + */ + bool init(const std::string &rawMapping, std::string &error); // Query - bool getValue(const std::string& strkey, const std::string*& pStrValue) const; + bool getValue(const std::string &strkey, const std::string *&pStrValue) const; /** * Formats the mapping as a list of comma-space separated key:value pairs @@ -53,7 +57,7 @@ public: std::string asString() const; private: - bool addValue(const std::string& strkey, const std::string& strValue); + bool addValue(const std::string &strkey, const std::string &strValue); std::map<std::string, std::string> _keyToValueMap; }; diff --git a/parameter/NamedElementBuilderTemplate.h b/parameter/NamedElementBuilderTemplate.h index 1334452..8c22956 100644 --- a/parameter/NamedElementBuilderTemplate.h +++ b/parameter/NamedElementBuilderTemplate.h @@ -35,9 +35,7 @@ template <class ElementType> class TNamedElementBuilderTemplate : public CElementBuilder { public: - TNamedElementBuilderTemplate() : CElementBuilder() {} - - virtual CElement* createElement(const CXmlElement& xmlElement) const + virtual CElement *createElement(const CXmlElement &xmlElement) const { return new ElementType(xmlElement.getNameAttribute()); } diff --git a/parameter/Parameter.cpp b/parameter/Parameter.cpp index e7de9ed..ca1d5ef 100644 --- a/parameter/Parameter.cpp +++ b/parameter/Parameter.cpp @@ -37,7 +37,8 @@ using std::string; -CParameter::CParameter(const string& strName, const CTypeElement* pTypeElement) : base(strName, pTypeElement) +CParameter::CParameter(const string &strName, const CTypeElement *pTypeElement) + : base(strName, pTypeElement) { } @@ -47,85 +48,99 @@ CInstanceConfigurableElement::Type CParameter::getType() const } // XML configuration settings parsing/composing -bool CParameter::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const +bool CParameter::serializeXmlSettings(CXmlElement &xmlConfigurationSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) const { // Check for value space handleValueSpaceAttribute(xmlConfigurationSettingsElementContent, configurationAccessContext); // Base - return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, configurationAccessContext); + return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, + configurationAccessContext); } // Value space handling for configuration import -void CParameter::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const +void CParameter::handleValueSpaceAttribute( + CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const { // Delegate to type - static_cast<const CParameterType*>(getTypeElement())->handleValueSpaceAttribute(xmlConfigurableElementSettingsElement, configurationAccessContext); + static_cast<const CParameterType *>(getTypeElement()) + ->handleValueSpaceAttribute(xmlConfigurableElementSettingsElement, + configurationAccessContext); } -uint32_t CParameter::getFootPrint() const +size_t CParameter::getFootPrint() const { return getSize(); } -uint32_t CParameter::getSize() const +size_t CParameter::getSize() const { - return static_cast<const CParameterType*>(getTypeElement())->getSize(); + return static_cast<const CParameterType *>(getTypeElement())->getSize(); } // Used for simulation and virtual subsystems -void CParameter::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +void CParameter::setDefaultValues(CParameterAccessContext ¶meterAccessContext) const { // Get default value from type - uint32_t uiDefaultValue = static_cast<const CParameterType*>(getTypeElement())->getDefaultValue(); + uint32_t uiDefaultValue = + static_cast<const CParameterType *>(getTypeElement())->getDefaultValue(); // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->writeInteger(&uiDefaultValue, getSize(), getOffset() - parameterAccessContext.getBaseOffset(), parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->writeInteger(&uiDefaultValue, getSize(), + getOffset() - parameterAccessContext.getBaseOffset()); } /// Actual parameter access // String access -bool CParameter::doSetValue(const string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CParameter::doSetValue(const string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { - return doSet(strValue, uiOffset, parameterAccessContext); + return doSet(strValue, offset, parameterAccessContext); } -void CParameter::doGetValue(string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +void CParameter::doGetValue(string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { - doGet(strValue, uiOffset, parameterAccessContext); + doGet(strValue, offset, parameterAccessContext); } // Boolean access -bool CParameter::accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CParameter::access(bool &bValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return doAccess(bValue, bSet, parameterAccessContext); } // Integer Access -bool CParameter::accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CParameter::access(uint32_t &uiValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return doAccess(uiValue, bSet, parameterAccessContext); } // Signed Integer Access -bool CParameter::accessAsSignedInteger(int32_t& iValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CParameter::access(int32_t &iValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return doAccess(iValue, bSet, parameterAccessContext); } // Double Access -bool CParameter::accessAsDouble(double& dValue, bool bSet, CParameterAccessContext& parameterAccessContext) const +bool CParameter::access(double &dValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { return doAccess(dValue, bSet, parameterAccessContext); } // Generic Access template <typename type> -bool CParameter::doAccess(type& value, bool bSet, - CParameterAccessContext& parameterAccessContext) const +bool CParameter::doAccess(type &value, bool bSet, + CParameterAccessContext ¶meterAccessContext) const { if (bSet) { // set value @@ -134,10 +149,9 @@ bool CParameter::doAccess(type& value, bool bSet, appendParameterPathToError(parameterAccessContext); return false; - } // Synchronize - if (!sync(parameterAccessContext)){ + if (!sync(parameterAccessContext)) { appendParameterPathToError(parameterAccessContext); return false; @@ -155,33 +169,37 @@ bool CParameter::doAccess(type& value, bool bSet, } template <typename type> -bool CParameter::doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CParameter::doSet(type value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { uint32_t uiData; - if (!static_cast<const CParameterType*>(getTypeElement())->toBlackboard(value, uiData, parameterAccessContext)) { + if (!static_cast<const CParameterType *>(getTypeElement()) + ->toBlackboard(value, uiData, parameterAccessContext)) { return false; } // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->writeInteger(&uiData, getSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->writeInteger(&uiData, getSize(), offset); return true; } template <typename type> -bool CParameter::doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CParameter::doGet(type &value, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { uint32_t uiData = 0; // Read blackboard - const CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + const CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); // Beware this code works on little endian architectures only! - pBlackboard->readInteger(&uiData, getSize(), uiOffset, parameterAccessContext.isBigEndianSubsystem()); + pBlackboard->readInteger(&uiData, getSize(), offset); - return static_cast<const CParameterType*>(getTypeElement())->fromBlackboard(value, uiData, parameterAccessContext); + return static_cast<const CParameterType *>(getTypeElement()) + ->fromBlackboard(value, uiData, parameterAccessContext); } diff --git a/parameter/Parameter.h b/parameter/Parameter.h index 8cf4bc5..2c97409 100644 --- a/parameter/Parameter.h +++ b/parameter/Parameter.h @@ -38,47 +38,58 @@ class CParameter : public CBaseParameter { public: - CParameter(const std::string& strName, const CTypeElement* pTypeElement); + CParameter(const std::string &strName, const CTypeElement *pTypeElement); // Instantiation, allocation - virtual uint32_t getFootPrint() const; + virtual size_t getFootPrint() const; // Type virtual Type getType() const; // XML configuration settings parsing/composing - virtual bool serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const; + virtual bool serializeXmlSettings( + CXmlElement &xmlConfigurationSettingsElementContent, + CConfigurationAccessContext &configurationAccessContext) const; // Boolean access - virtual bool accessAsBoolean(bool& bValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool access(bool &bValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override; // Integer Access - virtual bool accessAsInteger(uint32_t& uiValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool access(uint32_t &uiValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override; // Signed Integer Access - virtual bool accessAsSignedInteger(int32_t& iValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool access(int32_t &iValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override; // Double Access - virtual bool accessAsDouble(double& dValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool access(double &dValue, bool bSet, + CParameterAccessContext ¶meterAccessContext) const override; + protected: // Used for simulation and virtual subsystems - virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const; + virtual void setDefaultValues(CParameterAccessContext ¶meterAccessContext) const; // Actual value access - virtual bool doSetValue(const std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; - virtual void doGetValue(std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + virtual bool doSetValue(const std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const; + virtual void doGetValue(std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const; // Value space handling for configuration import - void handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const; + void handleValueSpaceAttribute(CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const; // Size - uint32_t getSize() const; + size_t getSize() const; + private: // Generic Access template <typename type> - bool doAccess(type& value, bool bSet, CParameterAccessContext& parameterAccessContext) const; + bool doAccess(type &value, bool bSet, CParameterAccessContext ¶meterAccessContext) const; template <typename type> - bool doSet(type value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + bool doSet(type value, size_t offset, CParameterAccessContext ¶meterAccessContext) const; template <typename type> - bool doGet(type& value, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + bool doGet(type &value, size_t offset, CParameterAccessContext ¶meterAccessContext) const; }; diff --git a/parameter/ParameterAccessContext.cpp b/parameter/ParameterAccessContext.cpp index e228d9b..8895821 100644 --- a/parameter/ParameterAccessContext.cpp +++ b/parameter/ParameterAccessContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,54 +29,48 @@ */ #include "ParameterAccessContext.h" -#define base CErrorContext +#define base utility::ErrorContext -CParameterAccessContext::CParameterAccessContext(std::string& strError, - CParameterBlackboard* pParameterBlackboard, - bool bValueSpaceIsRaw, - bool bOutputRawFormatIsHex, - uint32_t uiBaseOffset) +CParameterAccessContext::CParameterAccessContext(std::string &strError, + CParameterBlackboard *pParameterBlackboard, + bool bValueSpaceIsRaw, bool bOutputRawFormatIsHex, + size_t baseOffset) : base(strError), _pParameterBlackboard(pParameterBlackboard), - _bValueSpaceIsRaw(bValueSpaceIsRaw), _bOutputRawFormatIsHex(bOutputRawFormatIsHex), - _bBigEndianSubsystem(false), _bAutoSync(true), _uiBaseOffset(uiBaseOffset) + _bValueSpaceIsRaw(bValueSpaceIsRaw), _bOutputRawFormatIsHex(bOutputRawFormatIsHex), + _uiBaseOffset(baseOffset) { } -CParameterAccessContext::CParameterAccessContext(std::string& strError, - bool bBigEndianSubsystem, - CParameterBlackboard* pParameterBlackboard, - uint32_t uiBaseOffset) - : base(strError), _pParameterBlackboard(pParameterBlackboard), _bValueSpaceIsRaw(false), - _bOutputRawFormatIsHex(false), _bBigEndianSubsystem(bBigEndianSubsystem), _bAutoSync(true), - _uiBaseOffset(uiBaseOffset) +CParameterAccessContext::CParameterAccessContext(std::string &strError, + CParameterBlackboard *pParameterBlackboard, + size_t baseOffset) + : base(strError), _pParameterBlackboard(pParameterBlackboard), _uiBaseOffset(baseOffset) { } -CParameterAccessContext::CParameterAccessContext(std::string& strError) - : base(strError), _pParameterBlackboard(NULL), _bValueSpaceIsRaw(false), - _bOutputRawFormatIsHex(false), _bBigEndianSubsystem(false), _bAutoSync(true), _uiBaseOffset(0) +CParameterAccessContext::CParameterAccessContext(std::string &strError) : base(strError) { } // ParameterBlackboard -CParameterBlackboard* CParameterAccessContext::getParameterBlackboard() +CParameterBlackboard *CParameterAccessContext::getParameterBlackboard() { return _pParameterBlackboard; } -void CParameterAccessContext::setParameterBlackboard(CParameterBlackboard* pBlackboard) +void CParameterAccessContext::setParameterBlackboard(CParameterBlackboard *pBlackboard) { _pParameterBlackboard = pBlackboard; _uiBaseOffset = 0; } // Base offset for blackboard access -void CParameterAccessContext::setBaseOffset(uint32_t uiBaseOffset) +void CParameterAccessContext::setBaseOffset(size_t baseOffset) { - _uiBaseOffset = uiBaseOffset; + _uiBaseOffset = baseOffset; } -uint32_t CParameterAccessContext::getBaseOffset() const +size_t CParameterAccessContext::getBaseOffset() const { return _uiBaseOffset; } @@ -103,17 +97,6 @@ bool CParameterAccessContext::outputRawFormatIsHex() const return _bOutputRawFormatIsHex; } -// Endianness -void CParameterAccessContext::setBigEndianSubsystem(bool bBigEndian) -{ - _bBigEndianSubsystem = bBigEndian; -} - -bool CParameterAccessContext::isBigEndianSubsystem() const -{ - return _bBigEndianSubsystem; -} - // Automatic synchronization to HW void CParameterAccessContext::setAutoSync(bool bAutoSync) { diff --git a/parameter/ParameterAccessContext.h b/parameter/ParameterAccessContext.h index 302f920..f3e013f 100644 --- a/parameter/ParameterAccessContext.h +++ b/parameter/ParameterAccessContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -30,33 +30,35 @@ #pragma once #include <stdint.h> -#include "ErrorContext.h" +#include "ErrorContext.hpp" #include <string> class CParameterBlackboard; -class CParameterAccessContext : public CErrorContext +class CParameterAccessContext : public utility::ErrorContext { public: - CParameterAccessContext(std::string& strError, - CParameterBlackboard* pParameterBlackboard, - bool bValueSpaceIsRaw, - bool bOutputRawFormatIsHex = false, - uint32_t uiOffsetBase = 0); - CParameterAccessContext(std::string& strError, - bool bBigEndianSubsystem, - CParameterBlackboard* pParameterBlackboard, - uint32_t uiOffsetBase = 0); - CParameterAccessContext(std::string& strError); + CParameterAccessContext(std::string &strError, CParameterBlackboard *pParameterBlackboard, + bool bValueSpaceIsRaw, bool bOutputRawFormatIsHex, + size_t offsetBase = 0); + CParameterAccessContext(std::string &strError, CParameterBlackboard *pParameterBlackboard, + size_t offsetBase = 0); + CParameterAccessContext(std::string &strError); + virtual ~CParameterAccessContext() = default; // ParameterBlackboard - CParameterBlackboard* getParameterBlackboard(); - void setParameterBlackboard(CParameterBlackboard* pBlackboard); + CParameterBlackboard *getParameterBlackboard(); + void setParameterBlackboard(CParameterBlackboard *pBlackboard); // Value interpretation as Real or Raw void setValueSpaceRaw(bool bIsRaw); bool valueSpaceIsRaw() const; + /** @return true if setting serialization is requested, + * false if structure serialization + */ + virtual bool serializeSettings() const { return false; } + /** * Assigns Output Raw Format for user get value interpretation. * @@ -72,30 +74,23 @@ public: */ bool outputRawFormatIsHex() const; - // Endianness - void setBigEndianSubsystem(bool bBigEndian); - bool isBigEndianSubsystem() const; - // Automatic synchronization to HW void setAutoSync(bool bAutoSync); bool getAutoSync() const; // Base offset for blackboard access - void setBaseOffset(uint32_t uiBaseOffset); - uint32_t getBaseOffset() const; + void setBaseOffset(size_t baseOffset); + size_t getBaseOffset() const; private: // Blackboard - CParameterBlackboard* _pParameterBlackboard; + CParameterBlackboard *_pParameterBlackboard{nullptr}; // Value space - bool _bValueSpaceIsRaw; + bool _bValueSpaceIsRaw{false}; // Output Raw Format - bool _bOutputRawFormatIsHex; - // Subsystem Endianness - bool _bBigEndianSubsystem; + bool _bOutputRawFormatIsHex{false}; // Automatic synchronization to HW - bool _bAutoSync; + bool _bAutoSync{true}; // Base offset where parameters are stored in configuration blackboards - uint32_t _uiBaseOffset; + size_t _uiBaseOffset{0}; }; - diff --git a/parameter/ParameterAdaptation.cpp b/parameter/ParameterAdaptation.cpp index 99955f1..67b4bca 100644 --- a/parameter/ParameterAdaptation.cpp +++ b/parameter/ParameterAdaptation.cpp @@ -28,13 +28,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ParameterAdaptation.h" -#include "Utility.h" #define base CElement using std::string; -CParameterAdaptation::CParameterAdaptation(const string& strType) : base(strType), _iOffset(0) +CParameterAdaptation::CParameterAdaptation(const string &strType) : base(strType) { } // CElement @@ -50,7 +49,7 @@ int32_t CParameterAdaptation::getOffset() const } // Element properties -void CParameterAdaptation::showProperties(string& strResult) const +void CParameterAdaptation::showProperties(string &strResult) const { // Adaptation type strResult += " - Type: "; @@ -59,22 +58,15 @@ void CParameterAdaptation::showProperties(string& strResult) const // Offset strResult += " - Offset: "; - strResult += CUtility::toString(_iOffset); + strResult += std::to_string(_iOffset); strResult += "\n"; } // From IXmlSink -bool CParameterAdaptation::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CParameterAdaptation::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { - // Get offset - if (xmlElement.hasAttribute("Offset")) { - - _iOffset = xmlElement.getAttributeSignedInteger("Offset"); - - } else { - // Default - _iOffset = 0; - } + xmlElement.getAttribute("Offset", _iOffset); // Base return base::fromXml(xmlElement, serializingContext); diff --git a/parameter/ParameterAdaptation.h b/parameter/ParameterAdaptation.h index 89daee5..d9cbe4b 100644 --- a/parameter/ParameterAdaptation.h +++ b/parameter/ParameterAdaptation.h @@ -36,13 +36,13 @@ class CParameterAdaptation : public CElement { public: - CParameterAdaptation(const std::string& strType); + CParameterAdaptation(const std::string &strType); // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // Conversions virtual int64_t fromUserValue(double dValue) const; @@ -50,12 +50,12 @@ public: // CElement virtual std::string getKind() const; + protected: // Attributes int32_t getOffset() const; private: // Offset - int32_t _iOffset; + int32_t _iOffset{0}; }; - diff --git a/parameter/ParameterBlackboard.cpp b/parameter/ParameterBlackboard.cpp index 6001c77..eaa6b97 100644 --- a/parameter/ParameterBlackboard.cpp +++ b/parameter/ParameterBlackboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -28,112 +28,112 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ParameterBlackboard.h" -#include <string.h> -#include <assert.h> - -CParameterBlackboard::CParameterBlackboard() : _pucData(NULL), _uiSize(0) -{ -} - -CParameterBlackboard::~CParameterBlackboard() -{ - delete [] _pucData; -} +#include "Iterator.hpp" +#include "AlwaysAssert.hpp" +#include <algorithm> // Size -void CParameterBlackboard::setSize(uint32_t uiSize) +void CParameterBlackboard::setSize(size_t size) { - if (_pucData) { - - delete [] _pucData; - } - - _pucData = new uint8_t[uiSize]; - - memset(_pucData, 0, uiSize); - - _uiSize = uiSize; + mBlackboard.resize(size); } -uint32_t CParameterBlackboard::getSize() const +size_t CParameterBlackboard::getSize() const { - return _uiSize; + return mBlackboard.size(); } // Single parameter access -void CParameterBlackboard::writeInteger(const void* pvSrcData, uint32_t uiSize, uint32_t uiOffset, bool bBigEndian) +void CParameterBlackboard::writeInteger(const void *pvSrcData, size_t size, size_t offset) { - assert(uiSize + uiOffset <= _uiSize); + assertValidAccess(offset, size); - if (!bBigEndian) { + auto first = MAKE_ARRAY_ITERATOR(static_cast<const uint8_t *>(pvSrcData), size); + auto last = first + size; + auto dest_first = atOffset(offset); - memcpy(_pucData + uiOffset, pvSrcData, uiSize); - } else { + std::copy(first, last, dest_first); +} - uint32_t uiIndex; - const uint8_t* puiSrcData = (const uint8_t*)pvSrcData; +void CParameterBlackboard::readInteger(void *pvDstData, size_t size, size_t offset) const +{ + assertValidAccess(offset, size); - for (uiIndex = 0; uiIndex < uiSize; uiIndex++) { + auto first = atOffset(offset); + auto last = first + size; + auto dest_first = MAKE_ARRAY_ITERATOR(static_cast<uint8_t *>(pvDstData), size); - _pucData[uiIndex + uiOffset] = puiSrcData[uiSize - uiIndex - 1]; - } - } + std::copy(first, last, dest_first); } -void CParameterBlackboard::readInteger(void* pvDstData, uint32_t uiSize, uint32_t uiOffset, bool bBigEndian) const +void CParameterBlackboard::writeString(const std::string &input, size_t offset) { - assert(uiSize + uiOffset <= _uiSize); + assertValidAccess(offset, input.size() + 1); - if (!bBigEndian) { - - memcpy(pvDstData, _pucData + uiOffset, uiSize); - } else { + auto dest_last = std::copy(begin(input), end(input), atOffset(offset)); + *dest_last = '\0'; +} - uint32_t uiIndex; - uint8_t* puiDstData = (uint8_t*)pvDstData; +void CParameterBlackboard::readString(std::string &output, size_t offset) const +{ + // As the string is null terminated in the blackboard, + // the size that will be read is not known. (>= 1) + assertValidAccess(offset, sizeof('\0')); - for (uiIndex = 0; uiIndex < uiSize; uiIndex++) { + // Get the pointer to the null terminated string + const uint8_t *first = &mBlackboard[offset]; + output = reinterpret_cast<const char *>(first); +} - puiDstData[uiSize - uiIndex - 1] = _pucData[uiIndex + uiOffset]; - } - } +void CParameterBlackboard::writeBuffer(const void *pvSrcData, size_t size, size_t offset) +{ + writeInteger(pvSrcData, size, offset); +} +void CParameterBlackboard::readBuffer(void *pvDstData, size_t size, size_t offset) const +{ + readInteger(pvDstData, size, offset); } -void CParameterBlackboard::writeString(const std::string &input, uint32_t uiOffset) +// Element access +void CParameterBlackboard::writeBytes(const std::vector<uint8_t> &bytes, size_t offset) { - strcpy((char*)_pucData + uiOffset, input.c_str()); + assertValidAccess(offset, bytes.size()); + + std::copy(begin(bytes), end(bytes), atOffset(offset)); } -void CParameterBlackboard::readString(std::string &output, uint32_t uiOffset) const +void CParameterBlackboard::readBytes(std::vector<uint8_t> &bytes, size_t offset) const { - output = std::string((const char*)_pucData + uiOffset); + assertValidAccess(offset, bytes.size()); + + std::copy_n(atOffset(offset), bytes.size(), begin(bytes)); } // Access from/to subsystems -uint8_t* CParameterBlackboard::getLocation(uint32_t uiOffset) +uint8_t *CParameterBlackboard::getLocation(size_t offset) { - return _pucData + uiOffset; + assertValidAccess(offset, 1); + return &mBlackboard[offset]; } // Configuration handling -void CParameterBlackboard::restoreFrom(const CParameterBlackboard* pFromBlackboard, uint32_t uiOffset) +void CParameterBlackboard::restoreFrom(const CParameterBlackboard *pFromBlackboard, size_t offset) { - memcpy(_pucData + uiOffset, pFromBlackboard->_pucData, pFromBlackboard->_uiSize); + const auto &fromBB = pFromBlackboard->mBlackboard; + assertValidAccess(offset, fromBB.size()); + std::copy(begin(fromBB), end(fromBB), atOffset(offset)); } -void CParameterBlackboard::saveTo(CParameterBlackboard* pToBlackboard, uint32_t uiOffset) const +void CParameterBlackboard::saveTo(CParameterBlackboard *pToBlackboard, size_t offset) const { - memcpy(pToBlackboard->_pucData, _pucData + uiOffset, pToBlackboard->_uiSize); + auto &toBB = pToBlackboard->mBlackboard; + assertValidAccess(offset, toBB.size()); + std::copy_n(atOffset(offset), toBB.size(), begin(toBB)); } -// Serialization -void CParameterBlackboard::serialize(CBinaryStream& binaryStream) +void CParameterBlackboard::assertValidAccess(size_t offset, size_t size) const { - if (binaryStream.isOut()) { - - binaryStream.write(_pucData, _uiSize); - } else { - - binaryStream.read(_pucData, _uiSize); - } + ALWAYS_ASSERT(offset + size <= getSize(), + "Invalid data size access: offset=" << offset << " size=" << size + << "reference size=" << getSize()); } diff --git a/parameter/ParameterBlackboard.h b/parameter/ParameterBlackboard.h index bd48cc4..979e199 100644 --- a/parameter/ParameterBlackboard.h +++ b/parameter/ParameterBlackboard.h @@ -29,40 +29,72 @@ */ #pragma once -#include <stdint.h> -#include "BinaryStream.h" +#include "NonCopyable.hpp" + +#include <cstdint> #include <string> +#include <vector> -class CParameterBlackboard +class CParameterBlackboard : private utility::NonCopyable { public: - CParameterBlackboard(); - ~CParameterBlackboard(); - // Size - void setSize(uint32_t uiSize); - uint32_t getSize() const; + void setSize(size_t size); + size_t getSize() const; // Single parameter access - void writeInteger(const void* pvSrcData, uint32_t uiSize, uint32_t uiOffset, bool bBigEndian); - void readInteger(void* pvDstData, uint32_t uiSize, uint32_t uiOffset, bool bBigEndian) const; - void writeString(const std::string &input, uint32_t uiOffset); - void readString(std::string &output, uint32_t uiOffset) const; + void writeInteger(const void *pvSrcData, size_t size, size_t offset); + void readInteger(void *pvDstData, size_t size, size_t offset) const; + + void writeString(const std::string &input, size_t offset); + void readString(std::string &output, size_t offset) const; + + void writeBuffer(const void *pvSrcData, size_t size, size_t offset); + void readBuffer(void *pvDstData, size_t size, size_t offset) const; + + /** + * Raw write the blackboard memory. + * + * May be used to write a configurable element's settings + * + * @param[in] bytes the source data bytes vector. + * @param[in] offset the destination offset in the blackboard. + * + * Notes: + * - This function asserts that the input vector's size + the offset + * does not exceed the size of the blackboard istelf. + */ + void writeBytes(const std::vector<uint8_t> &bytes, size_t offset); + + /** + * Raw read the blackboard memory. + * + * May be used to read a configurable element's settings + * + * @param[out] bytes the destination data bytes vector. + * @param[in] offset the source offset in the blackboard. + * + * Notes: + * - This function asserts that the output vector's size + the offset + * does not exceed the size of the blackboard itself. + * - The user MUST resize the output vector to exactly the number of + * elements to be read + */ + void readBytes(std::vector<uint8_t> &bytes, size_t offset) const; // Access from/to subsystems - uint8_t* getLocation(uint32_t uiOffset); + uint8_t *getLocation(size_t offset); // Configuration handling - void restoreFrom(const CParameterBlackboard* pFromBlackboard, uint32_t uiOffset); - void saveTo(CParameterBlackboard* pToBlackboard, uint32_t uiOffset) const; + void restoreFrom(const CParameterBlackboard *pFromBlackboard, size_t offset); + void saveTo(CParameterBlackboard *pToBlackboard, size_t offset) const; - // Serialization - void serialize(CBinaryStream& binaryStream); private: - CParameterBlackboard(const CParameterBlackboard&); - CParameterBlackboard& operator=(const CParameterBlackboard&); + void assertValidAccess(size_t offset, size_t size) const; - uint8_t* _pucData; - uint32_t _uiSize; -}; + using Blackboard = std::vector<uint8_t>; + Blackboard mBlackboard; + Blackboard::iterator atOffset(size_t offset) { return begin(mBlackboard) + offset; } + Blackboard::const_iterator atOffset(size_t offset) const { return begin(mBlackboard) + offset; } +}; diff --git a/parameter/ParameterBlock.h b/parameter/ParameterBlock.h index cf9407f..0ebfdbe 100644 --- a/parameter/ParameterBlock.h +++ b/parameter/ParameterBlock.h @@ -36,15 +36,11 @@ class CParameterBlock : public CInstanceConfigurableElement { public: - CParameterBlock(const std::string& strName, const CTypeElement* pTypeElement) + CParameterBlock(const std::string &strName, const CTypeElement *pTypeElement) : CInstanceConfigurableElement(strName, pTypeElement) { } // Type - virtual Type getType() const - { - return EParameterBlock; - } + virtual Type getType() const { return EParameterBlock; } }; - diff --git a/parameter/ParameterBlockType.cpp b/parameter/ParameterBlockType.cpp index ad94888..d72af81 100644 --- a/parameter/ParameterBlockType.cpp +++ b/parameter/ParameterBlockType.cpp @@ -33,7 +33,7 @@ #define base CTypeElement -CParameterBlockType::CParameterBlockType(const std::string& strName) : base(strName) +CParameterBlockType::CParameterBlockType(const std::string &strName) : base(strName) { } @@ -47,24 +47,22 @@ bool CParameterBlockType::childrenAreDynamic() const return true; } -CInstanceConfigurableElement* CParameterBlockType::doInstantiate() const +CInstanceConfigurableElement *CParameterBlockType::doInstantiate() const { return new CParameterBlock(getName(), this); } -void CParameterBlockType::populate(CElement* pElement) const +void CParameterBlockType::populate(CElement *pElement) const { - uint32_t uiArrayLength = getArrayLength(); + size_t arrayLength = getArrayLength(); - if (uiArrayLength) { + if (arrayLength) { // Create child elements - size_t uiChild; + for (size_t child = 0; child < arrayLength; child++) { - for (uiChild = 0; uiChild < uiArrayLength; uiChild++) { - - CParameterBlock* pChildParameterBlock = new CParameterBlock(CUtility::toString(uiChild), - this); + CParameterBlock *pChildParameterBlock = + new CParameterBlock(std::to_string(child), this); pElement->addChild(pChildParameterBlock); diff --git a/parameter/ParameterBlockType.h b/parameter/ParameterBlockType.h index 2137a3e..6d81ee8 100644 --- a/parameter/ParameterBlockType.h +++ b/parameter/ParameterBlockType.h @@ -36,17 +36,15 @@ class CParameterBlockType : public CTypeElement { public: - CParameterBlockType(const std::string& strName); + CParameterBlockType(const std::string &strName); // CElement virtual std::string getKind() const; + private: virtual bool childrenAreDynamic() const; // Instantiation - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; // Population - virtual void populate(CElement* pElement) const; - // Creating sub blocks with indexes - static std::string computeChildName(size_t uiChild); + virtual void populate(CElement *pElement) const; }; - diff --git a/parameter/ParameterFrameworkConfiguration.cpp b/parameter/ParameterFrameworkConfiguration.cpp index 3488454..bf735fd 100644 --- a/parameter/ParameterFrameworkConfiguration.cpp +++ b/parameter/ParameterFrameworkConfiguration.cpp @@ -31,11 +31,6 @@ #define base CElement -CParameterFrameworkConfiguration::CParameterFrameworkConfiguration() - : _bTuningAllowed(false), _uiServerPort(0) -{ -} - std::string CParameterFrameworkConfiguration::getKind() const { return "ParameterFrameworkConfiguration"; @@ -47,7 +42,7 @@ bool CParameterFrameworkConfiguration::childrenAreDynamic() const } // System class name -const std::string& CParameterFrameworkConfiguration::getSystemClassName() const +const std::string &CParameterFrameworkConfiguration::getSystemClassName() const { return _strSystemClassName; } @@ -65,16 +60,17 @@ uint16_t CParameterFrameworkConfiguration::getServerPort() const } // From IXmlSink -bool CParameterFrameworkConfiguration::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CParameterFrameworkConfiguration::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // System class name - _strSystemClassName = xmlElement.getAttributeString("SystemClassName"); + xmlElement.getAttribute("SystemClassName", _strSystemClassName); // Tuning allowed - _bTuningAllowed = xmlElement.getAttributeBoolean("TuningAllowed"); + xmlElement.getAttribute("TuningAllowed", _bTuningAllowed); // Server port - _uiServerPort = (uint16_t)xmlElement.getAttributeInteger("ServerPort"); + xmlElement.getAttribute("ServerPort", _uiServerPort); // Base return base::fromXml(xmlElement, serializingContext); diff --git a/parameter/ParameterFrameworkConfiguration.h b/parameter/ParameterFrameworkConfiguration.h index a261775..a94f7ef 100644 --- a/parameter/ParameterFrameworkConfiguration.h +++ b/parameter/ParameterFrameworkConfiguration.h @@ -36,10 +36,8 @@ class CParameterFrameworkConfiguration : public CElement { public: - CParameterFrameworkConfiguration(); - // System class name - const std::string& getSystemClassName() const; + const std::string &getSystemClassName() const; // Tuning allowed bool isTuningAllowed() const; @@ -48,7 +46,8 @@ public: uint16_t getServerPort() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); + private: virtual std::string getKind() const; virtual bool childrenAreDynamic() const; @@ -56,7 +55,7 @@ private: // System class name std::string _strSystemClassName; // Tuning allowed - bool _bTuningAllowed; + bool _bTuningAllowed{false}; // Server port - uint16_t _uiServerPort; + uint16_t _uiServerPort{0}; }; diff --git a/parameter/ParameterHandle.cpp b/parameter/ParameterHandle.cpp deleted file mode 100644 index 3bb6120..0000000 --- a/parameter/ParameterHandle.cpp +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright (c) 2011-2014, 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 "ParameterHandle.h" -#include "ParameterAccessContext.h" -#include "BaseParameter.h" -#include "Subsystem.h" -#include <assert.h> -#include "ParameterMgr.h" -#include "AutoLock.h" - -using std::string; - -CParameterHandle::CParameterHandle(const CBaseParameter* pParameter, CParameterMgr* pParameterMgr) - : _pBaseParameter(pParameter), _pParameterMgr(pParameterMgr), _bBigEndianSubsystem(pParameter->getBelongingSubsystem()->isBigEndian()) -{ -} - -// Parameter features -bool CParameterHandle::isRogue() const -{ - return _pBaseParameter->isRogue(); -} - -bool CParameterHandle::isArray() const -{ - return !_pBaseParameter->isScalar(); -} - -// Array Length -uint32_t CParameterHandle::getArrayLength() const -{ - return _pBaseParameter->getArrayLength(); -} - -// Parameter path -string CParameterHandle::getPath() const -{ - return _pBaseParameter->getPath(); -} - -// Parameter kind -string CParameterHandle::getKind() const -{ - return _pBaseParameter->getKind(); -} - -// Boolean access -bool CParameterHandle::setAsBoolean(bool bValue, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsBoolean(bValue, true, parameterAccessContext); -} - -bool CParameterHandle::getAsBoolean(bool& bValue, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsBoolean(bValue, false, parameterAccessContext); -} - -bool CParameterHandle::setAsBooleanArray(const std::vector<bool>& abValues, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, abValues.size(), strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - // Copy values for type adaptation - std::vector<bool> abUserValues = abValues; - - return _pBaseParameter->accessAsBooleanArray(abUserValues, true, parameterAccessContext); -} - -bool CParameterHandle::getAsBooleanArray(std::vector<bool>& abValues, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, -1, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsBooleanArray(abValues, false, parameterAccessContext); -} - -// Integer Access -bool CParameterHandle::setAsInteger(uint32_t uiValue, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsInteger(uiValue, true, parameterAccessContext); -} - -bool CParameterHandle::getAsInteger(uint32_t& uiValue, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsInteger(uiValue, false, parameterAccessContext); -} - -bool CParameterHandle::setAsIntegerArray(const std::vector<uint32_t>& auiValues, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, auiValues.size(), strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - // Copy values for type adaptation - std::vector<uint32_t> auiUserValues = auiValues; - - return _pBaseParameter->accessAsIntegerArray(auiUserValues, true, parameterAccessContext); -} - -bool CParameterHandle::getAsIntegerArray(std::vector<uint32_t>& auiValues, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, -1, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsIntegerArray(auiValues, false, parameterAccessContext); -} - -// Signed Integer Access -bool CParameterHandle::setAsSignedInteger(int32_t iValue, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsSignedInteger(iValue, true, parameterAccessContext); -} - -bool CParameterHandle::getAsSignedInteger(int32_t& iValue, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsSignedInteger(iValue, false, parameterAccessContext); -} - -bool CParameterHandle::setAsSignedIntegerArray(const std::vector<int32_t>& aiValues, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, aiValues.size(), strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - // Copy values for type adaptation - std::vector<int32_t> aiUserValues = aiValues; - - return _pBaseParameter->accessAsSignedIntegerArray(aiUserValues, true, parameterAccessContext); -} - -bool CParameterHandle::getAsSignedIntegerArray(std::vector<int32_t>& aiValues, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, -1, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsSignedIntegerArray(aiValues, false, parameterAccessContext); -} - -// Double Access -bool CParameterHandle::setAsDouble(double dValue, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsDouble(dValue, true, parameterAccessContext); -} - -bool CParameterHandle::getAsDouble(double& dValue, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsDouble(dValue, false, parameterAccessContext); -} - -bool CParameterHandle::setAsDoubleArray(const std::vector<double>& adValues, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, adValues.size(), strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - // Copy values for type adaptation - std::vector<double> adUserValues = adValues; - - return _pBaseParameter->accessAsDoubleArray(adUserValues, true, parameterAccessContext); -} - -bool CParameterHandle::getAsDoubleArray(std::vector<double>& adValues, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, -1, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsDoubleArray(adValues, false, parameterAccessContext); -} - -// String Access -bool CParameterHandle::setAsString(const string& strValue, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - // Copy value for type adaptation - string strUserValue = strValue; - - return _pBaseParameter->accessAsString(strUserValue, true, parameterAccessContext); -} - -bool CParameterHandle::getAsString(string& strValue, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, 0, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsString(strValue, false, parameterAccessContext); -} - -bool CParameterHandle::setAsStringArray(const std::vector<string>& astrValues, string& strError) -{ - // Check operation validity - if (!checkAccessValidity(true, (uint32_t)astrValues.size(), strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // When in tuning mode, silently skip the request - if (_pParameterMgr->tuningModeOn()) { - - return true; - } - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - // Copy values for type adaptation - std::vector<string> astrUserValues = astrValues; - - return _pBaseParameter->accessAsStringArray(astrUserValues, true, parameterAccessContext); -} - -bool CParameterHandle::getAsStringArray(std::vector<string>& astrValues, string& strError) const -{ - // Check operation validity - if (!checkAccessValidity(false, -1, strError)) { - - return false; - } - // Ensure we're safe against blackboard foreign access - CAutoLock autoLock(_pParameterMgr->getBlackboardMutex()); - - // Define access context - CParameterAccessContext parameterAccessContext(strError, _bBigEndianSubsystem, _pParameterMgr->getParameterBlackboard()); - - return _pBaseParameter->accessAsStringArray(astrValues, false, parameterAccessContext); -} - -// Access validity -bool CParameterHandle::checkAccessValidity(bool bSet, size_t uiArrayLength, string& strError) const -{ - if (bSet && !isRogue()) { - - strError = "Parameter is not rogue: "; - - strError += getPath(); - - return false; - } - - if (uiArrayLength && !isArray()) { - - strError = "Parameter is scalar: "; - - strError += getPath(); - - return false; - } - - if (!uiArrayLength && isArray()) { - - strError = "Parameter is an array: "; - - strError += getPath(); - - return false; - } - - if (bSet && uiArrayLength && (uiArrayLength != getArrayLength())) { - - strError = "Array length mismatch: "; - - strError += getPath(); - - return false; - } - - return true; -} diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp index b42c7de..f450563 100644 --- a/parameter/ParameterMgr.cpp +++ b/parameter/ParameterMgr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, Intel Corporation + * Copyright (c) 2011-2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,7 +27,9 @@ * (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 "version.h" #include "ParameterMgr.h" +#include "ConfigurationAccessContext.h" #include "XmlParameterSerializingContext.h" #include "XmlElementSerializingContext.h" #include "SystemClass.h" @@ -36,7 +38,6 @@ #include "NamedElementBuilderTemplate.h" #include "KindElementBuilderTemplate.h" #include "ElementBuilderTemplate.h" -#include "XmlFileIncluderElement.h" #include "SelectionCriterionType.h" #include "SubsystemElementBuilder.h" #include "FileIncluderElementBuilder.h" @@ -47,10 +48,10 @@ #include "BooleanParameterType.h" #include "IntegerParameterType.h" #include "FixedPointParameterType.h" +#include "FloatingPointParameterType.h" #include "ParameterBlackboard.h" #include "Parameter.h" #include "ParameterAccessContext.h" -#include "XmlFileIncluderElement.h" #include "ParameterFrameworkConfiguration.h" #include "FrameworkConfigurationGroup.h" #include "PluginLocation.h" @@ -66,17 +67,13 @@ #include "BitParameterType.h" #include "StringParameterType.h" #include "EnumParameterType.h" -#include "RemoteProcessorServerInterface.h" +#include "BackgroundRemoteProcessorServer.h" #include "ElementLocator.h" -#include "AutoLog.h" #include "CompoundRule.h" #include "SelectionCriterionRule.h" #include "SimulatedBackSynchronizer.h" #include "HardwareBackSynchronizer.h" -#include "AutoLock.h" -#include <strings.h> -#include <dlfcn.h> -#include <assert.h> +#include <cassert> #include "ParameterHandle.h" #include "LinearParameterAdaptation.h" #include "LogarithmicParameterAdaptation.h" @@ -88,21 +85,34 @@ #include "XmlMemoryDocSource.h" #include "SelectionCriteriaDefinition.h" #include "Utility.h" +#include "Memory.hpp" #include <sstream> #include <fstream> #include <algorithm> -#include <ctype.h> -#include <memory> +#include <stdexcept> +#include <mutex> +#include <iomanip> +#include "convert.hpp" #define base CElement +/** Private macro helper to declare a new context + * + * Context declaration always need logger and logging prefix to be + * passed as parameters. + * This macro aims to avoid this boring notation. + * This macro should be called only once in a scope. Nested scopes can + * call this macro too, as variable shadowing is supported. + */ +#define LOG_CONTEXT(contextTitle) core::log::Context context(_logger, contextTitle) + #ifdef SIMULATION - // In simulation, back synchronization of the blackboard won't probably work - // We need to ensure though the blackboard is initialized with valid data - typedef CSimulatedBackSynchronizer BackSynchronizer; +// In simulation, back synchronization of the blackboard won't probably work +// We need to ensure though the blackboard is initialized with valid data +typedef CSimulatedBackSynchronizer BackSynchronizer; #else - // Real back synchronizer from subsystems - typedef CHardwareBackSynchronizer BackSynchronizer; +// Real back synchronizer from subsystems +typedef CHardwareBackSynchronizer BackSynchronizer; #endif using std::string; @@ -111,18 +121,20 @@ using std::vector; using std::ostringstream; using std::ofstream; using std::ifstream; +using std::mutex; +using std::lock_guard; -// Used for remote processor server creation -typedef IRemoteProcessorServerInterface* (*CreateRemoteProcessorServer)(uint16_t uiPort, IRemoteCommandHandler* pCommandHandler); +// FIXME: integrate ParameterMgr to core namespace +using namespace core; -// Global configuration file name (fixed) -const char* gacParameterFrameworkConfigurationFileName = "ParameterFrameworkConfiguration.xml"; -const char* gacSystemSchemasSubFolder = "Schemas"; +// Used for remote processor server creation +typedef IRemoteProcessorServerInterface *(*CreateRemoteProcessorServer)( + uint16_t uiPort, IRemoteCommandHandler *pCommandHandler); // Config File System looks normally like this: // --------------------------------------------- //|-- <ParameterFrameworkConfiguration>.xml -//|-- Schemas +//|-- schemas //| `-- *.xsd //|-- Settings //| `-- <SystemClassName folder>* @@ -134,269 +146,201 @@ const char* gacSystemSchemasSubFolder = "Schemas"; // `-- <Subsystem>.xml* // -------------------------------------------- - // Remote command parser array const CParameterMgr::SRemoteCommandParserItem CParameterMgr::gastRemoteCommandParserItems[] = { /// Version - { "version", &CParameterMgr::versionCommandProcess, 0, - "", "Show version" }, + {"version", &CParameterMgr::versionCommandProcess, 0, "", "Show version"}, /// Status - { "status", &CParameterMgr::statusCommandProcess, 0, "", - "Show current status" }, + {"status", &CParameterMgr::statusCommandProcess, 0, "", "Show current status"}, /// Tuning Mode - { "setTuningMode", &CParameterMgr::setTuningModeCommandProcess, 1, - "on|off*", "Turn on or off Tuning Mode" }, - { "getTuningMode", &CParameterMgr::getTuningModeCommandProcess, 0, - "", "Show Tuning Mode" }, + {"setTuningMode", &CParameterMgr::setTuningModeCommandProcess, 1, "on|off*", + "Turn on or off Tuning Mode"}, + {"getTuningMode", &CParameterMgr::getTuningModeCommandProcess, 0, "", "Show Tuning Mode"}, /// Value Space - { "setValueSpace", &CParameterMgr::setValueSpaceCommandProcess, 1, - "raw|real*", "Assigns Value Space used for parameter value interpretation" }, - { "getValueSpace", &CParameterMgr::getValueSpaceCommandProcess, 0, - "", "Show Value Space" }, + {"setValueSpace", &CParameterMgr::setValueSpaceCommandProcess, 1, "raw|real*", + "Assigns Value Space used for parameter value interpretation"}, + {"getValueSpace", &CParameterMgr::getValueSpaceCommandProcess, 0, "", "Show Value Space"}, /// Output Raw Format - { "setOutputRawFormat", &CParameterMgr::setOutputRawFormatCommandProcess, 1, - "dec*|hex", "Assigns format used to output parameter values when in raw Value Space" }, - { "getOutputRawFormat", &CParameterMgr::getOutputRawFormatCommandProcess, 0, - "", "Show Output Raw Format" }, + {"setOutputRawFormat", &CParameterMgr::setOutputRawFormatCommandProcess, 1, "dec*|hex", + "Assigns format used to output parameter values when in raw Value Space"}, + {"getOutputRawFormat", &CParameterMgr::getOutputRawFormatCommandProcess, 0, "", + "Show Output Raw Format"}, /// Sync - { "setAutoSync", &CParameterMgr::setAutoSyncCommandProcess, 1, - "on*|off", "Turn on or off automatic synchronization to hardware while in Tuning Mode" }, - { "getAutoSync", &CParameterMgr::getAutoSyncCommandProcess, 0, - "", "Show Auto Sync state" }, - { "sync", &CParameterMgr::syncCommandProcess, 0, - "", "Synchronize current settings to hardware while in Tuning Mode and Auto Sync off" }, + {"setAutoSync", &CParameterMgr::setAutoSyncCommandProcess, 1, "on*|off", + "Turn on or off automatic synchronization to hardware while in Tuning Mode"}, + {"getAutoSync", &CParameterMgr::getAutoSyncCommandProcess, 0, "", "Show Auto Sync state"}, + {"sync", &CParameterMgr::syncCommandProcess, 0, "", + "Synchronize current settings to hardware while in Tuning Mode and Auto Sync off"}, /// Criteria - { "listCriteria", &CParameterMgr::listCriteriaCommandProcess, 0, - "[CSV|XML]", "List selection criteria" }, + {"listCriteria", &CParameterMgr::listCriteriaCommandProcess, 0, "[CSV|XML]", + "List selection criteria"}, /// Domains - { "listDomains", &CParameterMgr::listDomainsCommandProcess, 0, - "", "List configurable domains" }, - { "dumpDomains", &CParameterMgr::dumpDomainsCommandProcess, 0, - "", "Show all domains and configurations, including applicability conditions" }, - { "createDomain", &CParameterMgr::createDomainCommandProcess, 1, - "<domain>", "Create new configurable domain" }, - { "deleteDomain", &CParameterMgr::deleteDomainCommandProcess, 1, - "<domain>", "Delete configurable domain" }, - { "deleteAllDomains", &CParameterMgr::deleteAllDomainsCommandProcess, 0, - "", "Delete all configurable domains" }, - { "renameDomain", &CParameterMgr::renameDomainCommandProcess, 2, - "<domain> <new name>", "Rename configurable domain" }, - { "setSequenceAwareness", &CParameterMgr::setSequenceAwarenessCommandProcess, 1, - "<domain> true|false*", "Set configurable domain sequence awareness" }, - { "getSequenceAwareness", &CParameterMgr::getSequenceAwarenessCommandProcess, 1, - "<domain>", "Get configurable domain sequence awareness" }, - { "listDomainElements", &CParameterMgr::listDomainElementsCommandProcess, 1, - "<domain>", "List elements associated to configurable domain" }, - { "addElement", &CParameterMgr::addElementCommandProcess, 2, - "<domain> <elem path>", "Associate element at given path to configurable domain" }, - { "removeElement", &CParameterMgr::removeElementCommandProcess, 2, - "<domain> <elem path>", "Dissociate element at given path from configurable domain" }, - { "splitDomain", &CParameterMgr::splitDomainCommandProcess, 2, - "<domain> <elem path>", "Split configurable domain at given associated element path" }, + {"listDomains", &CParameterMgr::listDomainsCommandProcess, 0, "", "List configurable domains"}, + {"dumpDomains", &CParameterMgr::dumpDomainsCommandProcess, 0, "", + "Show all domains and configurations, including applicability conditions"}, + {"createDomain", &CParameterMgr::createDomainCommandProcess, 1, "<domain>", + "Create new configurable domain"}, + {"deleteDomain", &CParameterMgr::deleteDomainCommandProcess, 1, "<domain>", + "Delete configurable domain"}, + {"deleteAllDomains", &CParameterMgr::deleteAllDomainsCommandProcess, 0, "", + "Delete all configurable domains"}, + {"renameDomain", &CParameterMgr::renameDomainCommandProcess, 2, "<domain> <new name>", + "Rename configurable domain"}, + {"setSequenceAwareness", &CParameterMgr::setSequenceAwarenessCommandProcess, 1, + "<domain> true|false*", "Set configurable domain sequence awareness"}, + {"getSequenceAwareness", &CParameterMgr::getSequenceAwarenessCommandProcess, 1, "<domain>", + "Get configurable domain sequence awareness"}, + {"listDomainElements", &CParameterMgr::listDomainElementsCommandProcess, 1, "<domain>", + "List elements associated to configurable domain"}, + {"addElement", &CParameterMgr::addElementCommandProcess, 2, "<domain> <elem path>", + "Associate element at given path to configurable domain"}, + {"removeElement", &CParameterMgr::removeElementCommandProcess, 2, "<domain> <elem path>", + "Dissociate element at given path from configurable domain"}, + {"splitDomain", &CParameterMgr::splitDomainCommandProcess, 2, "<domain> <elem path>", + "Split configurable domain at given associated element path"}, /// Configurations - { "listConfigurations", &CParameterMgr::listConfigurationsCommandProcess, 1, - "<domain>", "List domain configurations" }, - { "createConfiguration", &CParameterMgr::createConfigurationCommandProcess, 2, - "<domain> <configuration>", "Create new domain configuration" }, - { "deleteConfiguration", &CParameterMgr::deleteConfigurationCommandProcess, 2, - "<domain> <configuration>", "Delete domain configuration" }, - { "renameConfiguration", &CParameterMgr::renameConfigurationCommandProcess, 3, - "<domain> <configuration> <new name>", "Rename domain configuration" }, - { "saveConfiguration", &CParameterMgr::saveConfigurationCommandProcess, 2, - "<domain> <configuration>", "Save current settings into configuration" }, - { "restoreConfiguration", &CParameterMgr::restoreConfigurationCommandProcess, 2, - "<domain> <configuration>", "Restore current settings from configuration" }, - { "setElementSequence", &CParameterMgr::setElementSequenceCommandProcess, 3, - "<domain> <configuration> <elem path list>", - "Set element application order for configuration" }, - { "getElementSequence", &CParameterMgr::getElementSequenceCommandProcess, 2, - "<domain> <configuration>", "Get element application order for configuration" }, - { "setRule", &CParameterMgr::setRuleCommandProcess, 3, - "<domain> <configuration> <rule>", "Set configuration application rule" }, - { "clearRule", &CParameterMgr::clearRuleCommandProcess, 2, - "<domain> <configuration>", "Clear configuration application rule" }, - { "getRule", &CParameterMgr::getRuleCommandProcess, 2, - "<domain> <configuration>", "Get configuration application rule" }, + {"listConfigurations", &CParameterMgr::listConfigurationsCommandProcess, 1, "<domain>", + "List domain configurations"}, + {"createConfiguration", &CParameterMgr::createConfigurationCommandProcess, 2, + "<domain> <configuration>", "Create new domain configuration"}, + {"deleteConfiguration", &CParameterMgr::deleteConfigurationCommandProcess, 2, + "<domain> <configuration>", "Delete domain configuration"}, + {"renameConfiguration", &CParameterMgr::renameConfigurationCommandProcess, 3, + "<domain> <configuration> <new name>", "Rename domain configuration"}, + {"saveConfiguration", &CParameterMgr::saveConfigurationCommandProcess, 2, + "<domain> <configuration>", "Save current settings into configuration"}, + {"restoreConfiguration", &CParameterMgr::restoreConfigurationCommandProcess, 2, + "<domain> <configuration>", "Restore current settings from configuration"}, + {"setElementSequence", &CParameterMgr::setElementSequenceCommandProcess, 3, + "<domain> <configuration> <elem path list>", + "Set element application order for configuration"}, + {"getElementSequence", &CParameterMgr::getElementSequenceCommandProcess, 2, + "<domain> <configuration>", "Get element application order for configuration"}, + {"setRule", &CParameterMgr::setRuleCommandProcess, 3, "<domain> <configuration> <rule>", + "Set configuration application rule"}, + {"clearRule", &CParameterMgr::clearRuleCommandProcess, 2, "<domain> <configuration>", + "Clear configuration application rule"}, + {"getRule", &CParameterMgr::getRuleCommandProcess, 2, "<domain> <configuration>", + "Get configuration application rule"}, /// Elements/Parameters - { "listElements", &CParameterMgr::listElementsCommandProcess, 1, - "<elem path>|/", "List elements under element at given path or root" }, - { "listParameters", &CParameterMgr::listParametersCommandProcess, 1, - "<elem path>|/", "List parameters under element at given path or root" }, - { "dumpElement", &CParameterMgr::dumpElementCommandProcess, 1, - "<elem path>", "Dump structure and content of element at given path" }, - { "getElementSize", &CParameterMgr::getElementSizeCommandProcess, 1, - "<elem path>", "Show size of element at given path" }, - { "showProperties", &CParameterMgr::showPropertiesCommandProcess, 1, - "<elem path>", "Show properties of element at given path" }, - { "getParameter", &CParameterMgr::getParameterCommandProcess, 1, - "<param path>", "Get value for parameter at given path" }, - { "setParameter", &CParameterMgr::setParameterCommandProcess, 2, - "<param path> <value>", "Set value for parameter at given path" }, - { "listBelongingDomains", &CParameterMgr::listBelongingDomainsCommandProcess, 1, - "<elem path>", "List domain(s) element at given path belongs to" }, - { "listAssociatedDomains", &CParameterMgr::listAssociatedDomainsCommandProcess, 1, - "<elem path>", "List domain(s) element at given path is associated to" }, - { "getConfigurationParameter", &CParameterMgr::getConfigurationParameterCommandProcess, 3, - "<domain> <configuration> <param path>", - "Get value for parameter at given path from configuration" }, - { "setConfigurationParameter", &CParameterMgr::setConfigurationParameterCommandProcess, 4, - "<domain> <configuration> <param path> <value>", - "Set value for parameter at given path to configuration" }, - { "showMapping", &CParameterMgr::showMappingCommandProcess, 1, - "<elem path>", "Show mapping for an element at given path" }, + {"listElements", &CParameterMgr::listElementsCommandProcess, 1, "<elem path>|/", + "List elements under element at given path or root"}, + {"listParameters", &CParameterMgr::listParametersCommandProcess, 1, "<elem path>|/", + "List parameters under element at given path or root"}, + {"getElementStructureXML", &CParameterMgr::getElementStructureXMLCommandProcess, 1, + "<elem path>", "Get structure of element at given path in XML format"}, + {"getElementBytes", &CParameterMgr::getElementBytesCommandProcess, 1, "<elem path>", + "Get settings of element at given path in Byte Array format"}, + {"setElementBytes", &CParameterMgr::setElementBytesCommandProcess, 2, "<elem path> <values>", + "Set settings of element at given path in Byte Array format"}, + {"getElementXML", &CParameterMgr::getElementXMLCommandProcess, 1, "<elem path>", + "Get settings of element at given path in XML format"}, + {"setElementXML", &CParameterMgr::setElementXMLCommandProcess, 2, "<elem path> <values>", + "Set settings of element at given path in XML format"}, + {"dumpElement", &CParameterMgr::dumpElementCommandProcess, 1, "<elem path>", + "Dump structure and content of element at given path"}, + {"getElementSize", &CParameterMgr::getElementSizeCommandProcess, 1, "<elem path>", + "Show size of element at given path"}, + {"showProperties", &CParameterMgr::showPropertiesCommandProcess, 1, "<elem path>", + "Show properties of element at given path"}, + {"getParameter", &CParameterMgr::getParameterCommandProcess, 1, "<param path>", + "Get value for parameter at given path"}, + {"setParameter", &CParameterMgr::setParameterCommandProcess, 2, "<param path> <value>", + "Set value for parameter at given path"}, + {"listBelongingDomains", &CParameterMgr::listBelongingDomainsCommandProcess, 1, "<elem path>", + "List domain(s) element at given path belongs to"}, + {"listAssociatedDomains", &CParameterMgr::listAssociatedDomainsCommandProcess, 1, "<elem path>", + "List domain(s) element at given path is associated to"}, + {"getConfigurationParameter", &CParameterMgr::getConfigurationParameterCommandProcess, 3, + "<domain> <configuration> <param path>", + "Get value for parameter at given path from configuration"}, + {"setConfigurationParameter", &CParameterMgr::setConfigurationParameterCommandProcess, 4, + "<domain> <configuration> <param path> <value>", + "Set value for parameter at given path to configuration"}, + {"showMapping", &CParameterMgr::showMappingCommandProcess, 1, "<elem path>", + "Show mapping for an element at given path"}, /// Browse - { "listAssociatedElements", &CParameterMgr::listAssociatedElementsCommandProcess, 0, - "", "List element sub-trees associated to at least one configurable domain" }, - { "listConflictingElements", &CParameterMgr::listConflictingElementsCommandProcess, 0, - "", "List element sub-trees contained in more than one configurable domain" }, - { "listRogueElements", &CParameterMgr::listRogueElementsCommandProcess, 0, - "", "List element sub-trees owned by no configurable domain" }, + {"listAssociatedElements", &CParameterMgr::listAssociatedElementsCommandProcess, 0, "", + "List element sub-trees associated to at least one configurable domain"}, + {"listConflictingElements", &CParameterMgr::listConflictingElementsCommandProcess, 0, "", + "List element sub-trees contained in more than one configurable domain"}, + {"listRogueElements", &CParameterMgr::listRogueElementsCommandProcess, 0, "", + "List element sub-trees owned by no configurable domain"}, /// Settings Import/Export - { "exportDomainsXML", &CParameterMgr::exportDomainsXMLCommandProcess, 1, - "<file path> ", "Export domains to an XML file (provide an absolute path or relative" - "to the client's working directory)" }, - { "importDomainsXML", &CParameterMgr::importDomainsXMLCommandProcess, 1, - "<file path>", "Import domains from an XML file (provide an absolute path or relative" - "to the client's working directory)" }, - { "exportDomainsWithSettingsXML", - &CParameterMgr::exportDomainsWithSettingsXMLCommandProcess, 1, - "<file path> ", "Export domains including settings to XML file (provide an absolute path or relative" - "to the client's working directory)" }, - { "exportDomainWithSettingsXML", - &CParameterMgr::exportDomainWithSettingsXMLCommandProcess, 2, - "<domain> <file path> ", "Export a single given domain including settings to XML file" - " (provide an absolute path or relative to the client's" - " working directory)" }, - { "importDomainsWithSettingsXML", - &CParameterMgr::importDomainsWithSettingsXMLCommandProcess, 1, - "<file path>", "Import domains including settings from XML file (provide an absolute path or relative" - "to the client's working directory)" }, - { "importDomainWithSettingsXML", - &CParameterMgr::importDomainWithSettingsXMLCommandProcess, 1, - "<file path> [overwrite]", "Import a single domain including settings from XML file." - " Does not overwrite an existing domain unless 'overwrite' is passed as second" - " argument. Provide an absolute path or relative to the client's working directory)" }, - { "exportSettings", &CParameterMgr::exportSettingsCommandProcess, 1, - "<file path>", "Export settings to binary file (provide an absolute path or relative" - "to the client's working directory)" }, - { "importSettings", &CParameterMgr::importSettingsCommandProcess, 1, - "<file path>", "Import settings from binary file (provide an absolute path or relative" - "to the client's working directory)" }, - { "getDomainsWithSettingsXML", - &CParameterMgr::getDomainsWithSettingsXMLCommandProcess, 0, - "", "Print domains including settings as XML" }, - { "getDomainWithSettingsXML", - &CParameterMgr::getDomainWithSettingsXMLCommandProcess, 1, - "<domain>", "Print the given domain including settings as XML" }, - { "setDomainsWithSettingsXML", - &CParameterMgr::setDomainsWithSettingsXMLCommandProcess, 1, - "<xml configurable domains>", "Import domains including settings from XML string" }, - { "setDomainWithSettingsXML", - &CParameterMgr::setDomainWithSettingsXMLCommandProcess, 1, - "<xml configurable domain> [overwrite]", "Import domains including settings from XML" - " string. Does not overwrite an existing domain unless 'overwrite' is passed as second" - " argument" }, + {"exportDomainsXML", &CParameterMgr::exportDomainsXMLCommandProcess, 1, "<file path> ", + "Export domains to an XML file (provide an absolute path or relative" + "to the client's working directory)"}, + {"importDomainsXML", &CParameterMgr::importDomainsXMLCommandProcess, 1, "<file path>", + "Import domains from an XML file (provide an absolute path or relative" + "to the client's working directory)"}, + {"exportDomainsWithSettingsXML", &CParameterMgr::exportDomainsWithSettingsXMLCommandProcess, 1, + "<file path> ", + "Export domains including settings to XML file (provide an absolute path or relative" + "to the client's working directory)"}, + {"exportDomainWithSettingsXML", &CParameterMgr::exportDomainWithSettingsXMLCommandProcess, 2, + "<domain> <file path> ", "Export a single given domain including settings to XML file" + " (provide an absolute path or relative to the client's" + " working directory)"}, + {"importDomainsWithSettingsXML", &CParameterMgr::importDomainsWithSettingsXMLCommandProcess, 1, + "<file path>", + "Import domains including settings from XML file (provide an absolute path or relative" + "to the client's working directory)"}, + {"importDomainWithSettingsXML", &CParameterMgr::importDomainWithSettingsXMLCommandProcess, 1, + "<file path> [overwrite]", + "Import a single domain including settings from XML file." + " Does not overwrite an existing domain unless 'overwrite' is passed as second" + " argument. Provide an absolute path or relative to the client's working directory)"}, + {"getDomainsWithSettingsXML", &CParameterMgr::getDomainsWithSettingsXMLCommandProcess, 0, "", + "Print domains including settings as XML"}, + {"getDomainWithSettingsXML", &CParameterMgr::getDomainWithSettingsXMLCommandProcess, 1, + "<domain>", "Print the given domain including settings as XML"}, + {"setDomainsWithSettingsXML", &CParameterMgr::setDomainsWithSettingsXMLCommandProcess, 1, + "<xml configurable domains>", "Import domains including settings from XML string"}, + {"setDomainWithSettingsXML", &CParameterMgr::setDomainWithSettingsXMLCommandProcess, 1, + "<xml configurable domain> [overwrite]", + "Import domains including settings from XML" + " string. Does not overwrite an existing domain unless 'overwrite' is passed as second" + " argument"}, /// Structure Export - { "getSystemClassXML", &CParameterMgr::getSystemClassXMLCommandProcess, 0 , - "", "Print parameter structure as XML" }, + {"getSystemClassXML", &CParameterMgr::getSystemClassXMLCommandProcess, 0, "", + "Print parameter structure as XML"}, /// Deprecated Commands - { "getDomainsXML", - &CParameterMgr::getDomainsWithSettingsXMLCommandProcess, 0, - "", "DEPRECATED COMMAND, please use getDomainsWithSettingsXML" }, + {"getDomainsXML", &CParameterMgr::getDomainsWithSettingsXMLCommandProcess, 0, "", + "DEPRECATED COMMAND, please use getDomainsWithSettingsXML"}, }; // Remote command parsers array Size -const uint32_t CParameterMgr::guiNbRemoteCommandParserItems = sizeof(gastRemoteCommandParserItems) / sizeof(gastRemoteCommandParserItems[0]); - -CParameterMgr::CParameterMgr(const string& strConfigurationFilePath) : - _bTuningModeIsOn(false), - _bValueSpaceIsRaw(false), - _bOutputRawFormatIsHex(false), - _bAutoSyncOn(true), - _pMainParameterBlackboard(new CParameterBlackboard), - _pElementLibrarySet(new CElementLibrarySet), - _strXmlConfigurationFilePath(strConfigurationFilePath), - _pSubsystemPlugins(NULL), - _pvLibRemoteProcessorHandle(NULL), - _uiStructureChecksum(0), - _pRemoteProcessorServer(NULL), - _uiMaxCommandUsageLength(0), - _pLogger(NULL), - _uiLogDepth(0), - _bForceNoRemoteInterface(false), - _bFailOnMissingSubsystem(true), - _bFailOnFailedSettingsLoad(true), - _bValidateSchemasOnStart(false) - -{ - // Tuning Mode Mutex - bzero(&_blackboardMutex, sizeof(_blackboardMutex)); - pthread_mutex_init(&_blackboardMutex, NULL); - +CParameterMgr::CParameterMgr(const string &strConfigurationFilePath, log::ILogger &logger) + : _pMainParameterBlackboard(new CParameterBlackboard), + _pElementLibrarySet(new CElementLibrarySet), + _xmlConfigurationUri(CXmlDocSource::mkUri(strConfigurationFilePath, "")), _logger(logger) +{ // Deal with children addChild(new CParameterFrameworkConfiguration); addChild(new CSelectionCriteria); - addChild(new CSystemClass); + addChild(new CSystemClass(_logger)); addChild(new CConfigurableDomains); - - _pCommandHandler = new CCommandHandler(this); - - // Add command parsers - uint32_t uiRemoteCommandParserItem; - - for (uiRemoteCommandParserItem = 0; uiRemoteCommandParserItem < guiNbRemoteCommandParserItems; uiRemoteCommandParserItem++) { - - const SRemoteCommandParserItem* pRemoteCommandParserItem = &gastRemoteCommandParserItems[uiRemoteCommandParserItem]; - - _pCommandHandler->addCommandParser(pRemoteCommandParserItem->_pcCommandName, - pRemoteCommandParserItem->_pfnParser, - pRemoteCommandParserItem->_uiMinArgumentCount, - pRemoteCommandParserItem->_pcHelp, - pRemoteCommandParserItem->_pcDescription); - } - - // Configuration file folder - std::string::size_type slashPos = _strXmlConfigurationFilePath.rfind('/', -1); - if(slashPos == std::string::npos) { - // Configuration folder is the current folder - _strXmlConfigurationFolderPath = '.'; - } else { - _strXmlConfigurationFolderPath = _strXmlConfigurationFilePath.substr(0, slashPos); - } - - // Schema absolute folder location - _strSchemaFolderLocation = _strXmlConfigurationFolderPath + "/" + gacSystemSchemasSubFolder; } CParameterMgr::~CParameterMgr() { // Children delete _pRemoteProcessorServer; - delete _pCommandHandler; delete _pMainParameterBlackboard; delete _pElementLibrarySet; - - // Close remote processor library - if (_pvLibRemoteProcessorHandle) { - - dlclose(_pvLibRemoteProcessorHandle); - } - - // Tuning Mode Mutex - pthread_mutex_destroy(&_blackboardMutex); } string CParameterMgr::getKind() const @@ -404,61 +348,15 @@ string CParameterMgr::getKind() const return "ParameterMgr"; } -// Logging -void CParameterMgr::setLogger(CParameterMgr::ILogger* pLogger) -{ - _pLogger = pLogger; -} - -// Logging -void CParameterMgr::doLog(bool bIsWarning, const string& strLog) const -{ - if (_pLogger) { - - // Nest - string strIndent; - - // Level - uint32_t uiNbIndents = _uiLogDepth; - - while (uiNbIndents--) { - - strIndent += " "; - } - - // Log - _pLogger->log(bIsWarning, strIndent + strLog); - } -} - -void CParameterMgr::nestLog() const -{ - _uiLogDepth++; -} - -void CParameterMgr::unnestLog() const -{ - _uiLogDepth--; -} - // Version string CParameterMgr::getVersion() const { - string strVersion; - - // Major - strVersion = CUtility::toString(guiEditionMajor) + "."; - // Minor - strVersion += CUtility::toString(guiEditionMinor) + "."; - // Revision - strVersion += CUtility::toString(guiRevision); - - return strVersion; + return PARAMETER_FRAMEWORK_VERSION; } -bool CParameterMgr::load(string& strError) +bool CParameterMgr::load(string &strError) { - CAutoLog autoLog(this, "Loading"); + LOG_CONTEXT("Loading"); feedElementLibraries(); @@ -468,9 +366,7 @@ bool CParameterMgr::load(string& strError) return false; } - // Load subsystems - if (!getSystemClass()->loadSubsystems(strError, - _pSubsystemPlugins, !_bFailOnMissingSubsystem)) { + if (!loadSubsystems(strError)) { return false; } @@ -493,30 +389,29 @@ bool CParameterMgr::load(string& strError) return false; } - { - CAutoLog autoLog(this, "Main blackboard back synchronization"); + LOG_CONTEXT("Main blackboard back synchronization"); - // Back synchronization for areas in parameter blackboard not covered by any domain - BackSynchronizer(getConstSystemClass(), _pMainParameterBlackboard).sync(); + // Back synchronization for areas in parameter blackboard not covered by any domain + BackSynchronizer(getConstSystemClass(), _pMainParameterBlackboard).sync(); } // We're done loading the settings and back synchronizing - CConfigurableDomains* pConfigurableDomains = getConfigurableDomains(); + CConfigurableDomains *pConfigurableDomains = getConfigurableDomains(); // We need to ensure all domains are valid pConfigurableDomains->validate(_pMainParameterBlackboard); // Log selection criterion states { - CAutoLog autoLog(this, "Criterion states"); + LOG_CONTEXT("Criterion states"); - const CSelectionCriteria* selectionCriteria = getConstSelectionCriteria(); + const CSelectionCriteria *selectionCriteria = getConstSelectionCriteria(); - list<string> lstrSelectionCriteron; - selectionCriteria->listSelectionCriteria(lstrSelectionCriteron, true, false); + list<string> criteria; + selectionCriteria->listSelectionCriteria(criteria, true, false); - log_table(false, lstrSelectionCriteron); + info() << criteria; } // Subsystem can not ask for resync as they have not been synced yet @@ -529,20 +424,21 @@ bool CParameterMgr::load(string& strError) return handleRemoteProcessingInterface(strError); } -bool CParameterMgr::loadFrameworkConfiguration(string& strError) +bool CParameterMgr::loadFrameworkConfiguration(string &strError) { - CAutoLog autoLog(this, "Loading framework configuration"); + LOG_CONTEXT("Loading framework configuration"); // Parse Structure XML file CXmlElementSerializingContext elementSerializingContext(strError); - _xmlDoc *doc = CXmlDocSource::mkXmlDoc(_strXmlConfigurationFilePath, true, true, strError); + _xmlDoc *doc = + CXmlDocSource::mkXmlDoc(_xmlConfigurationUri, true, true, elementSerializingContext); if (doc == NULL) { return false; } - if (!xmlParse(elementSerializingContext, getFrameworkConfiguration(), doc, - _strXmlConfigurationFolderPath, EFrameworkConfigurationLibrary)) { + if (!xmlParse(elementSerializingContext, getFrameworkConfiguration(), doc, _xmlConfigurationUri, + EFrameworkConfigurationLibrary)) { return false; } @@ -551,7 +447,8 @@ bool CParameterMgr::loadFrameworkConfiguration(string& strError) getConfigurableDomains()->setName(getConstFrameworkConfiguration()->getSystemClassName()); // Get subsystem plugins elements - _pSubsystemPlugins = static_cast<const CSubsystemPlugins*>(getConstFrameworkConfiguration()->findChild("SubsystemPlugins")); + _pSubsystemPlugins = static_cast<const CSubsystemPlugins *>( + getConstFrameworkConfiguration()->findChild("SubsystemPlugins")); if (!_pSubsystemPlugins) { @@ -561,47 +458,74 @@ bool CParameterMgr::loadFrameworkConfiguration(string& strError) } // Log tuning availability - log_info("Tuning %s", getConstFrameworkConfiguration()->isTuningAllowed() ? "allowed" : "prohibited"); + info() << "Tuning " + << (getConstFrameworkConfiguration()->isTuningAllowed() ? "allowed" : "prohibited"); return true; } -bool CParameterMgr::loadStructure(string& strError) +bool CParameterMgr::loadSubsystems(std::string &error) +{ + LOG_CONTEXT("Loading subsystem plugins"); + + // Load subsystems + bool isSuccess = + getSystemClass()->loadSubsystems(error, _pSubsystemPlugins, !_bFailOnMissingSubsystem); + + if (isSuccess) { + info() << "All subsystem plugins successfully loaded"; + + if (!error.empty()) { + // Log missing subsystems as info + info() << error; + } + } else { + warning() << error; + } + return isSuccess; +} + +bool CParameterMgr::loadStructure(string &strError) { // Retrieve system to load structure to - CSystemClass* pSystemClass = getSystemClass(); + CSystemClass *pSystemClass = getSystemClass(); - log_info("Loading %s system class structure", pSystemClass->getName().c_str()); + LOG_CONTEXT("Loading " + pSystemClass->getName() + " system class structure"); // Get structure description element - const CFrameworkConfigurationLocation* pStructureDescriptionFileLocation = static_cast<const CFrameworkConfigurationLocation*>(getConstFrameworkConfiguration()->findChildOfKind("StructureDescriptionFileLocation")); + const CFrameworkConfigurationLocation *pStructureDescriptionFileLocation = + static_cast<const CFrameworkConfigurationLocation *>( + getConstFrameworkConfiguration()->findChildOfKind("StructureDescriptionFileLocation")); if (!pStructureDescriptionFileLocation) { - strError = "No StructureDescriptionFileLocation element found for SystemClass " + pSystemClass->getName(); + strError = "No StructureDescriptionFileLocation element found for SystemClass " + + pSystemClass->getName(); return false; } - // Get Xml structure folder - string strXmlStructureFolder = pStructureDescriptionFileLocation->getFolderPath(_strXmlConfigurationFolderPath); - - // Get Xml structure file name - string strXmlStructureFilePath = pStructureDescriptionFileLocation->getFilePath(_strXmlConfigurationFolderPath); - // Parse Structure XML file - CXmlParameterSerializingContext parameterBuildContext(strError); + CParameterAccessContext accessContext(strError); + CXmlParameterSerializingContext parameterBuildContext(accessContext, strError); - CAutoLog autolog(pSystemClass, "Importing system structure from file " + strXmlStructureFilePath); + { + // Get structure URI + string structureUri = + CXmlDocSource::mkUri(_xmlConfigurationUri, pStructureDescriptionFileLocation->getUri()); - _xmlDoc *doc = CXmlDocSource::mkXmlDoc(strXmlStructureFilePath, true, true, strError); - if (doc == NULL) { - return false; - } + LOG_CONTEXT("Importing system structure from file " + structureUri); + + _xmlDoc *doc = CXmlDocSource::mkXmlDoc(structureUri, true, true, parameterBuildContext); + if (doc == NULL) { + return false; + } - if (!xmlParse(parameterBuildContext, pSystemClass, doc, strXmlStructureFolder, EParameterCreationLibrary)) { + if (!xmlParse(parameterBuildContext, pSystemClass, doc, structureUri, + EParameterCreationLibrary)) { - return false; + return false; + } } // Initialize offsets @@ -613,15 +537,15 @@ bool CParameterMgr::loadStructure(string& strError) return true; } -bool CParameterMgr::loadSettings(string& strError) +bool CParameterMgr::loadSettings(string &strError) { string strLoadError; bool success = loadSettingsFromConfigFile(strLoadError); if (!success && !_bFailOnFailedSettingsLoad) { // Load can not fail, ie continue but log the load errors - log_info("%s", strLoadError.c_str()); - log_info("Failed to load settings, continue without domains."); + warning() << strLoadError; + warning() << "Failed to load settings, continue without domains."; success = true; } @@ -634,12 +558,14 @@ bool CParameterMgr::loadSettings(string& strError) return true; } -bool CParameterMgr::loadSettingsFromConfigFile(string& strError) +bool CParameterMgr::loadSettingsFromConfigFile(string &strError) { - CAutoLog autoLog(this, "Loading settings"); + LOG_CONTEXT("Loading settings"); // Get settings configuration element - const CFrameworkConfigurationGroup* pParameterConfigurationGroup = static_cast<const CFrameworkConfigurationGroup*>(getConstFrameworkConfiguration()->findChildOfKind("SettingsConfiguration")); + const CFrameworkConfigurationGroup *pParameterConfigurationGroup = + static_cast<const CFrameworkConfigurationGroup *>( + getConstFrameworkConfiguration()->findChildOfKind("SettingsConfiguration")); if (!pParameterConfigurationGroup) { @@ -647,98 +573,75 @@ bool CParameterMgr::loadSettingsFromConfigFile(string& strError) return true; } - // Get binary settings file location - const CFrameworkConfigurationLocation* pBinarySettingsFileLocation = static_cast<const CFrameworkConfigurationLocation*>(pParameterConfigurationGroup->findChildOfKind("BinarySettingsFileLocation")); - - string strXmlBinarySettingsFilePath; - - if (pBinarySettingsFileLocation) { - - // Get Xml binary settings file name - strXmlBinarySettingsFilePath = pBinarySettingsFileLocation->getFilePath(_strXmlConfigurationFolderPath); - } // Get configurable domains element - const CFrameworkConfigurationLocation* pConfigurableDomainsFileLocation = static_cast<const CFrameworkConfigurationLocation*>(pParameterConfigurationGroup->findChildOfKind("ConfigurableDomainsFileLocation")); + const CFrameworkConfigurationLocation *pConfigurableDomainsFileLocation = + static_cast<const CFrameworkConfigurationLocation *>( + pParameterConfigurationGroup->findChildOfKind("ConfigurableDomainsFileLocation")); if (!pConfigurableDomainsFileLocation) { - strError = "No ConfigurableDomainsFileLocation element found for SystemClass " + getSystemClass()->getName(); + strError = "No ConfigurableDomainsFileLocation element found for SystemClass " + + getSystemClass()->getName(); return false; } // Get destination root element - CConfigurableDomains* pConfigurableDomains = getConfigurableDomains(); + CConfigurableDomains *pConfigurableDomains = getConfigurableDomains(); - // Get Xml configuration domains file name - string strXmlConfigurationDomainsFilePath = pConfigurableDomainsFileLocation->getFilePath(_strXmlConfigurationFolderPath); + // Get Xml configuration domains URI + string configurationDomainsUri = + CXmlDocSource::mkUri(_xmlConfigurationUri, pConfigurableDomainsFileLocation->getUri()); - // Get Xml configuration domains folder - string strXmlConfigurationDomainsFolder = pConfigurableDomainsFileLocation->getFolderPath(_strXmlConfigurationFolderPath); - - // Parse configuration domains XML file (ask to read settings from XML file if they are not provided as binary) - CXmlDomainImportContext xmlDomainImportContext(strError, !pBinarySettingsFileLocation, - *getSystemClass()); + // Parse configuration domains XML file + CXmlDomainImportContext xmlDomainImportContext(strError, true, *getSystemClass()); // Selection criteria definition for rule creation - xmlDomainImportContext.setSelectionCriteriaDefinition(getConstSelectionCriteria()->getSelectionCriteriaDefinition()); + xmlDomainImportContext.setSelectionCriteriaDefinition( + getConstSelectionCriteria()->getSelectionCriteriaDefinition()); - // Auto validation of configurations if no binary settings provided - xmlDomainImportContext.setAutoValidationRequired(!pBinarySettingsFileLocation); + // Auto validation of configurations + xmlDomainImportContext.setAutoValidationRequired(true); - log_info("Importing configurable domains from file %s %s settings", strXmlConfigurationDomainsFilePath.c_str(), pBinarySettingsFileLocation ? "without" : "with"); + info() << "Importing configurable domains from file " << configurationDomainsUri + << " with settings"; - _xmlDoc *doc = CXmlDocSource::mkXmlDoc(strXmlConfigurationDomainsFilePath, true, true, strError); + _xmlDoc *doc = + CXmlDocSource::mkXmlDoc(configurationDomainsUri, true, true, xmlDomainImportContext); if (doc == NULL) { return false; } - if (!xmlParse(xmlDomainImportContext, pConfigurableDomains, doc, strXmlConfigurationDomainsFolder, EParameterConfigurationLibrary, "SystemClassName")) { - - return false; - } - // We have loaded the whole system structure, compute checksum - const CSystemClass* pSystemClass = getConstSystemClass(); - _uiStructureChecksum = pSystemClass->computeStructureChecksum() + getConfigurableDomains()->computeStructureChecksum() + getSelectionCriteria()->computeStructureChecksum(); - - // Load binary settings if any provided - if (pBinarySettingsFileLocation && !pConfigurableDomains->serializeSettings(strXmlBinarySettingsFilePath, false, _uiStructureChecksum, strError)) { - - return false; - } - - return true; + return xmlParse(xmlDomainImportContext, pConfigurableDomains, doc, _xmlConfigurationUri, + EParameterConfigurationLibrary, true, "SystemClassName"); } // XML parsing -bool CParameterMgr::xmlParse(CXmlElementSerializingContext& elementSerializingContext, - CElement* pRootElement, _xmlDoc* doc, - const string& strXmlFolder, - CParameterMgr::ElementLibrary eElementLibrary, - const string& strNameAttributeName) +bool CParameterMgr::xmlParse(CXmlElementSerializingContext &elementSerializingContext, + CElement *pRootElement, _xmlDoc *doc, const string &baseUri, + CParameterMgr::ElementLibrary eElementLibrary, bool replace, + const string &strNameAttributeName) { // Init serializing context - elementSerializingContext.set(_pElementLibrarySet->getElementLibrary( - eElementLibrary), strXmlFolder, _strSchemaFolderLocation); + elementSerializingContext.set(_pElementLibrarySet->getElementLibrary(eElementLibrary), baseUri); - // Get Schema file associated to root element - string strXmlSchemaFilePath = _strSchemaFolderLocation + "/" + pRootElement->getKind() + ".xsd"; + CXmlDocSource docSource(doc, _bValidateSchemasOnStart, pRootElement->getXmlElementName(), + pRootElement->getName(), strNameAttributeName); - CXmlDocSource docSource(doc, _bValidateSchemasOnStart, - strXmlSchemaFilePath, - pRootElement->getKind(), - pRootElement->getName(), - strNameAttributeName); + docSource.setSchemaBaseUri(getSchemaUri()); // Start clean - pRootElement->clean(); + auto clean = [replace, &pRootElement] { + if (replace) { + pRootElement->clean(); + } + }; + clean(); CXmlMemoryDocSink memorySink(pRootElement); if (!memorySink.process(docSource, elementSerializingContext)) { - //Cleanup - pRootElement->clean(); - + clean(); return false; } @@ -746,26 +649,28 @@ bool CParameterMgr::xmlParse(CXmlElementSerializingContext& elementSerializingCo } // Init -bool CParameterMgr::init(string& strError) +bool CParameterMgr::init(string &strError) { return base::init(strError); } // Selection criteria interface -CSelectionCriterionType* CParameterMgr::createSelectionCriterionType(bool bIsInclusive) +CSelectionCriterionType *CParameterMgr::createSelectionCriterionType(bool bIsInclusive) { // Propagate return getSelectionCriteria()->createSelectionCriterionType(bIsInclusive); } -CSelectionCriterion* CParameterMgr::createSelectionCriterion(const string& strName, const CSelectionCriterionType* pSelectionCriterionType) +CSelectionCriterion *CParameterMgr::createSelectionCriterion( + const string &strName, const CSelectionCriterionType *pSelectionCriterionType) { // Propagate - return getSelectionCriteria()->createSelectionCriterion(strName, pSelectionCriterionType); + return getSelectionCriteria()->createSelectionCriterion(strName, pSelectionCriterionType, + _logger); } // Selection criterion retrieval -CSelectionCriterion* CParameterMgr::getSelectionCriterion(const string& strName) +CSelectionCriterion *CParameterMgr::getSelectionCriterion(const string &strName) { // Propagate return getSelectionCriteria()->getSelectionCriterion(strName); @@ -774,10 +679,10 @@ CSelectionCriterion* CParameterMgr::getSelectionCriterion(const string& strName) // Configuration application void CParameterMgr::applyConfigurations() { - CAutoLog autoLog(this, "Configuration application request"); + LOG_CONTEXT("Configuration application request"); // Lock state - CAutoLock autoLock(&_blackboardMutex); + lock_guard<mutex> autoLock(getBlackboardMutex()); if (!_bTuningModeIsOn) { @@ -785,13 +690,12 @@ void CParameterMgr::applyConfigurations() doApplyConfigurations(false); } else { - log_warning("Configurations were not applied because the TuningMode is on"); + warning() << "Configurations were not applied because the TuningMode is on"; } } -// Get the configurableElement corresponding to the given path -const CConfigurableElement* CParameterMgr::getConfigurableElement(const string& strPath, - string& strError) const +const CConfigurableElement *CParameterMgr::getConfigurableElement(const string &strPath, + string &strError) const { CPathNavigator pathNavigator(strPath); @@ -802,7 +706,7 @@ const CConfigurableElement* CParameterMgr::getConfigurableElement(const string& } // Find element - const CElement* pElement = getConstSystemClass()->findDescendant(pathNavigator); + const CElement *pElement = getConstSystemClass()->findDescendant(pathNavigator); if (!pElement) { @@ -812,15 +716,24 @@ const CConfigurableElement* CParameterMgr::getConfigurableElement(const string& } // Check found element is a parameter - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pElement); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(pElement); return pConfigurableElement; } +CConfigurableElement *CParameterMgr::getConfigurableElement(const string &strPath, string &strError) +{ + // Implement the mutable version by calling the const one and removing + // the const from the result. + const auto *constThis = this; + return const_cast<CConfigurableElement *>(constThis->getConfigurableElement(strPath, strError)); +} + // Dynamic parameter handling -CParameterHandle* CParameterMgr::createParameterHandle(const string& strPath, string& strError) +CParameterHandle *CParameterMgr::createParameterHandle(const string &strPath, string &strError) { - const CConfigurableElement* pConfigurableElement = getConfigurableElement(strPath, strError); + CConfigurableElement *pConfigurableElement = getConfigurableElement(strPath, strError); if (!pConfigurableElement) { @@ -838,7 +751,69 @@ CParameterHandle* CParameterMgr::createParameterHandle(const string& strPath, st } // Convert as parameter and return new handle - return new CParameterHandle(static_cast<const CBaseParameter*>(pConfigurableElement), this); + return new CParameterHandle(static_cast<CBaseParameter &>(*pConfigurableElement), *this); +} + +// Dynamic element handling +ElementHandle *CParameterMgr::createElementHandle(const std::string &path, std::string &error) +{ + CConfigurableElement *pConfigurableElement; + + if (path == "/") { + // Attempt to access root configurable element + pConfigurableElement = getSystemClass(); + } else { + pConfigurableElement = getConfigurableElement(path, error); + } + + if (!pConfigurableElement) { + + // Element not found + error = "Element not found: " + path; + return nullptr; + } + + // The only reason why a heap object is returned instead of retuning by copy + // is to inform the client of a failure through a nullptr. + // It could be avoided (return by copy) with an + // - optional equivalent (see boost::optional or std::experimental::optional) + // - exception (but the api is noexcept) + return new ElementHandle(*pConfigurableElement, *this); +} + +void CParameterMgr::getSettingsAsBytes(const CConfigurableElement &element, + std::vector<uint8_t> &settings) const +{ + // Not useful as the get can not fail, + // but the current design forces all serialization and deserialization to + // have an error out string + std::string error; + + // Prepare parameter access context for main blackboard. + // No need to handle output raw format and value space as Byte arrays are hexa formatted + CParameterAccessContext parameterAccessContext(error); + parameterAccessContext.setParameterBlackboard(_pMainParameterBlackboard); + + // Get the settings + element.getSettingsAsBytes(settings, parameterAccessContext); +} + +bool CParameterMgr::setSettingsAsBytes(const CConfigurableElement &element, + const std::vector<uint8_t> &settings, std::string &error) +{ + // Prepare parameter access context for main blackboard. + // Notes: + // - No need to handle output raw format and value space as Byte arrays are interpreted as + // raw formatted + // - No check is done as to the intgrity of the input data. + // This may lead to undetected out of range value assignment. + // Use this functionality with caution + CParameterAccessContext parameterAccessContext(error); + parameterAccessContext.setParameterBlackboard(_pMainParameterBlackboard); + parameterAccessContext.setAutoSync(autoSyncOn()); + + // Set the settings + return element.setSettingsAsBytes(settings, parameterAccessContext); } void CParameterMgr::setFailureOnMissingSubsystem(bool bFail) @@ -856,19 +831,19 @@ void CParameterMgr::setFailureOnFailedSettingsLoad(bool bFail) _bFailOnFailedSettingsLoad = bFail; } -bool CParameterMgr::getFailureOnFailedSettingsLoad() +bool CParameterMgr::getFailureOnFailedSettingsLoad() const { return _bFailOnFailedSettingsLoad; } -const string& CParameterMgr::getSchemaFolderLocation() const +const string &CParameterMgr::getSchemaUri() const { - return _strSchemaFolderLocation; + return _schemaUri; } -void CParameterMgr::setSchemaFolderLocation(const string& strSchemaFolderLocation) +void CParameterMgr::setSchemaUri(const string &schemaUri) { - _strSchemaFolderLocation = strSchemaFolderLocation; + _schemaUri = schemaUri; } void CParameterMgr::setValidateSchemasOnStart(bool bValidate) @@ -883,10 +858,9 @@ bool CParameterMgr::getValidateSchemasOnStart() const /////////////////// Remote command parsers /// Version -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::versionCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::versionCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - // Show version strResult = getVersion(); @@ -894,15 +868,15 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::versionCommandProce } /// Status -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::statusCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::statusCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; // System class - const CSystemClass* pSystemClass = getSystemClass(); + const CSystemClass *pSystemClass = getSystemClass(); // Show status /// General section - CUtility::appendTitle(strResult, "General:"); + utility::appendTitle(strResult, "General:"); // System class strResult += "System Class: "; strResult += pSystemClass->getName(); @@ -929,31 +903,30 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::statusCommandProces strResult += "\n"; /// Subsystem list - CUtility::appendTitle(strResult, "Subsystems:"); + utility::appendTitle(strResult, "Subsystems:"); string strSubsystemList; pSystemClass->listChildrenPaths(strSubsystemList); strResult += strSubsystemList; /// Last applied configurations - CUtility::appendTitle(strResult, "Last Applied [Pending] Configurations:"); + utility::appendTitle(strResult, "Last Applied [Pending] Configurations:"); string strLastAppliedConfigurations; getConfigurableDomains()->listLastAppliedConfigurations(strLastAppliedConfigurations); strResult += strLastAppliedConfigurations; /// Criteria states - CUtility::appendTitle(strResult, "Selection Criteria:"); + utility::appendTitle(strResult, "Selection Criteria:"); list<string> lstrSelectionCriteria; getSelectionCriteria()->listSelectionCriteria(lstrSelectionCriteria, false, true); // Concatenate the criterion list as the command result - string strCriteriaStates; - CUtility::asString(lstrSelectionCriteria, strCriteriaStates); - strResult += strCriteriaStates; + strResult += utility::asString(lstrSelectionCriteria); return CCommandHandler::ESucceeded; } /// Tuning Mode -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setTuningModeCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setTuningModeCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { if (remoteCommand.getArgument(0) == "on") { @@ -974,20 +947,18 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setTuningModeComman return CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getTuningModeCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getTuningModeCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - strResult = tuningModeOn() ? "on" : "off"; return CCommandHandler::ESucceeded; } /// Value Space -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setValueSpaceCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setValueSpaceCommandProcess( + const IRemoteCommand &remoteCommand, string & /*strResult*/) { - (void)strResult; - if (remoteCommand.getArgument(0) == "raw") { setValueSpace(true); @@ -1007,20 +978,18 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setValueSpaceComman return CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getValueSpaceCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getValueSpaceCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - strResult = valueSpaceIsRaw() ? "raw" : "real"; return CCommandHandler::ESucceeded; } /// Output Raw Format -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setOutputRawFormatCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setOutputRawFormatCommandProcess( + const IRemoteCommand &remoteCommand, string & /*strResult*/) { - (void)strResult; - if (remoteCommand.getArgument(0) == "hex") { setOutputRawFormat(true); @@ -1040,17 +1009,17 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setOutputRawFormatC return CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getOutputRawFormatCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getOutputRawFormatCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - strResult = outputRawFormatIsHex() ? "hex" : "dec"; return CCommandHandler::ESucceeded; } /// Sync -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setAutoSyncCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setAutoSyncCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { if (remoteCommand.getArgument(0) == "on") { @@ -1071,24 +1040,23 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setAutoSyncCommandP return CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getAutoSyncCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getAutoSyncCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - strResult = autoSyncOn() ? "on" : "off"; return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::syncCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::syncCommandProcess( + const IRemoteCommand &, string &strResult) { - (void)remoteCommand; - return sync(strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; } /// Criteria -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listCriteriaCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listCriteriaCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { if (remoteCommand.getArgumentCount() > 1) { @@ -1104,7 +1072,8 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listCriteriaCommand strOutputFormat = remoteCommand.getArgument(0); // Capitalize - std::transform(strOutputFormat.begin(), strOutputFormat.end(), strOutputFormat.begin(), ::toupper); + std::transform(strOutputFormat.begin(), strOutputFormat.end(), strOutputFormat.begin(), + ::toupper); if (strOutputFormat != "XML" && strOutputFormat != "CSV") { @@ -1114,10 +1083,11 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listCriteriaCommand if (strOutputFormat == "XML") { // Get Root element where to export from - const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition = getConstSelectionCriteria()->getSelectionCriteriaDefinition(); + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition = + getConstSelectionCriteria()->getSelectionCriteriaDefinition(); if (!exportElementToXMLString(pSelectionCriteriaDefinition, "SelectionCriteria", - strResult)) { + CXmlSerializingContext{strResult}, strResult)) { return CCommandHandler::EFailed; } @@ -1133,46 +1103,51 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listCriteriaCommand getSelectionCriteria()->listSelectionCriteria(lstrResult, true, bHumanReadable); // Concatenate the criterion list as the command result - CUtility::asString(lstrResult, strResult); + strResult += utility::asString(lstrResult); return CCommandHandler::ESucceeded; } } /// Domains -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainsCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - getConfigurableDomains()->listDomains(strResult); return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::createDomainCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::createDomainCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return createDomain(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return createDomain(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteDomainCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteDomainCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return deleteDomain(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return deleteDomain(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteAllDomainsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteAllDomainsCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - return deleteAllDomains(strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::renameDomainCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::renameDomainCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return renameDomain(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return renameDomain(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setSequenceAwarenessCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setSequenceAwarenessCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Set property bool bSequenceAware; @@ -1190,11 +1165,13 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setSequenceAwarenes return CCommandHandler::EShowUsage; } - return setSequenceAwareness(remoteCommand.getArgument(0), bSequenceAware, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return setSequenceAwareness(remoteCommand.getArgument(0), bSequenceAware, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getSequenceAwarenessCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getSequenceAwarenessCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Get property bool bSequenceAware; @@ -1209,142 +1186,182 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getSequenceAwarenes return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainElementsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainElementsCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return getConfigurableDomains()->listDomainElements(remoteCommand.getArgument(0), strResult) ? CCommandHandler::ESucceeded : CCommandHandler::EFailed; + return getConfigurableDomains()->listDomainElements(remoteCommand.getArgument(0), strResult) + ? CCommandHandler::ESucceeded + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::addElementCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::addElementCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return addConfigurableElementToDomain(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return addConfigurableElementToDomain(remoteCommand.getArgument(0), + remoteCommand.getArgument(1), strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::removeElementCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::removeElementCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return removeConfigurableElementFromDomain(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return removeConfigurableElementFromDomain(remoteCommand.getArgument(0), + remoteCommand.getArgument(1), strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::splitDomainCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::splitDomainCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return split(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return split(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } /// Configurations -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConfigurationsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConfigurationsCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return getConstConfigurableDomains()->listConfigurations(remoteCommand.getArgument(0), strResult) ? CCommandHandler::ESucceeded : CCommandHandler::EFailed; + return getConstConfigurableDomains()->listConfigurations(remoteCommand.getArgument(0), + strResult) + ? CCommandHandler::ESucceeded + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpDomainsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpDomainsCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - // Dummy error context string strError; - CErrorContext errorContext(strError); + utility::ErrorContext errorContext(strError); // Dump - getConstConfigurableDomains()->dumpContent(strResult, errorContext); + strResult = getConstConfigurableDomains()->dumpContent(errorContext); return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::createConfigurationCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::createConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return createConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return createConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), + strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteConfigurationCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return deleteConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return deleteConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), + strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::renameConfigurationCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::renameConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { return renameConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), - remoteCommand.getArgument(2), strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + remoteCommand.getArgument(2), strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::saveConfigurationCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::saveConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return saveConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return saveConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::restoreConfigurationCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::restoreConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - list<string> lstrResult; - if (!restoreConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), lstrResult)) { - //Concatenate the error list as the command result - CUtility::asString(lstrResult, strResult); + core::Results result; + if (!restoreConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), result)) { + // Concatenate the error list as the command result + strResult = utility::asString(result); - return CCommandHandler::EFailed; + return CCommandHandler::EFailed; } return CCommandHandler::EDone; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementSequenceCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementSequenceCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Build configurable element path list std::vector<string> astrNewElementSequence; - uint32_t uiArgument; + for (size_t argument = 2; argument < remoteCommand.getArgumentCount(); argument++) { - for (uiArgument = 2; uiArgument < remoteCommand.getArgumentCount(); uiArgument++) { - - astrNewElementSequence.push_back(remoteCommand.getArgument(uiArgument)); + astrNewElementSequence.push_back(remoteCommand.getArgument(argument)); } // Delegate to configurable domains return setElementSequence(remoteCommand.getArgument(0), remoteCommand.getArgument(1), - astrNewElementSequence, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + astrNewElementSequence, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSequenceCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSequenceCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Delegate to configurable domains - return getConfigurableDomains()->getElementSequence(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) ? CCommandHandler::ESucceeded : CCommandHandler::EFailed; + return getConfigurableDomains()->getElementSequence(remoteCommand.getArgument(0), + remoteCommand.getArgument(1), strResult) + ? CCommandHandler::ESucceeded + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setRuleCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setRuleCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Delegate to configurable domains return setApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), - remoteCommand.packArguments(2, remoteCommand.getArgumentCount() - 2), strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + remoteCommand.packArguments(2, remoteCommand.getArgumentCount() - 2), + strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::clearRuleCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::clearRuleCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Delegate to configurable domains return clearApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), - strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getRuleCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getRuleCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Delegate to configurable domains - return getApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), - strResult) ? - CCommandHandler::ESucceeded : CCommandHandler::EFailed; + return getApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) + ? CCommandHandler::ESucceeded + : CCommandHandler::EFailed; } /// Elements/Parameters -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listElementsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listElementsCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { CElementLocator elementLocator(getSystemClass(), false); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { return CCommandHandler::EFailed; } - strResult = string("\n"); - if (!pLocatedElement) { // List from root folder @@ -1360,19 +1377,18 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listElementsCommand } /// Elements/Parameters -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listParametersCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listParametersCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { CElementLocator elementLocator(getSystemClass(), false); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { return CCommandHandler::EFailed; } - strResult = string("\n"); - if (!pLocatedElement) { // List from root folder @@ -1387,11 +1403,226 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listParametersComma return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpElementCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementStructureXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) +{ + CElementLocator elementLocator(getSystemClass()); + + CElement *pLocatedElement = NULL; + + if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { + + return CCommandHandler::EFailed; + } + + // Use default access context for structure export + CParameterAccessContext accessContext(strResult); + if (!exportElementToXMLString(pLocatedElement, pLocatedElement->getXmlElementName(), + CXmlParameterSerializingContext{accessContext, strResult}, + strResult)) { + + return CCommandHandler::EFailed; + } + + return CCommandHandler::ESucceeded; +} + +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementBytesCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult) +{ + CElementLocator elementLocator(getSystemClass()); + + CElement *pLocatedElement = NULL; + + if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { + + return CCommandHandler::EFailed; + } + + const CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(pLocatedElement); + + // Get the settings + vector<uint8_t> bytes; + getSettingsAsBytes(*pConfigurableElement, bytes); + + // Hexa formatting + std::ostringstream ostream; + ostream << std::hex << std::setfill('0'); + + // Format bytes + for (auto byte : bytes) { + + // Convert to an int in order to avoid the "char" overload that would + // print characters instead of numbers. + ostream << "0x" << std::setw(2) << int{byte} << " "; + } + + strResult = ostream.str(); + if (not strResult.empty()) { + // Remove the trailing space + strResult.pop_back(); + } + + return CCommandHandler::ESucceeded; +} + +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementBytesCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { + // Check tuning mode + if (!checkTuningModeOn(strResult)) { + + return CCommandHandler::EFailed; + } + + // Retrieve configurable element CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; + + if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { + + return CCommandHandler::EFailed; + } + + const CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(pLocatedElement); + + // Convert input data to binary + vector<uint8_t> bytes; + + auto first = remoteCommand.getArguments().cbegin() + 1; + auto last = remoteCommand.getArguments().cend(); + + try { + std::transform(first, last, begin(bytes), [](decltype(*first) input) { + uint8_t byte; + + if (!convertTo(input, byte)) { + throw std::domain_error("Some values out of byte range"); + } + + return byte; + }); + } catch (const std::domain_error &e) { + strResult = e.what(); + + return CCommandHandler::EFailed; + } + + // Set the settings + if (!setSettingsAsBytes(*pConfigurableElement, bytes, strResult)) { + + return CCommandHandler::EFailed; + } + + return CCommandHandler::EDone; +} + +bool CParameterMgr::getSettingsAsXML(const CConfigurableElement *configurableElement, + string &result) const +{ + string error; + CConfigurationAccessContext configContext(error, _pMainParameterBlackboard, _bValueSpaceIsRaw, + _bOutputRawFormatIsHex, true); + + CXmlParameterSerializingContext xmlParameterContext(configContext, error); + + // Use a doc source by loading data from instantiated Configurable Domains + CXmlMemoryDocSource memorySource(configurableElement, false, + configurableElement->getXmlElementName()); + + // Use a doc sink that write the doc data in a string + ostringstream output; + CXmlStreamDocSink streamSink(output); + + if (not streamSink.process(memorySource, xmlParameterContext)) { + result = error; + return false; + } + result = output.str(); + return true; +} + +bool CParameterMgr::setSettingsAsXML(CConfigurableElement *configurableElement, + const string &settings, string &error) +{ + CConfigurationAccessContext configContext(error, _pMainParameterBlackboard, _bValueSpaceIsRaw, + _bOutputRawFormatIsHex, false); + + CXmlParameterSerializingContext xmlParameterContext(configContext, error); + + // It doesn't make sense to resolve XIncludes on an imported file because + // we can't reliably decide of a "base url" + _xmlDoc *doc = CXmlDocSource::mkXmlDoc(settings, false, false, xmlParameterContext); + if (doc == nullptr) { + return false; + } + if (not xmlParse(xmlParameterContext, configurableElement, doc, "", + EParameterConfigurationLibrary, false)) { + return false; + } + if (_bAutoSyncOn) { + CSyncerSet syncerSet; + static_cast<CConfigurableElement *>(configurableElement)->fillSyncerSet(syncerSet); + core::Results errors; + if (not syncerSet.sync(*_pMainParameterBlackboard, false, &errors)) { + error = utility::asString(errors); + + return false; + } + } + return true; +} + +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &result) +{ + CElementLocator elementLocator(getSystemClass()); + + CElement *locatedElement = nullptr; + + if (not elementLocator.locate(remoteCommand.getArgument(0), &locatedElement, result)) { + + return CCommandHandler::EFailed; + } + + if (not getSettingsAsXML(static_cast<CConfigurableElement *>(locatedElement), result)) { + return CCommandHandler::EFailed; + } + return CCommandHandler::ESucceeded; +} + +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &result) +{ + if (!checkTuningModeOn(result)) { + + return CCommandHandler::EFailed; + } + + CElementLocator elementLocator(getSystemClass()); + + CElement *locatedElement = nullptr; + + if (not elementLocator.locate(remoteCommand.getArgument(0), &locatedElement, result)) { + + return CCommandHandler::EFailed; + } + if (not setSettingsAsXML(static_cast<CConfigurableElement *>(locatedElement), + remoteCommand.getArgument(1), result)) { + return CCommandHandler::EFailed; + } + return CCommandHandler::EDone; +} + +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpElementCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) +{ + CElementLocator elementLocator(getSystemClass()); + + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { @@ -1400,19 +1631,21 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpElementCommandP string strError; - CParameterAccessContext parameterAccessContext(strError, _pMainParameterBlackboard, _bValueSpaceIsRaw, _bOutputRawFormatIsHex); + CParameterAccessContext parameterAccessContext(strError, _pMainParameterBlackboard, + _bValueSpaceIsRaw, _bOutputRawFormatIsHex); // Dump elements - pLocatedElement->dumpContent(strResult, parameterAccessContext); + strResult = pLocatedElement->dumpContent(parameterAccessContext); return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSizeCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSizeCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { @@ -1420,7 +1653,8 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSizeComma } // Converted to actual sizable element - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pLocatedElement); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(pLocatedElement); // Get size as string strResult = pConfigurableElement->getFootprintAsString(); @@ -1428,11 +1662,12 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSizeComma return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showPropertiesCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showPropertiesCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { @@ -1440,7 +1675,8 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showPropertiesComma } // Convert element - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pLocatedElement); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(pLocatedElement); // Return element properties pConfigurableElement->showProperties(strResult); @@ -1448,7 +1684,8 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showPropertiesComma return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getParameterCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getParameterCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { string strValue; @@ -1462,19 +1699,23 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getParameterCommand return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setParameterCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setParameterCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { // Get value to set string strValue = remoteCommand.packArguments(1, remoteCommand.getArgumentCount() - 1); - return accessParameterValue(remoteCommand.getArgument(0), strValue, true, strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return accessParameterValue(remoteCommand.getArgument(0), strValue, true, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listBelongingDomainsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listBelongingDomainsCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { @@ -1482,7 +1723,8 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listBelongingDomain } // Convert element - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pLocatedElement); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(pLocatedElement); // Return element belonging domains pConfigurableElement->listBelongingDomains(strResult); @@ -1490,11 +1732,12 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listBelongingDomain return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedDomainsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedDomainsCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { @@ -1502,7 +1745,8 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedDomai } // Convert element - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pLocatedElement); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(pLocatedElement); // Return element belonging domains pConfigurableElement->listAssociatedDomains(strResult); @@ -1510,39 +1754,38 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedDomai return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedElementsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedElementsCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - getConfigurableDomains()->listAssociatedElements(strResult); return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConflictingElementsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConflictingElementsCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - getConfigurableDomains()->listConflictingElements(strResult); return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listRogueElementsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listRogueElementsCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - getSystemClass()->listRogueElements(strResult); return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getConfigurationParameterCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + getConfigurationParameterCommandProcess(const IRemoteCommand &remoteCommand, string &strResult) { string strOutputValue; string strError; - if (!accessConfigurationValue(remoteCommand.getArgument(0), remoteCommand.getArgument(1), remoteCommand.getArgument(2), strOutputValue, false, strError)) { + if (!accessConfigurationValue(remoteCommand.getArgument(0), remoteCommand.getArgument(1), + remoteCommand.getArgument(2), strOutputValue, false, strError)) { strResult = strError; return CCommandHandler::EFailed; @@ -1553,22 +1796,21 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getConfigurationPar return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setConfigurationParameterCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + setConfigurationParameterCommandProcess(const IRemoteCommand &remoteCommand, string &strResult) { // Get value to set string strValue = remoteCommand.packArguments(3, remoteCommand.getArgumentCount() - 3); - bool bSuccess = accessConfigurationValue(remoteCommand.getArgument(0), - remoteCommand.getArgument(1), - remoteCommand.getArgument(2), - strValue, true, strResult); + bool bSuccess = + accessConfigurationValue(remoteCommand.getArgument(0), remoteCommand.getArgument(1), + remoteCommand.getArgument(2), strValue, true, strResult); return bSuccess ? CCommandHandler::EDone : CCommandHandler::EFailed; } CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showMappingCommandProcess( - const IRemoteCommand& remoteCommand, - string& strResult) + const IRemoteCommand &remoteCommand, string &strResult) { if (!getParameterMapping(remoteCommand.getArgument(0), strResult)) { @@ -1579,48 +1821,53 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showMappingCommandP } /// Settings Import/Export -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::exportDomainsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::exportDomainsXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { string strFileName = remoteCommand.getArgument(0); - return exportDomainsXml(strFileName, false, true, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return exportDomainsXml(strFileName, false, true, strResult) ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::importDomainsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::importDomainsXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { - return importDomainsXml(remoteCommand.getArgument(0), false, true, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return importDomainsXml(remoteCommand.getArgument(0), false, true, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::exportDomainsWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + exportDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, + string &strResult) { string strFileName = remoteCommand.getArgument(0); - return exportDomainsXml(strFileName, true, true, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return exportDomainsXml(strFileName, true, true, strResult) ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::exportDomainWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& result) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + exportDomainWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, string &result) { string domainName = remoteCommand.getArgument(0); string fileName = remoteCommand.getArgument(1); - return exportSingleDomainXml(fileName, domainName, true, true, result) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return exportSingleDomainXml(fileName, domainName, true, true, result) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::importDomainsWithSettingsXMLCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + importDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, + string &strResult) { - return importDomainsXml(remoteCommand.getArgument(0), true, true, strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return importDomainsXml(remoteCommand.getArgument(0), true, true, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::importDomainWithSettingsXMLCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + importDomainWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, + string &strResult) { bool bOverwrite = false; @@ -1636,26 +1883,14 @@ CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::importDomainWithSet } } - return importSingleDomainXml(remoteCommand.getArgument(0), bOverwrite, true, true, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; -} - -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::exportSettingsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) -{ - return exportDomainsBinary(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; + return importSingleDomainXml(remoteCommand.getArgument(0), bOverwrite, true, true, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::importSettingsCommandProcess(const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + getDomainsWithSettingsXMLCommandProcess(const IRemoteCommand & /*command*/, string &strResult) { - return importDomainsBinary(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; -} - -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::getDomainsWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) -{ - (void)remoteCommand; - if (!exportDomainsXml(strResult, true, false, strResult)) { return CCommandHandler::EFailed; @@ -1664,27 +1899,26 @@ CParameterMgr::CCommandHandler::CommandStatus return CCommandHandler::ESucceeded; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::getDomainWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getDomainWithSettingsXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &strResult) { string strDomainName = remoteCommand.getArgument(0); - return exportSingleDomainXml(strResult, strDomainName, true, false, strResult) ? - CCommandHandler::ESucceeded : CCommandHandler::EFailed; + return exportSingleDomainXml(strResult, strDomainName, true, false, strResult) + ? CCommandHandler::ESucceeded + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::setDomainsWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: + setDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, string &strResult) { - return importDomainsXml(remoteCommand.getArgument(0), true, false, strResult) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return importDomainsXml(remoteCommand.getArgument(0), true, false, strResult) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::setDomainWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& result) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setDomainWithSettingsXMLCommandProcess( + const IRemoteCommand &remoteCommand, string &result) { bool overwrite = false; @@ -1699,21 +1933,22 @@ CParameterMgr::CCommandHandler::CommandStatus } } - return importSingleDomainXml(remoteCommand.getArgument(0), overwrite, true, false, result) ? - CCommandHandler::EDone : CCommandHandler::EFailed; + return importSingleDomainXml(remoteCommand.getArgument(0), overwrite, true, false, result) + ? CCommandHandler::EDone + : CCommandHandler::EFailed; } -CParameterMgr::CCommandHandler::CommandStatus - CParameterMgr::getSystemClassXMLCommandProcess( - const IRemoteCommand& remoteCommand, string& strResult) +CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getSystemClassXMLCommandProcess( + const IRemoteCommand & /*command*/, string &strResult) { - (void)remoteCommand; - // Get Root element where to export from - const CSystemClass* pSystemClass = getSystemClass(); - - if (!exportElementToXMLString(pSystemClass, pSystemClass->getKind(), strResult)) { + const CSystemClass *pSystemClass = getSystemClass(); + // Use default access context for structure export + CParameterAccessContext accessContext(strResult); + if (!exportElementToXMLString(pSystemClass, pSystemClass->getXmlElementName(), + CXmlParameterSerializingContext{accessContext, strResult}, + strResult)) { return CCommandHandler::EFailed; } // Succeeded @@ -1721,7 +1956,8 @@ CParameterMgr::CCommandHandler::CommandStatus } // User set/get parameters in main BlackBoard -bool CParameterMgr::accessParameterValue(const string& strPath, string& strValue, bool bSet, string& strError) +bool CParameterMgr::accessParameterValue(const string &strPath, string &strValue, bool bSet, + string &strError) { // Forbid write access when not in TuningMode if (bSet && !checkTuningModeOn(strError)) { @@ -1730,7 +1966,8 @@ bool CParameterMgr::accessParameterValue(const string& strPath, string& strValue } // Define context - CParameterAccessContext parameterAccessContext(strError, _pMainParameterBlackboard, _bValueSpaceIsRaw, _bOutputRawFormatIsHex); + CParameterAccessContext parameterAccessContext(strError, _pMainParameterBlackboard, + _bValueSpaceIsRaw, _bOutputRawFormatIsHex); // Activate the auto synchronization with the hardware if (bSet) { @@ -1742,29 +1979,20 @@ bool CParameterMgr::accessParameterValue(const string& strPath, string& strValue } // User get parameter mapping -bool CParameterMgr::getParameterMapping(const string& strPath, string& strResult) const +bool CParameterMgr::getParameterMapping(const string &strPath, string &strResult) const { - CPathNavigator pathNavigator(strPath); - - // Nagivate through system class - if (!pathNavigator.navigateThrough(getConstSystemClass()->getName(), strResult)) { - - return false; - } - // Get the ConfigurableElement corresponding to strPath - const CConfigurableElement* pConfigurableElement = getConfigurableElement(strPath, strResult); + const CConfigurableElement *pConfigurableElement = getConfigurableElement(strPath, strResult); if (!pConfigurableElement) { return false; } // Find the list of the ancestors of the current ConfigurableElement that have a mapping - list<const CConfigurableElement*> configurableElementPath; - pConfigurableElement->getListOfElementsWithMapping(configurableElementPath); + auto configurableElementPath = pConfigurableElement->getConfigurableElementContext(); // Get the Subsystem containing the ConfigurableElement - const CSubsystem* pSubsystem = pConfigurableElement->getBelongingSubsystem(); + const CSubsystem *pSubsystem = pConfigurableElement->getBelongingSubsystem(); if (!pSubsystem) { strResult = "Unable to find the Subsystem containing the parameter"; @@ -1778,11 +2006,13 @@ bool CParameterMgr::getParameterMapping(const string& strPath, string& strResult } // User set/get parameters in specific Configuration BlackBoard -bool CParameterMgr::accessConfigurationValue(const string& strDomain, const string& strConfiguration, const string& strPath, string& strValue, bool bSet, string& strError) +bool CParameterMgr::accessConfigurationValue(const string &strDomain, + const string &strConfiguration, const string &strPath, + string &strValue, bool bSet, string &strError) { CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(strPath, &pLocatedElement, strError)) { @@ -1790,25 +2020,35 @@ bool CParameterMgr::accessConfigurationValue(const string& strDomain, const stri } // Convert element - const CConfigurableElement* pConfigurableElement = static_cast<const CConfigurableElement*>(pLocatedElement); + const CConfigurableElement *pConfigurableElement = + static_cast<const CConfigurableElement *>(pLocatedElement); - // Get the Configuration blackboard and the Base Offset of the configurable element in this blackboard - uint32_t uiBaseOffset; + // Get the Configuration blackboard and the Base Offset of the configurable element in this + // blackboard + size_t baseOffset; bool bIsLastApplied; - CParameterBlackboard* pConfigurationBlackboard = getConstConfigurableDomains()->findConfigurationBlackboard(strDomain, strConfiguration, pConfigurableElement, uiBaseOffset, bIsLastApplied, strError); + CParameterBlackboard *pConfigurationBlackboard = NULL; - if (!pConfigurationBlackboard) { + { + pConfigurationBlackboard = getConstConfigurableDomains()->findConfigurationBlackboard( + strDomain, strConfiguration, pConfigurableElement, baseOffset, bIsLastApplied, + strError); + if (!pConfigurationBlackboard) { - return false; + warning() << "Fail: " << strError; + return false; + } } - log_info("Element %s in Domain %s, offset: %d, base offset: %d", strPath.c_str(), strDomain.c_str(), pConfigurableElement->getOffset(), uiBaseOffset); + info() << "Element " << strPath << " in Domain " << strDomain + << ", offset: " << pConfigurableElement->getOffset() << ", base offset: " << baseOffset; /// Update the Configuration Blackboard // Define Configuration context using Base Offset and keep Auto Sync off to prevent access to HW - CParameterAccessContext parameterAccessContext(strError, pConfigurationBlackboard, _bValueSpaceIsRaw, _bOutputRawFormatIsHex, uiBaseOffset); + CParameterAccessContext parameterAccessContext( + strError, pConfigurationBlackboard, _bValueSpaceIsRaw, _bOutputRawFormatIsHex, baseOffset); // Deactivate the auto synchronization with the hardware during the Configuration Blackboard // access (only Main Blackboard shall be synchronized, Configurations Blackboards are copied @@ -1846,10 +2086,12 @@ bool CParameterMgr::accessConfigurationValue(const string& strDomain, const stri } // User set/get parameters -bool CParameterMgr::accessValue(CParameterAccessContext& parameterAccessContext, const string& strPath, string& strValue, bool bSet, string& strError) +bool CParameterMgr::accessValue(CParameterAccessContext ¶meterAccessContext, + const string &strPath, string &strValue, bool bSet, + string &strError) { // Lock state - CAutoLock autoLock(&_blackboardMutex); + lock_guard<mutex> autoLock(getBlackboardMutex()); CPathNavigator pathNavigator(strPath); @@ -1862,12 +2104,17 @@ bool CParameterMgr::accessValue(CParameterAccessContext& parameterAccessContext, } // Do the get - return getConstSystemClass()->accessValue(pathNavigator, strValue, bSet, parameterAccessContext); + return getConstSystemClass()->accessValue(pathNavigator, strValue, bSet, + parameterAccessContext); } // Tuning mode -bool CParameterMgr::setTuningMode(bool bOn, string& strError) +bool CParameterMgr::setTuningMode(bool bOn, string &strError) { + if (bOn == tuningModeOn()) { + strError = "Tuning mode is already in the state requested"; + return false; + } // Tuning allowed? if (bOn && !getConstFrameworkConfiguration()->isTuningAllowed()) { @@ -1876,17 +2123,14 @@ bool CParameterMgr::setTuningMode(bool bOn, string& strError) return false; } // Lock state - CAutoLock autoLock(&_blackboardMutex); + lock_guard<mutex> autoLock(getBlackboardMutex()); // Warn domains about exiting tuning mode - if (!bOn && _bTuningModeIsOn) { + if (!bOn) { // Ensure application of currently selected configurations // Force-apply configurations doApplyConfigurations(true); - - // Turn auto sync back on - _bAutoSyncOn = true; } // Store @@ -1924,17 +2168,13 @@ bool CParameterMgr::outputRawFormatIsHex() /// Sync // Automatic hardware synchronization control (during tuning session) -bool CParameterMgr::setAutoSync(bool bAutoSyncOn, string& strError) +bool CParameterMgr::setAutoSync(bool bAutoSyncOn, string &strError) { - // Check tuning mode - if (!checkTuningModeOn(strError)) { - - return false; - } // Warn domains about turning auto sync back on if (bAutoSyncOn && !_bAutoSyncOn) { - // Do the synchronization at system class level (could be optimized by keeping track of all modified parameters) + // Do the synchronization at system class level (could be optimized by keeping track of all + // modified parameters) if (!sync(strError)) { return false; @@ -1953,13 +2193,8 @@ bool CParameterMgr::autoSyncOn() const } // Manual hardware synchronization control (during tuning session) -bool CParameterMgr::sync(string& strError) +bool CParameterMgr::sync(string &strError) { - // Check tuning mode - if (!checkTuningModeOn(strError)) { - - return false; - } // Warn domains about turning auto sync back on if (_bAutoSyncOn) { @@ -1974,10 +2209,10 @@ bool CParameterMgr::sync(string& strError) getConstSystemClass()->fillSyncerSet(syncerSet); // Sync - list<string> lstrError; - if (! syncerSet.sync(*_pMainParameterBlackboard, false, &lstrError)){ + core::Results error; + if (!syncerSet.sync(*_pMainParameterBlackboard, false, &error)) { - CUtility::asString(lstrError, strError); + strError = utility::asString(error); return false; }; @@ -1985,8 +2220,9 @@ bool CParameterMgr::sync(string& strError) } // Configuration/Domains handling -bool CParameterMgr::createDomain(const string& strName, string& strError) +bool CParameterMgr::createDomain(const string &strName, string &strError) { + LOG_CONTEXT("Creating configurable domain " + strName); // Check tuning mode if (!checkTuningModeOn(strError)) { @@ -1994,190 +2230,280 @@ bool CParameterMgr::createDomain(const string& strName, string& strError) } // Delegate to configurable domains - return getConfigurableDomains()->createDomain(strName, strError); + return logResult(getConfigurableDomains()->createDomain(strName, strError), strError); } -bool CParameterMgr::deleteDomain(const string& strName, string& strError) +bool CParameterMgr::deleteDomain(const string &strName, string &strError) { + LOG_CONTEXT("Deleting configurable domain '" + strName + "'"); + // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail: " << strError; return false; } // Delegate to configurable domains - return getConfigurableDomains()->deleteDomain(strName, strError); + return logResult(getConfigurableDomains()->deleteDomain(strName, strError), strError); } -bool CParameterMgr::renameDomain(const string& strName, const string& strNewName, string& strError) +bool CParameterMgr::renameDomain(const string &strName, const string &strNewName, string &strError) { + LOG_CONTEXT("Renaming configurable domain '" + strName + "' to '" + strNewName + "'"); + // Delegate to configurable domains - return getConfigurableDomains()->renameDomain(strName, strNewName, strError); + return logResult(getConfigurableDomains()->renameDomain(strName, strNewName, strError), + strError); } -bool CParameterMgr::deleteAllDomains(string& strError) +bool CParameterMgr::deleteAllDomains(string &strError) { + LOG_CONTEXT("Deleting all configurable domains"); + // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail: " << strError; return false; } // Delegate to configurable domains getConfigurableDomains()->deleteAllDomains(); + info() << "Success"; return true; } -bool CParameterMgr::setSequenceAwareness(const string& strName, bool bSequenceAware, string& strResult) +bool CParameterMgr::setSequenceAwareness(const string &strName, bool bSequenceAware, + string &strResult) { + LOG_CONTEXT("Making domain '" + strName + "' sequence " + + (bSequenceAware ? "aware" : "unaware")); // Check tuning mode if (!checkTuningModeOn(strResult)) { + warning() << "Fail: " << strResult; return false; } - return getConfigurableDomains()->setSequenceAwareness(strName, bSequenceAware, strResult); + return logResult( + getConfigurableDomains()->setSequenceAwareness(strName, bSequenceAware, strResult), + strResult); } -bool CParameterMgr::getSequenceAwareness(const string& strName, bool& bSequenceAware, - string& strResult) +bool CParameterMgr::getSequenceAwareness(const string &strName, bool &bSequenceAware, + string &strResult) { return getConfigurableDomains()->getSequenceAwareness(strName, bSequenceAware, strResult); } -bool CParameterMgr::createConfiguration(const string& strDomain, const string& strConfiguration, string& strError) +bool CParameterMgr::createConfiguration(const string &strDomain, const string &strConfiguration, + string &strError) { + LOG_CONTEXT("Creating domain configuration '" + strConfiguration + "' into domain '" + + strDomain + "'"); // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail: " << strError; return false; } // Delegate to configurable domains - return getConfigurableDomains()->createConfiguration(strDomain, strConfiguration, _pMainParameterBlackboard, strError); + return logResult(getConfigurableDomains()->createConfiguration( + strDomain, strConfiguration, _pMainParameterBlackboard, strError), + strError); } -bool CParameterMgr::renameConfiguration(const string& strDomain, const string& strConfiguration, - const string& strNewConfiguration, string& strError) +bool CParameterMgr::renameConfiguration(const string &strDomain, const string &strConfiguration, + const string &strNewConfiguration, string &strError) { - return getConfigurableDomains()->renameConfiguration(strDomain, strConfiguration, - strNewConfiguration, strError); + LOG_CONTEXT("Renaming domain '" + strDomain + "''s configuration '" + strConfiguration + + "' to '" + strNewConfiguration + "'"); + + return logResult(getConfigurableDomains()->renameConfiguration(strDomain, strConfiguration, + strNewConfiguration, strError), + strError); } -bool CParameterMgr::deleteConfiguration(const string& strDomain, const string& strConfiguration, string& strError) +bool CParameterMgr::deleteConfiguration(const string &strDomain, const string &strConfiguration, + string &strError) { + LOG_CONTEXT("Deleting configuration '" + strConfiguration + "' from domain '" + strDomain + + "'"); + // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail:" << strError; return false; } // Delegate to configurable domains - return getConfigurableDomains()->deleteConfiguration(strDomain, strConfiguration, strError); + return logResult( + getConfigurableDomains()->deleteConfiguration(strDomain, strConfiguration, strError), + strError); } -bool CParameterMgr::restoreConfiguration(const string& strDomain, const string& strConfiguration, list<string>& lstrError) +bool CParameterMgr::restoreConfiguration(const string &strDomain, const string &strConfiguration, + core::Results &errors) { string strError; + LOG_CONTEXT("Restoring domain '" + strDomain + "''s configuration '" + strConfiguration + + "' to parameter blackboard"); // Check tuning mode if (!checkTuningModeOn(strError)) { - lstrError.push_back(strError); + errors.push_back(strError); + warning() << "Fail:" << strError; return false; } // Delegate to configurable domains - return getConstConfigurableDomains()->restoreConfiguration(strDomain, strConfiguration, _pMainParameterBlackboard, _bAutoSyncOn, lstrError); + return logResult( + getConstConfigurableDomains()->restoreConfiguration( + strDomain, strConfiguration, _pMainParameterBlackboard, _bAutoSyncOn, errors), + strError); } -bool CParameterMgr::saveConfiguration(const string& strDomain, const string& strConfiguration, string& strError) +bool CParameterMgr::saveConfiguration(const string &strDomain, const string &strConfiguration, + string &strError) { + LOG_CONTEXT("Saving domain '" + strDomain + "' configuration '" + strConfiguration + + "' from parameter blackboard"); // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail:" << strError; return false; } // Delegate to configurable domains - return getConfigurableDomains()->saveConfiguration(strDomain, strConfiguration, _pMainParameterBlackboard, strError); + return logResult(getConfigurableDomains()->saveConfiguration( + strDomain, strConfiguration, _pMainParameterBlackboard, strError), + strError); } // Configurable element - domain association -bool CParameterMgr::addConfigurableElementToDomain(const string& strDomain, const string& strConfigurableElementPath, string& strError) +bool CParameterMgr::addConfigurableElementToDomain(const string &strDomain, + const string &strConfigurableElementPath, + string &strError) { + LOG_CONTEXT("Adding configurable element '" + strConfigurableElementPath + "' to domain '" + + strDomain + "'"); // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail: " << strError; return false; } CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(strConfigurableElementPath, &pLocatedElement, strError)) { + warning() << "Fail: " << strError; return false; } // Convert element - CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pLocatedElement); + CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(pLocatedElement); // Delegate - return getConfigurableDomains()->addConfigurableElementToDomain(strDomain, pConfigurableElement, _pMainParameterBlackboard, strError); + core::Results infos; + bool isSuccess = getConfigurableDomains()->addConfigurableElementToDomain( + strDomain, pConfigurableElement, _pMainParameterBlackboard, infos); + + if (isSuccess) { + info() << infos; + } else { + warning() << infos; + } + + strError = utility::asString(infos); + return isSuccess; } -bool CParameterMgr::removeConfigurableElementFromDomain(const string& strDomain, const string& strConfigurableElementPath, string& strError) +bool CParameterMgr::removeConfigurableElementFromDomain(const string &strDomain, + const string &strConfigurableElementPath, + string &strError) { + LOG_CONTEXT("Removing configurable element '" + strConfigurableElementPath + "' from domain '" + + strDomain + "'"); + // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail:" << strError; return false; } CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(strConfigurableElementPath, &pLocatedElement, strError)) { + warning() << "Fail:" << strError; return false; } // Convert element - CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pLocatedElement); + CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(pLocatedElement); // Delegate - return getConfigurableDomains()->removeConfigurableElementFromDomain(strDomain, pConfigurableElement, strError); + return logResult(getConfigurableDomains()->removeConfigurableElementFromDomain( + strDomain, pConfigurableElement, strError), + strError); } -bool CParameterMgr::split(const string& strDomain, const string& strConfigurableElementPath, string& strError) +bool CParameterMgr::split(const string &strDomain, const string &strConfigurableElementPath, + string &strError) { + LOG_CONTEXT("Splitting configurable element '" + strConfigurableElementPath + "' domain '" + + strDomain + "'"); // Check tuning mode if (!checkTuningModeOn(strError)) { + warning() << "Fail:" << strError; return false; } CElementLocator elementLocator(getSystemClass()); - CElement* pLocatedElement = NULL; + CElement *pLocatedElement = NULL; if (!elementLocator.locate(strConfigurableElementPath, &pLocatedElement, strError)) { + warning() << "Fail: " << strError; return false; } // Convert element - CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pLocatedElement); + CConfigurableElement *pConfigurableElement = + static_cast<CConfigurableElement *>(pLocatedElement); // Delegate - return getConfigurableDomains()->split(strDomain, pConfigurableElement, strError); + core::Results infos; + bool isSuccess = getConfigurableDomains()->split(strDomain, pConfigurableElement, infos); + + if (isSuccess) { + info() << infos; + } else { + warning() << infos; + } + + strError = utility::asString(infos); + return isSuccess; } -bool CParameterMgr::setElementSequence(const string& strDomain, const string& strConfiguration, - const std::vector<string>& astrNewElementSequence, - string& strError) +bool CParameterMgr::setElementSequence(const string &strDomain, const string &strConfiguration, + const std::vector<string> &astrNewElementSequence, + string &strError) { // Check tuning mode if (!checkTuningModeOn(strError)) { @@ -2186,31 +2512,31 @@ bool CParameterMgr::setElementSequence(const string& strDomain, const string& st } return getConfigurableDomains()->setElementSequence(strDomain, strConfiguration, - astrNewElementSequence, strError); + astrNewElementSequence, strError); } -bool CParameterMgr::getApplicationRule(const string& strDomain, const string& strConfiguration, - string& strResult) +bool CParameterMgr::getApplicationRule(const string &strDomain, const string &strConfiguration, + string &strResult) { return getConfigurableDomains()->getApplicationRule(strDomain, strConfiguration, strResult); } -bool CParameterMgr::setApplicationRule(const string& strDomain, const string& strConfiguration, - const string& strApplicationRule, string& strError) +bool CParameterMgr::setApplicationRule(const string &strDomain, const string &strConfiguration, + const string &strApplicationRule, string &strError) { - return getConfigurableDomains()->setApplicationRule(strDomain, strConfiguration, - strApplicationRule, getConstSelectionCriteria()->getSelectionCriteriaDefinition(), - strError); + return getConfigurableDomains()->setApplicationRule( + strDomain, strConfiguration, strApplicationRule, + getConstSelectionCriteria()->getSelectionCriteriaDefinition(), strError); } -bool CParameterMgr::clearApplicationRule(const string& strDomain, const string& strConfiguration, - string& strError) +bool CParameterMgr::clearApplicationRule(const string &strDomain, const string &strConfiguration, + string &strError) { return getConfigurableDomains()->clearApplicationRule(strDomain, strConfiguration, strError); } -bool CParameterMgr::importDomainsXml(const string& xmlSource, bool withSettings, - bool fromFile, string& errorMsg) +bool CParameterMgr::importDomainsXml(const string &xmlSource, bool withSettings, bool fromFile, + string &errorMsg) { // Check tuning mode if (!checkTuningModeOn(errorMsg)) { @@ -2218,11 +2544,11 @@ bool CParameterMgr::importDomainsXml(const string& xmlSource, bool withSettings, return false; } - CAutoLog autoLog(this, string("Importing domains from ") + - (fromFile ? ("\"" + xmlSource + "\"") : "a user-provided buffer")); + LOG_CONTEXT("Importing domains from " + + (fromFile ? ("\"" + xmlSource + "\"") : "a user-provided buffer")); // Root element - CConfigurableDomains* pConfigurableDomains = getConfigurableDomains(); + CConfigurableDomains *pConfigurableDomains = getConfigurableDomains(); bool importSuccess = wrapLegacyXmlImport(xmlSource, fromFile, withSettings, *pConfigurableDomains, "SystemClassName", errorMsg); @@ -2236,20 +2562,20 @@ bool CParameterMgr::importDomainsXml(const string& xmlSource, bool withSettings, return importSuccess; } -bool CParameterMgr::importSingleDomainXml(const string& xmlSource, bool overwrite, - bool withSettings, bool fromFile, string& errorMsg) +bool CParameterMgr::importSingleDomainXml(const string &xmlSource, bool overwrite, + bool withSettings, bool fromFile, string &errorMsg) { if (!checkTuningModeOn(errorMsg)) { return false; } - CAutoLog autoLog(this, string("Importing a single domain from ") + - (fromFile ? ("\"" + xmlSource + "\"") : "a user-provided buffer")); + LOG_CONTEXT("Importing a single domain from " + + (fromFile ? ('"' + xmlSource + '"') : "a user-provided buffer")); // We initialize the domain with an empty name but since we have set the isDomainStandalone // context, the name will be retrieved during de-serialization - std::auto_ptr<CConfigurableDomain> standaloneDomain(new CConfigurableDomain()); + auto standaloneDomain = utility::make_unique<CConfigurableDomain>(); if (!wrapLegacyXmlImport(xmlSource, fromFile, withSettings, *standaloneDomain, "", errorMsg)) { return false; @@ -2264,44 +2590,39 @@ bool CParameterMgr::importSingleDomainXml(const string& xmlSource, bool overwrit return true; } -bool CParameterMgr::wrapLegacyXmlImport(const string& xmlSource, bool fromFile, - bool withSettings, CElement& element, - const string& nameAttributeName, string& errorMsg) +bool CParameterMgr::wrapLegacyXmlImport(const string &xmlSource, bool fromFile, bool withSettings, + CElement &element, const string &nameAttributeName, + string &errorMsg) { CXmlDomainImportContext xmlDomainImportContext(errorMsg, withSettings, *getSystemClass()); // Selection criteria definition for rule creation xmlDomainImportContext.setSelectionCriteriaDefinition( - getConstSelectionCriteria()->getSelectionCriteriaDefinition()); + getConstSelectionCriteria()->getSelectionCriteriaDefinition()); // It doesn't make sense to resolve XIncludes on an imported file because // we can't reliably decide of a "base url" - _xmlDoc *doc = CXmlDocSource::mkXmlDoc(xmlSource, fromFile, false, errorMsg); + _xmlDoc *doc = CXmlDocSource::mkXmlDoc(xmlSource, fromFile, false, xmlDomainImportContext); if (doc == NULL) { return false; } - return xmlParse(xmlDomainImportContext, &element, doc, "", EParameterConfigurationLibrary, nameAttributeName); + return xmlParse(xmlDomainImportContext, &element, doc, "", EParameterConfigurationLibrary, true, + nameAttributeName); } -bool CParameterMgr::serializeElement(std::ostream& output, - CXmlSerializingContext& xmlSerializingContext, - const CElement& element) const +bool CParameterMgr::serializeElement(std::ostream &output, + CXmlSerializingContext &xmlSerializingContext, + const CElement &element) const { if (!output.good()) { xmlSerializingContext.setError("Can't write XML: the output is in a bad state."); return false; } - // Get Schema file associated to root element - string xmlSchemaFilePath = _strSchemaFolderLocation + "/" + - element.getKind() + ".xsd"; - // Use a doc source by loading data from instantiated Configurable Domains CXmlMemoryDocSource memorySource(&element, _bValidateSchemasOnStart, - element.getKind(), - xmlSchemaFilePath, - "parameter-framework", + element.getXmlElementName(), "parameter-framework", getVersion()); // Use a doc sink to write the doc data in a stream @@ -2312,25 +2633,25 @@ bool CParameterMgr::serializeElement(std::ostream& output, return processSuccess; } -bool CParameterMgr::exportDomainsXml(string& xmlDest, bool withSettings, bool toFile, - string& errorMsg) const +bool CParameterMgr::exportDomainsXml(string &xmlDest, bool withSettings, bool toFile, + string &errorMsg) const { - CAutoLog autoLog(this, string("Exporting domains to ") + - (toFile ? ("\"" + xmlDest + "\"") : " a user-provided buffer")); + LOG_CONTEXT("Exporting domains to " + + (toFile ? ('"' + xmlDest + '"') : "a user-provided buffer")); - const CConfigurableDomains* configurableDomains = getConstConfigurableDomains(); + const CConfigurableDomains *configurableDomains = getConstConfigurableDomains(); return wrapLegacyXmlExport(xmlDest, toFile, withSettings, *configurableDomains, errorMsg); } -bool CParameterMgr::exportSingleDomainXml(string& xmlDest, const string& domainName, - bool withSettings, bool toFile, string& errorMsg) const +bool CParameterMgr::exportSingleDomainXml(string &xmlDest, const string &domainName, + bool withSettings, bool toFile, string &errorMsg) const { - CAutoLog autoLog(this, string("Exporting single domain '") + domainName + "' to " + - (toFile ? ("\"" + xmlDest + "\"") : " a user-provided buffer")); + LOG_CONTEXT("Exporting single domain '" + domainName + "' to " + + (toFile ? ('"' + xmlDest + '"') : "a user-provided buffer")); // Element to be serialized - const CConfigurableDomain* requestedDomain = + const CConfigurableDomain *requestedDomain = getConstConfigurableDomains()->findConfigurableDomain(domainName, errorMsg); if (requestedDomain == NULL) { @@ -2340,8 +2661,8 @@ bool CParameterMgr::exportSingleDomainXml(string& xmlDest, const string& domainN return wrapLegacyXmlExport(xmlDest, toFile, withSettings, *requestedDomain, errorMsg); } -bool CParameterMgr::wrapLegacyXmlExport(string& xmlDest, bool toFile, bool withSettings, - const CElement& element, string& errorMsg) const +bool CParameterMgr::wrapLegacyXmlExport(string &xmlDest, bool toFile, bool withSettings, + const CElement &element, string &errorMsg) const { CXmlDomainExportContext context(errorMsg, withSettings, _bValueSpaceIsRaw, _bOutputRawFormatIsHex); @@ -2353,23 +2674,28 @@ bool CParameterMgr::wrapLegacyXmlExport(string& xmlDest, bool toFile, bool withS } } -bool CParameterMgr::wrapLegacyXmlExportToFile(string& xmlDest, - const CElement& element, +bool CParameterMgr::wrapLegacyXmlExportToFile(string &xmlDest, const CElement &element, CXmlDomainExportContext &context) const { - std::ofstream output(xmlDest.c_str()); + try { + std::ofstream output; + // Force stream to throw instead of using fail/bad bit + // in order to retreive an error message. + output.exceptions(~std::ifstream::goodbit); - if (output.fail()) { - context.setError("Failed to open \"" + xmlDest + "\" for writing."); - return false; - } + output.open(xmlDest.c_str()); + bool status = serializeElement(output, context, element); + output.close(); // Explicit close to detect errors - return serializeElement(output, context, element); + return status; + } catch (std::ofstream::failure &e) { + context.setError("Failed to open \"" + xmlDest + "\" for writing: " + e.what()); + return false; + } } -bool CParameterMgr::wrapLegacyXmlExportToString(string& xmlDest, - const CElement& element, +bool CParameterMgr::wrapLegacyXmlExportToString(string &xmlDest, const CElement &element, CXmlDomainExportContext &context) const { std::ostringstream output; @@ -2383,35 +2709,8 @@ bool CParameterMgr::wrapLegacyXmlExportToString(string& xmlDest, return true; } -// Binary Import/Export -bool CParameterMgr::importDomainsBinary(const string& strFileName, string& strError) -{ - // Check tuning mode - if (!checkTuningModeOn(strError)) { - - return false; - } - - CAutoLog autoLog(this, string("Importing domains from binary file \"") + strFileName + "\""); - // Root element - CConfigurableDomains* pConfigurableDomains = getConfigurableDomains(); - - // Serialize in - return pConfigurableDomains->serializeSettings(strFileName, false, _uiStructureChecksum, strError); -} - -bool CParameterMgr::exportDomainsBinary(const string& strFileName, string& strError) -{ - CAutoLog autoLog(this, string("Exporting domains to binary file \"") + strFileName + "\""); - // Root element - CConfigurableDomains* pConfigurableDomains = getConfigurableDomains(); - - // Serialize out - return pConfigurableDomains->serializeSettings(strFileName, true, _uiStructureChecksum, strError); -} - // For tuning, check we're in tuning mode -bool CParameterMgr::checkTuningModeOn(string& strError) const +bool CParameterMgr::checkTuningModeOn(string &strError) const { // Tuning Mode on? if (!_bTuningModeIsOn) { @@ -2424,13 +2723,13 @@ bool CParameterMgr::checkTuningModeOn(string& strError) const } // Tuning mutex dynamic parameter handling -pthread_mutex_t* CParameterMgr::getBlackboardMutex() +std::mutex &CParameterMgr::getBlackboardMutex() { - return &_blackboardMutex; + return _blackboardMutex; } // Blackboard reference (dynamic parameter handling) -CParameterBlackboard* CParameterMgr::getParameterBlackboard() +CParameterBlackboard *CParameterMgr::getParameterBlackboard() { return _pMainParameterBlackboard; } @@ -2439,46 +2738,76 @@ CParameterBlackboard* CParameterMgr::getParameterBlackboard() void CParameterMgr::feedElementLibraries() { // Global Configuration handling - CElementLibrary* pFrameworkConfigurationLibrary = new CElementLibrary; - - pFrameworkConfigurationLibrary->addElementBuilder("ParameterFrameworkConfiguration", new TElementBuilderTemplate<CParameterFrameworkConfiguration>()); - pFrameworkConfigurationLibrary->addElementBuilder("SubsystemPlugins", new TKindElementBuilderTemplate<CSubsystemPlugins>()); - pFrameworkConfigurationLibrary->addElementBuilder("Location", new TKindElementBuilderTemplate<CPluginLocation>()); - pFrameworkConfigurationLibrary->addElementBuilder("StructureDescriptionFileLocation", new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); - pFrameworkConfigurationLibrary->addElementBuilder("SettingsConfiguration", new TKindElementBuilderTemplate<CFrameworkConfigurationGroup>()); - pFrameworkConfigurationLibrary->addElementBuilder("ConfigurableDomainsFileLocation", new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); - pFrameworkConfigurationLibrary->addElementBuilder("BinarySettingsFileLocation", new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); + CElementLibrary *pFrameworkConfigurationLibrary = new CElementLibrary; + + pFrameworkConfigurationLibrary->addElementBuilder( + "ParameterFrameworkConfiguration", + new TElementBuilderTemplate<CParameterFrameworkConfiguration>()); + pFrameworkConfigurationLibrary->addElementBuilder( + "SubsystemPlugins", new TKindElementBuilderTemplate<CSubsystemPlugins>()); + pFrameworkConfigurationLibrary->addElementBuilder( + "Location", new TKindElementBuilderTemplate<CPluginLocation>()); + pFrameworkConfigurationLibrary->addElementBuilder( + "StructureDescriptionFileLocation", + new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); + pFrameworkConfigurationLibrary->addElementBuilder( + "SettingsConfiguration", new TKindElementBuilderTemplate<CFrameworkConfigurationGroup>()); + pFrameworkConfigurationLibrary->addElementBuilder( + "ConfigurableDomainsFileLocation", + new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); _pElementLibrarySet->addElementLibrary(pFrameworkConfigurationLibrary); // Parameter creation - CElementLibrary* pParameterCreationLibrary = new CElementLibrary; - - pParameterCreationLibrary->addElementBuilder("Subsystem", new CSubsystemElementBuilder(getSystemClass()->getSubsystemLibrary())); - pParameterCreationLibrary->addElementBuilder("ComponentType", new TNamedElementBuilderTemplate<CComponentType>()); - pParameterCreationLibrary->addElementBuilder("Component", new TNamedElementBuilderTemplate<CComponentInstance>()); - pParameterCreationLibrary->addElementBuilder("BitParameter", new TNamedElementBuilderTemplate<CBitParameterType>()); - pParameterCreationLibrary->addElementBuilder("BitParameterBlock", new TNamedElementBuilderTemplate<CBitParameterBlockType>()); - pParameterCreationLibrary->addElementBuilder("StringParameter", new TNamedElementBuilderTemplate<CStringParameterType>()); - pParameterCreationLibrary->addElementBuilder("ParameterBlock", new TNamedElementBuilderTemplate<CParameterBlockType>()); - pParameterCreationLibrary->addElementBuilder("BooleanParameter", new TNamedElementBuilderTemplate<CBooleanParameterType>()); - pParameterCreationLibrary->addElementBuilder("IntegerParameter", new TNamedElementBuilderTemplate<CIntegerParameterType>()); - pParameterCreationLibrary->addElementBuilder("LinearAdaptation", new TElementBuilderTemplate<CLinearParameterAdaptation>()); - pParameterCreationLibrary->addElementBuilder("LogarithmicAdaptation", new TElementBuilderTemplate<CLogarithmicParameterAdaptation>()); - pParameterCreationLibrary->addElementBuilder("EnumParameter", new TNamedElementBuilderTemplate<CEnumParameterType>()); - pParameterCreationLibrary->addElementBuilder("ValuePair", new TElementBuilderTemplate<CEnumValuePair>()); - pParameterCreationLibrary->addElementBuilder("FixedPointParameter", new TNamedElementBuilderTemplate<CFixedPointParameterType>()); - pParameterCreationLibrary->addElementBuilder("SubsystemInclude", new CFileIncluderElementBuilder(_bValidateSchemasOnStart)); + CElementLibrary *pParameterCreationLibrary = new CElementLibrary; + + pParameterCreationLibrary->addElementBuilder( + "Subsystem", new CSubsystemElementBuilder(getSystemClass()->getSubsystemLibrary())); + pParameterCreationLibrary->addElementBuilder( + "ComponentType", new TNamedElementBuilderTemplate<CComponentType>()); + pParameterCreationLibrary->addElementBuilder( + "Component", new TNamedElementBuilderTemplate<CComponentInstance>()); + pParameterCreationLibrary->addElementBuilder( + "BitParameter", new TNamedElementBuilderTemplate<CBitParameterType>()); + pParameterCreationLibrary->addElementBuilder( + "BitParameterBlock", new TNamedElementBuilderTemplate<CBitParameterBlockType>()); + pParameterCreationLibrary->addElementBuilder( + "StringParameter", new TNamedElementBuilderTemplate<CStringParameterType>()); + pParameterCreationLibrary->addElementBuilder( + "ParameterBlock", new TNamedElementBuilderTemplate<CParameterBlockType>()); + pParameterCreationLibrary->addElementBuilder( + "BooleanParameter", new TNamedElementBuilderTemplate<CBooleanParameterType>()); + pParameterCreationLibrary->addElementBuilder( + "IntegerParameter", new TNamedElementBuilderTemplate<CIntegerParameterType>()); + pParameterCreationLibrary->addElementBuilder( + "LinearAdaptation", new TElementBuilderTemplate<CLinearParameterAdaptation>()); + pParameterCreationLibrary->addElementBuilder( + "LogarithmicAdaptation", new TElementBuilderTemplate<CLogarithmicParameterAdaptation>()); + pParameterCreationLibrary->addElementBuilder( + "EnumParameter", new TNamedElementBuilderTemplate<CEnumParameterType>()); + pParameterCreationLibrary->addElementBuilder("ValuePair", + new TElementBuilderTemplate<CEnumValuePair>()); + pParameterCreationLibrary->addElementBuilder( + "FixedPointParameter", new TNamedElementBuilderTemplate<CFixedPointParameterType>()); + pParameterCreationLibrary->addElementBuilder( + "FloatingPointParameter", new TNamedElementBuilderTemplate<CFloatingPointParameterType>); + pParameterCreationLibrary->addElementBuilder( + "SubsystemInclude", + new CFileIncluderElementBuilder(_bValidateSchemasOnStart, getSchemaUri())); _pElementLibrarySet->addElementLibrary(pParameterCreationLibrary); // Parameter Configuration Domains creation - CElementLibrary* pParameterConfigurationLibrary = new CElementLibrary; + CElementLibrary *pParameterConfigurationLibrary = new CElementLibrary; - pParameterConfigurationLibrary->addElementBuilder("ConfigurableDomain", new TElementBuilderTemplate<CConfigurableDomain>()); - pParameterConfigurationLibrary->addElementBuilder("Configuration", new TNamedElementBuilderTemplate<CDomainConfiguration>()); - pParameterConfigurationLibrary->addElementBuilder("CompoundRule", new TElementBuilderTemplate<CCompoundRule>()); - pParameterConfigurationLibrary->addElementBuilder("SelectionCriterionRule", new TElementBuilderTemplate<CSelectionCriterionRule>()); + pParameterConfigurationLibrary->addElementBuilder( + "ConfigurableDomain", new TElementBuilderTemplate<CConfigurableDomain>()); + pParameterConfigurationLibrary->addElementBuilder( + "Configuration", new TNamedElementBuilderTemplate<CDomainConfiguration>()); + pParameterConfigurationLibrary->addElementBuilder("CompoundRule", + new TElementBuilderTemplate<CCompoundRule>()); + pParameterConfigurationLibrary->addElementBuilder( + "SelectionCriterionRule", new TElementBuilderTemplate<CSelectionCriterionRule>()); _pElementLibrarySet->addElementLibrary(pParameterConfigurationLibrary); } @@ -2493,139 +2822,135 @@ void CParameterMgr::setForceNoRemoteInterface(bool bForceNoRemoteInterface) _bForceNoRemoteInterface = bForceNoRemoteInterface; } -// Remote Processor Server connection handling -bool CParameterMgr::handleRemoteProcessingInterface(string& strError) +CParameterMgr::CommandHandler CParameterMgr::createCommandHandler() { - CAutoLog autoLog(this, "Handling remote processing interface"); + auto commandHandler = utility::make_unique<CCommandHandler>(this); - if (_bForceNoRemoteInterface) { - // The user requested not to start the remote interface - return true; + // Add command parsers + for (const auto &remoteCommandParserItem : gastRemoteCommandParserItems) { + commandHandler->addCommandParser( + remoteCommandParserItem._pcCommandName, remoteCommandParserItem._pfnParser, + remoteCommandParserItem._minArgumentCount, remoteCommandParserItem._pcHelp, + remoteCommandParserItem._pcDescription); } - // Start server if tuning allowed - if (getConstFrameworkConfiguration()->isTuningAllowed()) { - - log_info("Loading remote processor library"); - - // Load library - _pvLibRemoteProcessorHandle = dlopen("libremote-processor.so", RTLD_NOW); - - if (!_pvLibRemoteProcessorHandle) { - - // Return error - const char* pcError = dlerror(); - - if (pcError) { - - strError = pcError; - } else { - - strError = "Unable to load libremote-processor.so library"; - } - - return false; - } - - CreateRemoteProcessorServer pfnCreateRemoteProcessorServer = (CreateRemoteProcessorServer)dlsym(_pvLibRemoteProcessorHandle, "createRemoteProcessorServer"); - - if (!pfnCreateRemoteProcessorServer) { + return commandHandler; +} - strError = "libremote-process.so does not contain createRemoteProcessorServer symbol."; +bool CParameterMgr::isRemoteInterfaceRequired() +{ + // The remote interface should only be started if the client didn't + // explicitly forbid it and if the configuration file allows it. + return (not _bForceNoRemoteInterface) and getConstFrameworkConfiguration()->isTuningAllowed(); +} - return false; - } +// Remote Processor Server connection handling +bool CParameterMgr::handleRemoteProcessingInterface(string &strError) +{ + LOG_CONTEXT("Handling remote processing interface"); - // Create server - _pRemoteProcessorServer = pfnCreateRemoteProcessorServer(getConstFrameworkConfiguration()->getServerPort(), _pCommandHandler); + if (not isRemoteInterfaceRequired()) { + return true; + } - log_info("Starting remote processor server on port %d", getConstFrameworkConfiguration()->getServerPort()); - // Start - if (!_pRemoteProcessorServer->start(strError)) { + auto port = getConstFrameworkConfiguration()->getServerPort(); - ostringstream oss; - oss << "ParameterMgr: Unable to start remote processor server on port " - << getConstFrameworkConfiguration()->getServerPort(); - strError = oss.str() + ": " + strError; + try { + // The ownership of remoteComandHandler is given to Bg remote processor server. + _pRemoteProcessorServer = new BackgroundRemoteProcessorServer(port, createCommandHandler()); + } catch (std::runtime_error &e) { + strError = string("ParameterMgr: Unable to create Remote Processor Server: ") + e.what(); + return false; + } - return false; - } + if (_pRemoteProcessorServer == NULL) { + strError = "ParameterMgr: Unable to create Remote Processor Server"; + return false; } + if (!_pRemoteProcessorServer->start(strError)) { + ostringstream oss; + oss << "ParameterMgr: Unable to start remote processor server on port " << port; + strError = oss.str() + ": " + strError; + return false; + } + info() << "Remote Processor Server started on port " << port; return true; } // Children typwise access -CParameterFrameworkConfiguration* CParameterMgr::getFrameworkConfiguration() +CParameterFrameworkConfiguration *CParameterMgr::getFrameworkConfiguration() { - return static_cast<CParameterFrameworkConfiguration*>(getChild(EFrameworkConfiguration)); + return static_cast<CParameterFrameworkConfiguration *>(getChild(EFrameworkConfiguration)); } -const CParameterFrameworkConfiguration* CParameterMgr::getConstFrameworkConfiguration() +const CParameterFrameworkConfiguration *CParameterMgr::getConstFrameworkConfiguration() { return getFrameworkConfiguration(); } -CSelectionCriteria* CParameterMgr::getSelectionCriteria() +CSelectionCriteria *CParameterMgr::getSelectionCriteria() { - return static_cast<CSelectionCriteria*>(getChild(ESelectionCriteria)); + return static_cast<CSelectionCriteria *>(getChild(ESelectionCriteria)); } -const CSelectionCriteria* CParameterMgr::getConstSelectionCriteria() +const CSelectionCriteria *CParameterMgr::getConstSelectionCriteria() { - return static_cast<const CSelectionCriteria*>(getChild(ESelectionCriteria)); + return static_cast<const CSelectionCriteria *>(getChild(ESelectionCriteria)); } -CSystemClass* CParameterMgr::getSystemClass() +CSystemClass *CParameterMgr::getSystemClass() { - return static_cast<CSystemClass*>(getChild(ESystemClass)); + return static_cast<CSystemClass *>(getChild(ESystemClass)); } -const CSystemClass* CParameterMgr::getConstSystemClass() const +const CSystemClass *CParameterMgr::getConstSystemClass() const { - return static_cast<const CSystemClass*>(getChild(ESystemClass)); + return static_cast<const CSystemClass *>(getChild(ESystemClass)); } // Configurable Domains -CConfigurableDomains* CParameterMgr::getConfigurableDomains() +CConfigurableDomains *CParameterMgr::getConfigurableDomains() { - return static_cast<CConfigurableDomains*>(getChild(EConfigurableDomains)); + return static_cast<CConfigurableDomains *>(getChild(EConfigurableDomains)); } -const CConfigurableDomains* CParameterMgr::getConstConfigurableDomains() +const CConfigurableDomains *CParameterMgr::getConstConfigurableDomains() { - return static_cast<const CConfigurableDomains*>(getChild(EConfigurableDomains)); + return static_cast<const CConfigurableDomains *>(getChild(EConfigurableDomains)); } -const CConfigurableDomains* CParameterMgr::getConstConfigurableDomains() const +const CConfigurableDomains *CParameterMgr::getConstConfigurableDomains() const { - return static_cast<const CConfigurableDomains*>(getChild(EConfigurableDomains)); + return static_cast<const CConfigurableDomains *>(getChild(EConfigurableDomains)); } // Apply configurations void CParameterMgr::doApplyConfigurations(bool bForce) { + LOG_CONTEXT("Applying configurations"); + CSyncerSet syncerSet; + core::Results infos; // Check subsystems that need resync - getSystemClass()->checkForSubsystemsToResync(syncerSet); + getSystemClass()->checkForSubsystemsToResync(syncerSet, infos); // Ensure application of currently selected configurations - getConfigurableDomains()->apply(_pMainParameterBlackboard, syncerSet, bForce); + getConfigurableDomains()->apply(_pMainParameterBlackboard, syncerSet, bForce, infos); + info() << infos; - // Reset the modified status of the current criteria to indicate that a new configuration has been applied + // Reset the modified status of the current criteria to indicate that a new configuration has + // been applied getSelectionCriteria()->resetModifiedStatus(); } // Export to XML string -bool CParameterMgr::exportElementToXMLString(const IXmlSource* pXmlSource, - const string& strRootElementType, - string& strResult) const +bool CParameterMgr::exportElementToXMLString(const IXmlSource *pXmlSource, + const string &strRootElementType, + CXmlSerializingContext &&xmlSerializingContext, + string &strResult) const { - string strError; - - CXmlSerializingContext xmlSerializingContext(strError); - // Use a doc source by loading data from instantiated Configurable Domains CXmlMemoryDocSource memorySource(pXmlSource, false, strRootElementType); @@ -2636,11 +2961,30 @@ bool CParameterMgr::exportElementToXMLString(const IXmlSource* pXmlSource, // Do the export bool bProcessSuccess = streamSink.process(memorySource, xmlSerializingContext); - if (bProcessSuccess) { - strResult = output.str(); + strResult = output.str(); + + return bProcessSuccess; +} + +bool CParameterMgr::logResult(bool isSuccess, const std::string &result) +{ + std::string log = result.empty() ? "" : ": " + result; + + if (isSuccess) { + info() << "Success" << log; } else { - strResult = strError; + warning() << "Fail" << log; } - return bProcessSuccess; + return isSuccess; +} + +log::details::Info CParameterMgr::info() +{ + return _logger.info(); +} + +log::details::Warning CParameterMgr::warning() +{ + return _logger.warning(); } diff --git a/parameter/ParameterMgr.h b/parameter/ParameterMgr.h index cd2f664..784f55f 100644 --- a/parameter/ParameterMgr.h +++ b/parameter/ParameterMgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,10 +29,9 @@ */ #pragma once -#include <pthread.h> +#include <mutex> #include <map> #include <vector> -#include <list> #include "RemoteCommandHandlerTemplate.h" #include "PathNavigator.h" #include "SelectionCriterionType.h" @@ -41,17 +40,21 @@ #include "XmlDocSink.h" #include "XmlDocSource.h" #include "XmlDomainExportContext.h" +#include "Results.h" +#include "ElementHandle.h" +#include <log/LogWrapper.h> +#include <log/Context.h> -#include <string> -#include <ostream> #include <istream> +#include <memory> +#include <ostream> +#include <string> class CElementLibrarySet; class CSubsystemLibrary; class CSystemClass; class CSelectionCriteria; class CParameterFrameworkConfiguration; -class CSystemClassConfiguration; class CParameterBlackboard; class CConfigurableDomains; class IRemoteProcessorServerInterface; @@ -62,56 +65,28 @@ class CConfigurableElement; class CParameterMgr : private CElement { - enum ChildElement { + enum ChildElement + { EFrameworkConfiguration, ESelectionCriteria, ESystemClass, EConfigurableDomains }; - enum ElementLibrary { + enum ElementLibrary + { EFrameworkConfigurationLibrary, EParameterCreationLibrary, EParameterConfigurationLibrary }; - // Remote command parsers - typedef TRemoteCommandHandlerTemplate<CParameterMgr> CCommandHandler; - - typedef CCommandHandler::CommandStatus (CParameterMgr::*RemoteCommandParser)(const IRemoteCommand& remoteCommand, std::string& strResult); - - // Parser descriptions - struct SRemoteCommandParserItem - { - const char* _pcCommandName; - CParameterMgr::RemoteCommandParser _pfnParser; - uint32_t _uiMinArgumentCount; - const char* _pcHelp; - const char* _pcDescription; - }; - // Version - static const uint32_t guiEditionMajor = 2; - static const uint32_t guiEditionMinor = 6; - static const uint32_t guiRevision = 0; - // Parameter handle friendship - friend class CParameterHandle; -public: - // Logger interface - class ILogger - { - public: - virtual void log(bool bIsWarning, const std::string& strLog) = 0; - protected: - virtual ~ILogger() {} - }; + friend class ElementHandle; +public: // Construction - CParameterMgr(const std::string& strConfigurationFilePath); + CParameterMgr(const std::string &strConfigurationFilePath, core::log::ILogger &logger); virtual ~CParameterMgr(); - // Logging - void setLogger(ILogger* pLogger); - /** Load plugins, structures and settings from the config file given. * * @param[out] strError is a std::string describing the error if an error occurred @@ -119,19 +94,32 @@ public: * * @return true if no error occurred, false otherwise. */ - bool load(std::string& strError); + bool load(std::string &strError); + + // Remote command parsers + using CommandHandler = std::unique_ptr<TRemoteCommandHandlerTemplate<CParameterMgr>>; + + /** Create and return a command handler for this ParameterMgr instance + * + * @returns a Command Handler + */ + CommandHandler createCommandHandler(); // Selection Criteria - CSelectionCriterionType* createSelectionCriterionType(bool bIsInclusive); - CSelectionCriterion* createSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pSelectionCriterionType); + CSelectionCriterionType *createSelectionCriterionType(bool bIsInclusive); + CSelectionCriterion *createSelectionCriterion( + const std::string &strName, const CSelectionCriterionType *pSelectionCriterionType); // Selection criterion retrieval - CSelectionCriterion* getSelectionCriterion(const std::string& strName); + CSelectionCriterion *getSelectionCriterion(const std::string &strName); // Configuration application void applyConfigurations(); - /** - * Returns the CConfigurableElement corresponding to the path given in argument. + /** const version of getConfigurableElement */ + const CConfigurableElement *getConfigurableElement(const std::string &strPath, + std::string &strError) const; + + /** Returns the CConfigurableElement corresponding to the path given in argument. * * @param[in] strPath A std::string representing a path to an element. * @param[out] strError Error message @@ -139,10 +127,22 @@ public: * @return A const pointer to the corresponding CConfigurableElement. * On error, NULL is returned and the error is explained in strError. */ - const CConfigurableElement* getConfigurableElement(const std::string& strPath, - std::string& strError) const; + CConfigurableElement *getConfigurableElement(const std::string &strPath, std::string &strError); // Dynamic parameter handling - CParameterHandle* createParameterHandle(const std::string& strPath, std::string& strError); + CParameterHandle *createParameterHandle(const std::string &strPath, std::string &strError); + + /** Creates a handle to a configurable element. + * + * The returned object is owned by the client who is responsible to delete it. + * + * @param[in] path A string representing a path to a configurable element. + * @param[out] error On error: an human readable error message + * On success: undefined + * + * @return An element handle on success + * nullptr on error + */ + ElementHandle *createElementHandle(const std::string &path, std::string &error); /** Is the remote interface forcefully disabled ? */ @@ -178,19 +178,19 @@ public: * * @return failure on failed settings load policy state. */ - bool getFailureOnFailedSettingsLoad(); + bool getFailureOnFailedSettingsLoad() const; - /** Get the path to the directory containing the XML Schemas + /** Get the XML Schemas URI * - * @returns the directory containing the XML Schemas + * @returns the XML Schemas URI */ - const std::string& getSchemaFolderLocation() const; + const std::string &getSchemaUri() const; - /** Override the directory containing the XML Schemas + /** Override the XML Schemas URI * - * @param[in] strSchemaFolderLocation directory containing the XML Schemas + * @param[in] schemaUri XML Schemas URI */ - void setSchemaFolderLocation(const std::string& strSchemaFolderLocation); + void setSchemaUri(const std::string &schemaUri); /** Should .xml files be validated on start ? * @@ -211,8 +211,16 @@ public: bool getValidateSchemasOnStart() const; //////////// Tuning ///////////// - // Tuning mode - bool setTuningMode(bool bOn, std::string& strError); + /** + * Activate / deactivate the tuning mode. + * + * @param[in] bOn true if tuning mode activation is requested, false for desactivation + * @param[out] strError human readable error + * @return true if request is successful, false if the Parameter Manager is already in the mode + * requested or in case of error. + * If false, strError is set with the associated human readable error. + */ + bool setTuningMode(bool bOn, std::string &strError); bool tuningModeOn() const; // Current value space for user set/get value interpretation @@ -224,12 +232,13 @@ public: bool outputRawFormatIsHex(); // Automatic hardware synchronization control (during tuning session) - bool setAutoSync(bool bAutoSyncOn, std::string& strError); + bool setAutoSync(bool bAutoSyncOn, std::string &strError); bool autoSyncOn() const; - bool sync(std::string& strError); + bool sync(std::string &strError); // User set/get parameters - bool accessParameterValue(const std::string& strPath, std::string& strValue, bool bSet, std::string& strError); + bool accessParameterValue(const std::string &strPath, std::string &strValue, bool bSet, + std::string &strError); /** * Returns the element mapping corresponding to the path given in parameter. * @@ -238,42 +247,61 @@ public: * * @return true if a mapping was found for this element */ - bool getParameterMapping(const std::string& strPath, std::string& strValue) const; - bool accessConfigurationValue(const std::string &strDomain, const std::string &stConfiguration, const std::string& strPath, std::string& strValue, bool bSet, std::string& strError); + bool getParameterMapping(const std::string &strPath, std::string &strValue) const; + bool accessConfigurationValue(const std::string &strDomain, const std::string &stConfiguration, + const std::string &strPath, std::string &strValue, bool bSet, + std::string &strError); ////////// Configuration/Domains handling ////////////// // Creation/Deletion - bool createDomain(const std::string& strName, std::string& strError); - bool renameDomain(const std::string& strName, const std::string& strNewName, - std::string& strError); - bool deleteDomain(const std::string& strName, std::string& strError); - bool deleteAllDomains(std::string& strError); - bool setSequenceAwareness(const std::string& strName, bool bSequenceAware, - std::string& strResult); - bool getSequenceAwareness(const std::string& strName, bool& bSequenceAware, - std::string& strResult); - bool createConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); - bool deleteConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); - bool renameConfiguration(const std::string& strDomain, const std::string& strConfiguration, const std::string& strNewConfiguration, std::string& strError); - - // Save/Restore - bool restoreConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::list<std::string>& strError); - bool saveConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); + bool createDomain(const std::string &strName, std::string &strError); + bool renameDomain(const std::string &strName, const std::string &strNewName, + std::string &strError); + bool deleteDomain(const std::string &strName, std::string &strError); + bool deleteAllDomains(std::string &strError); + bool setSequenceAwareness(const std::string &strName, bool bSequenceAware, + std::string &strResult); + bool getSequenceAwareness(const std::string &strName, bool &bSequenceAware, + std::string &strResult); + bool createConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); + bool deleteConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); + bool renameConfiguration(const std::string &strDomain, const std::string &strConfiguration, + const std::string &strNewConfiguration, std::string &strError); + + /** Restore a configuration + * + * @param[in] strDomain the domain name + * @param[in] strConfiguration the configuration name + * @param[out] errors errors encountered during restoration + * @return true if success false otherwise + */ + bool restoreConfiguration(const std::string &strDomain, const std::string &strConfiguration, + core::Results &errors); + + bool saveConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); // Configurable element - domain association - bool addConfigurableElementToDomain(const std::string& strDomain, const std::string& strConfigurableElementPath, std::string& strError); - bool removeConfigurableElementFromDomain(const std::string& strDomain, const std::string& strConfigurableElementPath, std::string& strError); - bool split(const std::string& strDomain, const std::string& strConfigurableElementPath, std::string& strError); - bool setElementSequence(const std::string& strDomain, const std::string& strConfiguration, - const std::vector<std::string>& astrNewElementSequence, - std::string& strError); - - bool getApplicationRule(const std::string& strDomain, const std::string& strConfiguration, - std::string& strResult); - bool setApplicationRule(const std::string& strDomain, const std::string& strConfiguration, - const std::string& strApplicationRule, std::string& strError); - bool clearApplicationRule(const std::string& strDomain, const std::string& strConfiguration, - std::string& strError); + bool addConfigurableElementToDomain(const std::string &strDomain, + const std::string &strConfigurableElementPath, + std::string &strError); + bool removeConfigurableElementFromDomain(const std::string &strDomain, + const std::string &strConfigurableElementPath, + std::string &strError); + bool split(const std::string &strDomain, const std::string &strConfigurableElementPath, + std::string &strError); + bool setElementSequence(const std::string &strDomain, const std::string &strConfiguration, + const std::vector<std::string> &astrNewElementSequence, + std::string &strError); + + bool getApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + std::string &strResult); + bool setApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + const std::string &strApplicationRule, std::string &strError); + bool clearApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); /** * Method that imports Configurable Domains from an Xml source. @@ -287,8 +315,8 @@ public: * * @return false if any error occures */ - bool importDomainsXml(const std::string& xmlSource, bool withSettings, bool fromFile, - std::string& errorMsg); + bool importDomainsXml(const std::string &xmlSource, bool withSettings, bool fromFile, + std::string &errorMsg); /** * Method that imports a single Configurable Domain from an Xml source. @@ -304,8 +332,8 @@ public: * * @return false if any error occurs */ - bool importSingleDomainXml(const std::string& xmlSource, bool overwrite, bool withSettings, - bool fromFile, std::string& errorMsg); + bool importSingleDomainXml(const std::string &xmlSource, bool overwrite, bool withSettings, + bool fromFile, std::string &errorMsg); /** * Method that exports Configurable Domains to an Xml destination. @@ -319,8 +347,8 @@ public: * * @return false if any error occurs, true otherwise. */ - bool exportDomainsXml(std::string& xmlDest, bool withSettings, bool toFile, - std::string& errorMsg) const; + bool exportDomainsXml(std::string &xmlDest, bool withSettings, bool toFile, + std::string &errorMsg) const; /** * Method that exports a given Configurable Domain to an Xml destination. @@ -335,112 +363,192 @@ public: * * @return false if any error occurs, true otherwise. */ - bool exportSingleDomainXml(std::string& xmlDest, const std::string& domainName, - bool withSettings, bool toFile, std::string& errorMsg) const; - - // Binary Import/Export - bool importDomainsBinary(const std::string& strFileName, std::string& strError); - bool exportDomainsBinary(const std::string& strFileName, std::string& strError); + bool exportSingleDomainXml(std::string &xmlDest, const std::string &domainName, + bool withSettings, bool toFile, std::string &errorMsg) const; /** * Method that exports an Xml description of the passed element into a string * * @param[in] pXmlSource The source element to export * @param[in] strRootElementType The XML root element name of the exported instance document - * @param[out] strResult contains the xml description or the error description in case false is returned + * @param[in] xmlSerializingContext the context to use for serialization + * Is an rvalue as it must be destructed after this function + * call to set the error. + * Additionally, using it for an other serialization would + * override the error. + * @param[out] strResult contains the xml description or the error description in case false is + * returned * - * @return true for success, false if any error occurs during the creation of the xml description (validation or encoding) + * @return true for success, false if any error occurs during the creation of the xml + * description (validation or encoding) */ - bool exportElementToXMLString(const IXmlSource* pXmlSource, - const std::string& strRootElementType, - std::string& strResult) const; + bool exportElementToXMLString(const IXmlSource *pXmlSource, + const std::string &strRootElementType, + CXmlSerializingContext &&xmlSerializingContext, + std::string &strResult) const; // CElement virtual std::string getKind() const; private: - CParameterMgr(const CParameterMgr&); - CParameterMgr& operator=(const CParameterMgr&); + CParameterMgr(const CParameterMgr &); + CParameterMgr &operator=(const CParameterMgr &); // Init - virtual bool init(std::string& strError); - - // Logging (done by root) - virtual void doLog(bool bIsWarning, const std::string& strLog) const; - virtual void nestLog() const; - virtual void unnestLog() const; + virtual bool init(std::string &strError); // Version std::string getVersion() const; + // This using is here for internal reasons: CommandHandler is public and is + // a unique_ptr but we want the type that's inside. And for legacy reason + // because that's the original name before a rework; this directive avoids + // renaming a lot of stuff. + using CCommandHandler = CommandHandler::element_type; + using RemoteCommandParser = CCommandHandler::CommandStatus (CParameterMgr::*)( + const IRemoteCommand &remoteCommand, std::string &strResult); + + // Parser descriptions + struct SRemoteCommandParserItem + { + const char *_pcCommandName; + CParameterMgr::RemoteCommandParser _pfnParser; + size_t _minArgumentCount; + const char *_pcHelp; + const char *_pcDescription; + }; + ////////////////:: Remote command parsers /// Version - CCommandHandler::CommandStatus versionCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus versionCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Status - CCommandHandler::CommandStatus statusCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus statusCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Tuning Mode - CCommandHandler::CommandStatus setTuningModeCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getTuningModeCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus setTuningModeCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getTuningModeCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Value Space - CCommandHandler::CommandStatus setValueSpaceCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getValueSpaceCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus setValueSpaceCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getValueSpaceCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Output Raw Format - CCommandHandler::CommandStatus setOutputRawFormatCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getOutputRawFormatCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus setOutputRawFormatCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus getOutputRawFormatCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); /// Sync - CCommandHandler::CommandStatus setAutoSyncCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getAutoSyncCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus syncCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus setAutoSyncCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getAutoSyncCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus syncCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Criteria - CCommandHandler::CommandStatus listCriteriaCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus listCriteriaCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Domains - CCommandHandler::CommandStatus listDomainsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus createDomainCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus deleteDomainCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus deleteAllDomainsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus renameDomainCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus setSequenceAwarenessCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getSequenceAwarenessCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus listDomainElementsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus addElementCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus removeElementCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus splitDomainCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus listDomainsCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus createDomainCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus deleteDomainCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus deleteAllDomainsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus renameDomainCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus setSequenceAwarenessCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus getSequenceAwarenessCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus listDomainElementsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus addElementCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus removeElementCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus splitDomainCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Configurations - CCommandHandler::CommandStatus listConfigurationsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus dumpDomainsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus createConfigurationCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus deleteConfigurationCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus renameConfigurationCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus saveConfigurationCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus restoreConfigurationCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus setElementSequenceCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getElementSequenceCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus setRuleCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus clearRuleCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getRuleCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus listConfigurationsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus dumpDomainsCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus createConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus deleteConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus renameConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus saveConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus restoreConfigurationCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus setElementSequenceCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus getElementSequenceCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus setRuleCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus clearRuleCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getRuleCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Elements/Parameters - CCommandHandler::CommandStatus listElementsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus listParametersCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus dumpElementCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getElementSizeCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus showPropertiesCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getParameterCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus setParameterCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus getConfigurationParameterCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus setConfigurationParameterCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus listBelongingDomainsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus listAssociatedDomainsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus showMappingCommandProcess(const IRemoteCommand& remoteCommand, - std::string& strResult); + CCommandHandler::CommandStatus listElementsCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus listParametersCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getElementStructureXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus getElementBytesCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus setElementBytesCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus getElementXMLCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus setElementXMLCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus dumpElementCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getElementSizeCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus showPropertiesCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getParameterCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus setParameterCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); + CCommandHandler::CommandStatus getConfigurationParameterCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus setConfigurationParameterCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus listBelongingDomainsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus listAssociatedDomainsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus showMappingCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult); /// Browse - CCommandHandler::CommandStatus listAssociatedElementsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus listConflictingElementsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus listRogueElementsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus listAssociatedElementsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus listConflictingElementsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus listRogueElementsCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); /// Settings Import/Export - CCommandHandler::CommandStatus exportDomainsXMLCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus importDomainsXMLCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus exportDomainsWithSettingsXMLCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus importDomainsWithSettingsXMLCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus exportDomainsXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus importDomainsXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus exportDomainsWithSettingsXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); + CCommandHandler::CommandStatus importDomainsWithSettingsXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); /** * Command handler method for exportDomainWithSettingsXML command. * @@ -450,10 +558,10 @@ private: * @return CCommandHandler::ESucceeded if command succeeded or CCommandHandler::EFailed * in the other case */ - CCommandHandler::CommandStatus exportDomainWithSettingsXMLCommandProcess(const IRemoteCommand& remoteCommand, std::string& result); - CCommandHandler::CommandStatus importDomainWithSettingsXMLCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus exportSettingsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); - CCommandHandler::CommandStatus importSettingsCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult); + CCommandHandler::CommandStatus exportDomainWithSettingsXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &result); + CCommandHandler::CommandStatus importDomainWithSettingsXMLCommandProcess( + const IRemoteCommand &remoteCommand, std::string &strResult); /** * Command handler method for getDomainsWithSettings command. @@ -465,7 +573,7 @@ private: * in the other case */ CCommandHandler::CommandStatus getDomainsWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, std::string& strResult); + const IRemoteCommand &remoteCommand, std::string &strResult); /** * Command handler method for getDomainWithSettings command. @@ -477,7 +585,7 @@ private: * in the other case */ CCommandHandler::CommandStatus getDomainWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, std::string& strResult); + const IRemoteCommand &remoteCommand, std::string &strResult); /** * Command handler method for setDomainsWithSettings command. @@ -489,7 +597,7 @@ private: * in the other case */ CCommandHandler::CommandStatus setDomainsWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, std::string& strResult); + const IRemoteCommand &remoteCommand, std::string &strResult); /** * Command handler method for setDomainWithSettings command. @@ -501,7 +609,7 @@ private: * in the other case */ CCommandHandler::CommandStatus setDomainWithSettingsXMLCommandProcess( - const IRemoteCommand& remoteCommand, std::string& result); + const IRemoteCommand &remoteCommand, std::string &result); /** * Command handler method for getSystemClass command. @@ -513,49 +621,104 @@ private: * in the other case */ CCommandHandler::CommandStatus getSystemClassXMLCommandProcess( - const IRemoteCommand& remoteCommand, std::string& strResult); + const IRemoteCommand &remoteCommand, std::string &strResult); // Max command usage length, use for formatting void setMaxCommandUsageLength(); // For tuning, check we're in tuning mode - bool checkTuningModeOn(std::string& strError) const; + bool checkTuningModeOn(std::string &strError) const; // Blackboard (dynamic parameter handling) - pthread_mutex_t* getBlackboardMutex(); + std::mutex &getBlackboardMutex(); // Blackboard reference (dynamic parameter handling) - CParameterBlackboard* getParameterBlackboard(); + CParameterBlackboard *getParameterBlackboard(); // Parameter access - bool accessValue(CParameterAccessContext& parameterAccessContext, const std::string& strPath, std::string& strValue, bool bSet, std::string& strError); - bool doSetValue(const std::string& strPath, const std::string& strValue, bool bRawValueSpace, bool bDynamicAccess, std::string& strError) const; - bool doGetValue(const std::string& strPath, std::string& strValue, bool bRawValueSpace, bool bHexOutputRawFormat, bool bDynamicAccess, std::string& strError) const; + bool accessValue(CParameterAccessContext ¶meterAccessContext, const std::string &strPath, + std::string &strValue, bool bSet, std::string &strError); + bool doSetValue(const std::string &strPath, const std::string &strValue, bool bRawValueSpace, + bool bDynamicAccess, std::string &strError) const; + bool doGetValue(const std::string &strPath, std::string &strValue, bool bRawValueSpace, + bool bHexOutputRawFormat, bool bDynamicAccess, std::string &strError) const; // Framework global configuration loading - bool loadFrameworkConfiguration(std::string& strError); + bool loadFrameworkConfiguration(std::string &strError); + + /** Load required subsystems + * + * @param[out] error error description if there is one + * @return true if succeed false otherwise + */ + bool loadSubsystems(std::string &error); // System class Structure loading - bool loadStructure(std::string& strError); + bool loadStructure(std::string &strError); // System class Structure loading - bool loadSettings(std::string& strError); - bool loadSettingsFromConfigFile(std::string& strError); + bool loadSettings(std::string &strError); + bool loadSettingsFromConfigFile(std::string &strError); + + /** Get settings from a configurable element in binary format. + * + * @param[in] element configurable element. + * @param[out] settings current element settings (in mainblackboard) in binary format + * + * @return true on success, false on error + */ + void getSettingsAsBytes(const CConfigurableElement &element, + std::vector<uint8_t> &settings) const; + + /** Assign settings to a configurable element in binary format. + * + * @param[in] element configurable element. + * @param[in] settings the settings as byte array (binary). + * @param[out] error error message filled in case of error + * + * @return true in case of success, false oherwise, in which case error is filled with error + * message. + */ + bool setSettingsAsBytes(const CConfigurableElement &element, + const std::vector<uint8_t> &settings, std::string &error); + + /** Assign settings to a configurable element in XML format. + * + * @param[in] configurableElement The element to set. + * @param[in] settings The settings to set. + * @param[out] error human readable error message filled in case of error, + * undefined in case of success. + * @return true in case of success, false otherwise + */ + bool setSettingsAsXML(CConfigurableElement *configurableElement, const std::string &settings, + std::string &error); + + /** Get settings from a configurable element in XML format. + * + * @param[in] configurableElement The element to get settings from. + * @param[out] result on success: the exported setttings in XML + * on error: human readable error message + * + * @return true in case of success, false otherwise. + */ + bool getSettingsAsXML(const CConfigurableElement *configurableElement, + std::string &result) const; /** Parse an XML stream into an element * * @param[in] elementSerializingContext serializing context * @param[out] pRootElement the receiving element * @param[in] input the input XML stream - * @param[in] strXmlFolder the folder containing the XML input file (if applicable) or "" + * @param[in] baseUri the XML input file URI or "" * @param[in] eElementLibrary which element library to be used + * @param[in] replace Should the element be overridden or modified in place * @param[in] strNameAttributeName the name of the element's XML "name" attribute * * @returns true if parsing succeeded, false otherwise */ - bool xmlParse(CXmlElementSerializingContext& elementSerializingContext, CElement* pRootElement, - _xmlDoc* doc, const std::string& strXmlFolder, - ElementLibrary eElementLibrary, const std::string& strNameAttributeName = "Name"); + bool xmlParse(CXmlElementSerializingContext &elementSerializingContext, CElement *pRootElement, + _xmlDoc *doc, const std::string &baseUri, ElementLibrary eElementLibrary, + bool replace = true, const std::string &strNameAttributeName = "Name"); /** Wrapper for converting public APIs semantics to internal API * @@ -582,9 +745,9 @@ private: * * @returns true if the import succeeded, false otherwise */ - bool wrapLegacyXmlImport(const std::string& xmlSource, bool fromFile, bool withSettings, - CElement& element, const std::string& nameAttributeName, - std::string& errorMsg); + bool wrapLegacyXmlImport(const std::string &xmlSource, bool fromFile, bool withSettings, + CElement &element, const std::string &nameAttributeName, + std::string &errorMsg); /** * Export an element object to an Xml destination. @@ -596,8 +759,8 @@ private: * * @return false if any error occurs, true otherwise. */ - bool serializeElement(std::ostream& output, CXmlSerializingContext& xmlSerializingContext, - const CElement& element) const; + bool serializeElement(std::ostream &output, CXmlSerializingContext &xmlSerializingContext, + const CElement &element) const; /** Wrapper for converting public APIs semantics to internal API * @@ -622,42 +785,39 @@ private: * * @returns true if the export succeeded, false otherwise */ - bool wrapLegacyXmlExport(std::string& xmlDest, bool toFile, bool withSettings, - const CElement& element, std::string& errorMsg) const; + bool wrapLegacyXmlExport(std::string &xmlDest, bool toFile, bool withSettings, + const CElement &element, std::string &errorMsg) const; /** Wrapper for converting public APIs semantics to internal API * * @see wrapLegacyXmlExport */ - bool wrapLegacyXmlExportToFile(std::string& xmlDest, - const CElement& element, + bool wrapLegacyXmlExportToFile(std::string &xmlDest, const CElement &element, CXmlDomainExportContext &context) const; /** Wrapper for converting public APIs semantics to internal API * * @see wrapLegacyXmlExport */ - bool wrapLegacyXmlExportToString(std::string& xmlDest, - const CElement& element, + bool wrapLegacyXmlExportToString(std::string &xmlDest, const CElement &element, CXmlDomainExportContext &context) const; - // Framework Configuration - CParameterFrameworkConfiguration* getFrameworkConfiguration(); - const CParameterFrameworkConfiguration* getConstFrameworkConfiguration(); + CParameterFrameworkConfiguration *getFrameworkConfiguration(); + const CParameterFrameworkConfiguration *getConstFrameworkConfiguration(); // Selection Criteria - CSelectionCriteria* getSelectionCriteria(); - const CSelectionCriteria* getConstSelectionCriteria(); + CSelectionCriteria *getSelectionCriteria(); + const CSelectionCriteria *getConstSelectionCriteria(); // System Class - CSystemClass* getSystemClass(); - const CSystemClass* getConstSystemClass() const; + CSystemClass *getSystemClass(); + const CSystemClass *getConstSystemClass() const; // Configurable Domains - CConfigurableDomains* getConfigurableDomains(); - const CConfigurableDomains* getConstConfigurableDomains(); - const CConfigurableDomains* getConstConfigurableDomains() const; + CConfigurableDomains *getConfigurableDomains(); + const CConfigurableDomains *getConstConfigurableDomains(); + const CConfigurableDomains *getConstConfigurableDomains() const; // Apply configurations void doApplyConfigurations(bool bForce); @@ -666,85 +826,83 @@ private: void feedElementLibraries(); // Remote Processor Server connection handling - bool handleRemoteProcessingInterface(std::string& strError); + bool isRemoteInterfaceRequired(); + bool handleRemoteProcessingInterface(std::string &strError); + + /** Log the result of a function + * + * @param[in] isSuccess indicates if the previous function has succeed + * @param[in] result function provided result string + * @return isSuccess parameter + */ + bool logResult(bool isSuccess, const std::string &result); + + /** Info logger call helper */ + inline core::log::details::Info info(); + + /** Warning logger call helper */ + inline core::log::details::Warning warning(); // Tuning - bool _bTuningModeIsOn; + bool _bTuningModeIsOn{false}; // Value Space - bool _bValueSpaceIsRaw; + bool _bValueSpaceIsRaw{false}; // Output Raw Format - bool _bOutputRawFormatIsHex; + bool _bOutputRawFormatIsHex{false}; // Automatic synchronization to HW during Tuning session - bool _bAutoSyncOn; + bool _bAutoSyncOn{true}; // Current Parameter Settings - CParameterBlackboard* _pMainParameterBlackboard; + CParameterBlackboard *_pMainParameterBlackboard; // Dynamic object creation - CElementLibrarySet* _pElementLibrarySet; + CElementLibrarySet *_pElementLibrarySet; // XML parsing, object creation handling - std::string _strXmlConfigurationFilePath; // Configuration file path - std::string _strXmlConfigurationFolderPath; // Root folder for configuration file - std::string _strSchemaFolderLocation; // Place where schemas stand + std::string _xmlConfigurationUri; + std::string _schemaUri; // Place where schemas stand // Subsystem plugin location - const CSubsystemPlugins* _pSubsystemPlugins; - - /** - * Remote processor library handle - */ - void* _pvLibRemoteProcessorHandle; - - // Whole system structure checksum - uint8_t _uiStructureChecksum; - - // Command Handler - CCommandHandler* _pCommandHandler; + const CSubsystemPlugins *_pSubsystemPlugins{nullptr}; // Remote Processor Server - IRemoteProcessorServerInterface* _pRemoteProcessorServer; + IRemoteProcessorServerInterface *_pRemoteProcessorServer{nullptr}; // Parser description array static const SRemoteCommandParserItem gastRemoteCommandParserItems[]; - // Parser description array size - static const uint32_t guiNbRemoteCommandParserItems; - // Maximum command usage length - uint32_t _uiMaxCommandUsageLength; + size_t _maxCommandUsageLength{0}; // Blackboard access mutex - pthread_mutex_t _blackboardMutex; + std::mutex _blackboardMutex; - // Logging - ILogger* _pLogger; - mutable uint32_t _uiLogDepth; + /** Application main logger based on the one provided by the client */ + mutable core::log::Logger _logger; /** If set to false, the remote interface won't be started no matter what. * If set to true - the default - it has no impact on the policy for * starting the remote interface. */ - bool _bForceNoRemoteInterface; + bool _bForceNoRemoteInterface{false}; /** If set to true, missing subsystem will abort parameterMgr start. * If set to false, missing subsystem will fallback on virtual subsystem. */ - bool _bFailOnMissingSubsystem; + bool _bFailOnMissingSubsystem{true}; /** If set to true, unparsable or discording domains will abort parameterMgr start. * If set to false, unparsable or discording domains * will continue the parameterMgr start with no domains. */ - bool _bFailOnFailedSettingsLoad; + bool _bFailOnFailedSettingsLoad{true}; /** * If set to true, parameterMgr will report an error * when being unable to validate .xml files * If set to false, no .xml/xsd validation will happen (default behaviour) */ - bool _bValidateSchemasOnStart; + bool _bValidateSchemasOnStart{false}; }; - diff --git a/parameter/ParameterMgrFullConnector.cpp b/parameter/ParameterMgrFullConnector.cpp index 30d2780..81577a9 100644 --- a/parameter/ParameterMgrFullConnector.cpp +++ b/parameter/ParameterMgrFullConnector.cpp @@ -31,126 +31,41 @@ #include "ParameterMgr.h" #include "ParameterMgrLogger.h" +#include "CommandHandlerWrapper.h" + #include <list> using std::string; -CParameterMgrFullConnector::CParameterMgrFullConnector(const string& strConfigurationFilePath) : - _pParameterMgr(new CParameterMgr(strConfigurationFilePath)), _pLogger(NULL) -{ - _pParameterMgrLogger = new CParameterMgrLogger<CParameterMgrFullConnector>(*this); - _pParameterMgr->setLogger(_pParameterMgrLogger); -} - -CParameterMgrFullConnector::~CParameterMgrFullConnector() -{ - delete _pParameterMgr; - delete _pParameterMgrLogger; -} - - -bool CParameterMgrFullConnector::start(string& strError) -{ - // Create data structure & Init flow - return _pParameterMgr->load(strError); -} - -void CParameterMgrFullConnector::setLogger(CParameterMgrFullConnector::ILogger* pLogger) -{ - _pLogger = pLogger; -} - -// Private logging -void CParameterMgrFullConnector::doLog(bool bIsWarning, const string& strLog) -{ - if (_pLogger) { - - _pLogger->log(bIsWarning, strLog); - } -} - -CParameterHandle* CParameterMgrFullConnector::createParameterHandle(const string& strPath, - string& strError) -{ - return _pParameterMgr->createParameterHandle(strPath, strError); -} - -ISelectionCriterionTypeInterface* CParameterMgrFullConnector::createSelectionCriterionType( - bool bIsInclusive) -{ - return _pParameterMgr->createSelectionCriterionType(bIsInclusive); -} - -ISelectionCriterionInterface* CParameterMgrFullConnector::createSelectionCriterion( - const string& strName, - const ISelectionCriterionTypeInterface* pSelectionCriterionType) -{ - return _pParameterMgr->createSelectionCriterion(strName, - static_cast<const CSelectionCriterionType*>(pSelectionCriterionType)); -} - -ISelectionCriterionInterface* CParameterMgrFullConnector::getSelectionCriterion( - const string& strName) +CParameterMgrFullConnector::CParameterMgrFullConnector(const string &strConfigurationFilePath) + : CParameterMgrPlatformConnector(strConfigurationFilePath) { - return _pParameterMgr->getSelectionCriterion(strName); } -bool CParameterMgrFullConnector::getForceNoRemoteInterface() const +CommandHandlerInterface *CParameterMgrFullConnector::createCommandHandler() { - return _pParameterMgr->getForceNoRemoteInterface(); -} - -void CParameterMgrFullConnector::setForceNoRemoteInterface(bool bForceNoRemoteInterface) -{ - _pParameterMgr->setForceNoRemoteInterface(bForceNoRemoteInterface); -} - -void CParameterMgrFullConnector::applyConfigurations() -{ - return _pParameterMgr->applyConfigurations(); + return new CommandHandlerWrapper(_pParameterMgr->createCommandHandler()); } void CParameterMgrFullConnector::setFailureOnMissingSubsystem(bool bFail) { - _pParameterMgr->setFailureOnMissingSubsystem(bFail); -} - -bool CParameterMgrFullConnector::getFailureOnMissingSubsystem() const -{ - return _pParameterMgr->getFailureOnMissingSubsystem(); + std::string error; + setFailureOnMissingSubsystem(bFail, error); } void CParameterMgrFullConnector::setFailureOnFailedSettingsLoad(bool bFail) { - _pParameterMgr->setFailureOnFailedSettingsLoad(bFail); -} - -bool CParameterMgrFullConnector::getFailureOnFailedSettingsLoad() -{ - return _pParameterMgr->getFailureOnFailedSettingsLoad(); -} - -const string& CParameterMgrFullConnector::getSchemaFolderLocation() const -{ - return _pParameterMgr->getSchemaFolderLocation(); -} - -void CParameterMgrFullConnector::setSchemaFolderLocation(const string& strSchemaFolderLocation) -{ - _pParameterMgr->setSchemaFolderLocation(strSchemaFolderLocation); + std::string error; + setFailureOnFailedSettingsLoad(bFail, error); } void CParameterMgrFullConnector::setValidateSchemasOnStart(bool bValidate) { - _pParameterMgr->setValidateSchemasOnStart(bValidate); -} - -bool CParameterMgrFullConnector::getValidateSchemasOnStart() const -{ - return _pParameterMgr->getValidateSchemasOnStart(); + std::string error; + setValidateSchemasOnStart(bValidate, error); } -bool CParameterMgrFullConnector::setTuningMode(bool bOn, string& strError) +bool CParameterMgrFullConnector::setTuningMode(bool bOn, string &strError) { return _pParameterMgr->setTuningMode(bOn, strError); } @@ -162,7 +77,7 @@ bool CParameterMgrFullConnector::isTuningModeOn() const void CParameterMgrFullConnector::setValueSpace(bool bIsRaw) { - return _pParameterMgr->setValueSpace(bIsRaw); + _pParameterMgr->setValueSpace(bIsRaw); } bool CParameterMgrFullConnector::isValueSpaceRaw() const @@ -172,7 +87,7 @@ bool CParameterMgrFullConnector::isValueSpaceRaw() const void CParameterMgrFullConnector::setOutputRawFormat(bool bIsHex) { - return _pParameterMgr->setOutputRawFormat(bIsHex); + _pParameterMgr->setOutputRawFormat(bIsHex); } bool CParameterMgrFullConnector::isOutputRawFormatHex() const @@ -180,7 +95,7 @@ bool CParameterMgrFullConnector::isOutputRawFormatHex() const return _pParameterMgr->outputRawFormatIsHex(); } -bool CParameterMgrFullConnector::setAutoSync(bool bAutoSyncOn, string& strError) +bool CParameterMgrFullConnector::setAutoSync(bool bAutoSyncOn, string &strError) { return _pParameterMgr->setAutoSync(bAutoSyncOn, strError); } @@ -190,185 +105,182 @@ bool CParameterMgrFullConnector::isAutoSyncOn() const return _pParameterMgr->autoSyncOn(); } -bool CParameterMgrFullConnector::sync(string& strError) +bool CParameterMgrFullConnector::sync(string &strError) { return _pParameterMgr->sync(strError); } -bool CParameterMgrFullConnector::accessParameterValue(const string& strPath, string& strValue, - bool bSet, string& strError) +bool CParameterMgrFullConnector::accessParameterValue(const string &strPath, string &strValue, + bool bSet, string &strError) { return _pParameterMgr->accessParameterValue(strPath, strValue, bSet, strError); } bool CParameterMgrFullConnector::accessConfigurationValue(const string &strDomain, const string &strConfiguration, - const string& strPath, string& strValue, - bool bSet, string& strError) + const string &strPath, string &strValue, + bool bSet, string &strError) { return _pParameterMgr->accessConfigurationValue(strDomain, strConfiguration, strPath, strValue, - bSet, strError); + bSet, strError); } -bool CParameterMgrFullConnector::getParameterMapping(const string& strPath, string& strValue) const +bool CParameterMgrFullConnector::getParameterMapping(const string &strPath, string &strValue) const { return _pParameterMgr->getParameterMapping(strPath, strValue); } -bool CParameterMgrFullConnector::createDomain(const string& strName, string& strError) +bool CParameterMgrFullConnector::createDomain(const string &strName, string &strError) { return _pParameterMgr->createDomain(strName, strError); } -bool CParameterMgrFullConnector::deleteDomain(const string& strName, string& strError) +bool CParameterMgrFullConnector::deleteDomain(const string &strName, string &strError) { return _pParameterMgr->deleteDomain(strName, strError); } -bool CParameterMgrFullConnector::renameDomain(const string& strName, const string& strNewName, - string& strError) +bool CParameterMgrFullConnector::renameDomain(const string &strName, const string &strNewName, + string &strError) { return _pParameterMgr->renameDomain(strName, strNewName, strError); } -bool CParameterMgrFullConnector::deleteAllDomains(string& strError) +bool CParameterMgrFullConnector::deleteAllDomains(string &strError) { return _pParameterMgr->deleteAllDomains(strError); } -bool CParameterMgrFullConnector::createConfiguration(const string& strDomain, - const string& strConfiguration, - string& strError) +bool CParameterMgrFullConnector::createConfiguration(const string &strDomain, + const string &strConfiguration, + string &strError) { return _pParameterMgr->createConfiguration(strDomain, strConfiguration, strError); } -bool CParameterMgrFullConnector::deleteConfiguration(const string& strDomain, - const string& strConfiguration, - string& strError) +bool CParameterMgrFullConnector::deleteConfiguration(const string &strDomain, + const string &strConfiguration, + string &strError) { return _pParameterMgr->deleteConfiguration(strDomain, strConfiguration, strError); } -bool CParameterMgrFullConnector::renameConfiguration(const string& strDomain, - const string& strConfiguration, - const string& strNewConfiguration, - string& strError) +bool CParameterMgrFullConnector::renameConfiguration(const string &strDomain, + const string &strConfiguration, + const string &strNewConfiguration, + string &strError) { return _pParameterMgr->renameConfiguration(strDomain, strConfiguration, strNewConfiguration, - strError); + strError); } -bool CParameterMgrFullConnector::saveConfiguration(const string& strDomain, - const string& strConfiguration, string& strError) +bool CParameterMgrFullConnector::saveConfiguration(const string &strDomain, + const string &strConfiguration, string &strError) { return _pParameterMgr->saveConfiguration(strDomain, strConfiguration, strError); } -bool CParameterMgrFullConnector::restoreConfiguration(const string& strDomain, - const string& strConfiguration, - std::list<string>& lstrError) +bool CParameterMgrFullConnector::restoreConfiguration(const string &strDomain, + const string &strConfiguration, + Results &errors) { - return _pParameterMgr->restoreConfiguration(strDomain, strConfiguration, lstrError); + return _pParameterMgr->restoreConfiguration(strDomain, strConfiguration, errors); } -bool CParameterMgrFullConnector::setSequenceAwareness(const string& strName, bool bSequenceAware, - string& strResult) +bool CParameterMgrFullConnector::setSequenceAwareness(const string &strName, bool bSequenceAware, + string &strResult) { return _pParameterMgr->setSequenceAwareness(strName, bSequenceAware, strResult); } -bool CParameterMgrFullConnector::getSequenceAwareness(const string& strName, bool& bSequenceAware, - string& strResult) +bool CParameterMgrFullConnector::getSequenceAwareness(const string &strName, bool &bSequenceAware, + string &strResult) { return _pParameterMgr->getSequenceAwareness(strName, bSequenceAware, strResult); } -bool CParameterMgrFullConnector::addConfigurableElementToDomain(const string& strDomain, - const string& strConfigurableElementPath, string& strError) +bool CParameterMgrFullConnector::addConfigurableElementToDomain( + const string &strDomain, const string &strConfigurableElementPath, string &strError) { return _pParameterMgr->addConfigurableElementToDomain(strDomain, strConfigurableElementPath, - strError); + strError); } -bool CParameterMgrFullConnector::removeConfigurableElementFromDomain(const string& strDomain, - const string& strConfigurableElementPath, string& strError) +bool CParameterMgrFullConnector::removeConfigurableElementFromDomain( + const string &strDomain, const string &strConfigurableElementPath, string &strError) { - return _pParameterMgr->removeConfigurableElementFromDomain(strDomain, - strConfigurableElementPath, strError); + return _pParameterMgr->removeConfigurableElementFromDomain( + strDomain, strConfigurableElementPath, strError); } -bool CParameterMgrFullConnector::split(const string& strDomain, - const string& strConfigurableElementPath, string& strError) +bool CParameterMgrFullConnector::split(const string &strDomain, + const string &strConfigurableElementPath, string &strError) { return _pParameterMgr->split(strDomain, strConfigurableElementPath, strError); } -bool CParameterMgrFullConnector::setElementSequence(const string& strDomain, - const string& strConfiguration, - const std::vector<string>& astrNewElementSequence, - string& strError) +bool CParameterMgrFullConnector::setElementSequence( + const string &strDomain, const string &strConfiguration, + const std::vector<string> &astrNewElementSequence, string &strError) { return _pParameterMgr->setElementSequence(strDomain, strConfiguration, astrNewElementSequence, - strError); + strError); } -bool CParameterMgrFullConnector::setApplicationRule(const string& strDomain, - const string& strConfiguration, - const string& strApplicationRule, - string& strError) +bool CParameterMgrFullConnector::setApplicationRule(const string &strDomain, + const string &strConfiguration, + const string &strApplicationRule, + string &strError) { return _pParameterMgr->setApplicationRule(strDomain, strConfiguration, strApplicationRule, - strError); + strError); } - -bool CParameterMgrFullConnector::getApplicationRule(const string& strDomain, - const string& strConfiguration, - string& strResult) +bool CParameterMgrFullConnector::getApplicationRule(const string &strDomain, + const string &strConfiguration, + string &strResult) { return _pParameterMgr->getApplicationRule(strDomain, strConfiguration, strResult); } -bool CParameterMgrFullConnector::clearApplicationRule(const string& strDomain, - const string& strConfiguration, - string& strError) +bool CParameterMgrFullConnector::clearApplicationRule(const string &strDomain, + const string &strConfiguration, + string &strError) { return _pParameterMgr->clearApplicationRule(strDomain, strConfiguration, strError); } - -bool CParameterMgrFullConnector::importDomainsXml(const string& strXmlSource, bool bWithSettings, - bool bFromFile, string& strError) +bool CParameterMgrFullConnector::importDomainsXml(const string &strXmlSource, bool bWithSettings, + bool bFromFile, string &strError) { return _pParameterMgr->importDomainsXml(strXmlSource, bWithSettings, bFromFile, strError); } -bool CParameterMgrFullConnector::exportDomainsXml(string& strXmlDest, bool bWithSettings, - bool bToFile, string& strError) const +bool CParameterMgrFullConnector::exportDomainsXml(string &strXmlDest, bool bWithSettings, + bool bToFile, string &strError) const { return _pParameterMgr->exportDomainsXml(strXmlDest, bWithSettings, bToFile, strError); } // deprecated, use the other version of importSingleDomainXml instead -bool CParameterMgrFullConnector::importSingleDomainXml(const string& strXmlSource, bool bOverwrite, - string& strError) +bool CParameterMgrFullConnector::importSingleDomainXml(const string &strXmlSource, bool bOverwrite, + string &strError) { return importSingleDomainXml(strXmlSource, bOverwrite, true, false, strError); } -bool CParameterMgrFullConnector::importSingleDomainXml(const string& xmlSource, bool overwrite, +bool CParameterMgrFullConnector::importSingleDomainXml(const string &xmlSource, bool overwrite, bool withSettings, bool fromFile, - string& errorMsg) + string &errorMsg) { return _pParameterMgr->importSingleDomainXml(xmlSource, overwrite, withSettings, fromFile, errorMsg); } -bool CParameterMgrFullConnector::exportSingleDomainXml(string& strXmlDest, - const string& strDomainName, +bool CParameterMgrFullConnector::exportSingleDomainXml(string &strXmlDest, + const string &strDomainName, bool bWithSettings, bool bToFile, - string& strError) const + string &strError) const { return _pParameterMgr->exportSingleDomainXml(strXmlDest, strDomainName, bWithSettings, bToFile, - strError); + strError); } diff --git a/parameter/ParameterMgrLogger.h b/parameter/ParameterMgrLogger.h index 0e42d8a..aafb76a 100644 --- a/parameter/ParameterMgrLogger.h +++ b/parameter/ParameterMgrLogger.h @@ -30,28 +30,24 @@ #pragma once #include "ParameterMgrLoggerForward.h" -#include "ParameterMgr.h" +#include <log/ILogger.h> +#include <NonCopyable.hpp> #include <string> -/* Wrap a class to expose its logging [log(bool, string&)] capabilities +/* Wrap a class to expose its logging [info, warning] capabilities * through ILogger. */ -template<class T> -class CParameterMgrLogger : public CParameterMgr::ILogger +template <class T> +class CParameterMgrLogger : public core::log::ILogger, private utility::NonCopyable { public: - CParameterMgrLogger(T& parameterMgrConnector) : - _parameterMgrConnector(parameterMgrConnector) - { - } + CParameterMgrLogger(T ¶meterMgrConnector) : _parameterMgrConnector(parameterMgrConnector) {} - virtual void log(bool bIsWarning, const std::string& strLog) - { - _parameterMgrConnector.doLog(bIsWarning, strLog); - } + virtual void info(const std::string &log) { _parameterMgrConnector.info(log); } + + virtual void warning(const std::string &log) { _parameterMgrConnector.warning(log); } private: // Log destination - T& _parameterMgrConnector; + T &_parameterMgrConnector; }; - diff --git a/parameter/ParameterMgrPlatformConnector.cpp b/parameter/ParameterMgrPlatformConnector.cpp index d49003d..8eff7c9 100644 --- a/parameter/ParameterMgrPlatformConnector.cpp +++ b/parameter/ParameterMgrPlatformConnector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -36,12 +36,11 @@ using std::string; // Construction CParameterMgrPlatformConnector::CParameterMgrPlatformConnector( - const string& strConfigurationFilePath) : - _pParameterMgr(new CParameterMgr(strConfigurationFilePath)), _bStarted(false), _pLogger(NULL) + const string &strConfigurationFilePath) + : _pParameterMgrLogger(new CParameterMgrLogger<CParameterMgrPlatformConnector>(*this)), + _pParameterMgr(new CParameterMgr(strConfigurationFilePath, *_pParameterMgrLogger)), + _bStarted(false), _pLogger(NULL) { - // Logging - _pParameterMgrLogger = new CParameterMgrLogger<CParameterMgrPlatformConnector>(*this); - _pParameterMgr->setLogger(_pParameterMgrLogger); } CParameterMgrPlatformConnector::~CParameterMgrPlatformConnector() @@ -51,22 +50,26 @@ CParameterMgrPlatformConnector::~CParameterMgrPlatformConnector() } // Selection Criteria interface. Beware returned objects are lent, clients shall not delete them! -ISelectionCriterionTypeInterface* CParameterMgrPlatformConnector::createSelectionCriterionType(bool bIsInclusive) +ISelectionCriterionTypeInterface *CParameterMgrPlatformConnector::createSelectionCriterionType( + bool bIsInclusive) { assert(!_bStarted); return _pParameterMgr->createSelectionCriterionType(bIsInclusive); } -ISelectionCriterionInterface* CParameterMgrPlatformConnector::createSelectionCriterion(const string& strName, const ISelectionCriterionTypeInterface* pSelectionCriterionType) +ISelectionCriterionInterface *CParameterMgrPlatformConnector::createSelectionCriterion( + const string &strName, const ISelectionCriterionTypeInterface *pSelectionCriterionType) { assert(!_bStarted); - return _pParameterMgr->createSelectionCriterion(strName, static_cast<const CSelectionCriterionType*>(pSelectionCriterionType)); + return _pParameterMgr->createSelectionCriterion( + strName, static_cast<const CSelectionCriterionType *>(pSelectionCriterionType)); } // Selection criterion retrieval -ISelectionCriterionInterface* CParameterMgrPlatformConnector::getSelectionCriterion(const string& strName) const +ISelectionCriterionInterface *CParameterMgrPlatformConnector::getSelectionCriterion( + const string &strName) const { return _pParameterMgr->getSelectionCriterion(strName); } @@ -80,15 +83,22 @@ void CParameterMgrPlatformConnector::applyConfigurations() } // Dynamic parameter handling -CParameterHandle* CParameterMgrPlatformConnector::createParameterHandle(const string& strPath, string& strError) const +CParameterHandle *CParameterMgrPlatformConnector::createParameterHandle(const string &strPath, + string &strError) const { assert(_bStarted); return _pParameterMgr->createParameterHandle(strPath, strError); } +ElementHandle *CParameterMgrPlatformConnector::createElementHandle(const string &strPath, + string &strError) const +{ + return _pParameterMgr->createElementHandle(strPath, strError); +} + // Logging -void CParameterMgrPlatformConnector::setLogger(CParameterMgrPlatformConnector::ILogger* pLogger) +void CParameterMgrPlatformConnector::setLogger(CParameterMgrPlatformConnector::ILogger *pLogger) { _pLogger = pLogger; } @@ -115,13 +125,13 @@ bool CParameterMgrPlatformConnector::setFailureOnMissingSubsystem(bool bFail, st return true; } -bool CParameterMgrPlatformConnector::getFailureOnMissingSubsystem() +bool CParameterMgrPlatformConnector::getFailureOnMissingSubsystem() const { return _pParameterMgr->getFailureOnMissingSubsystem(); } -bool CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad( - bool bFail, std::string& strError) +bool CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad(bool bFail, + std::string &strError) { if (_bStarted) { @@ -133,23 +143,23 @@ bool CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad( return true; } -bool CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad() +bool CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad() const { return _pParameterMgr->getFailureOnFailedSettingsLoad(); } -const string& CParameterMgrPlatformConnector::getSchemaFolderLocation() const +const string &CParameterMgrPlatformConnector::getSchemaUri() const { - return _pParameterMgr->getSchemaFolderLocation(); + return _pParameterMgr->getSchemaUri(); } -void CParameterMgrPlatformConnector::setSchemaFolderLocation(const string& strSchemaFolderLocation) +void CParameterMgrPlatformConnector::setSchemaUri(const string &schemaUri) { - _pParameterMgr->setSchemaFolderLocation(strSchemaFolderLocation); + _pParameterMgr->setSchemaUri(schemaUri); } -bool CParameterMgrPlatformConnector::setValidateSchemasOnStart( - bool bValidate, std::string& strError) +bool CParameterMgrPlatformConnector::setValidateSchemasOnStart(bool bValidate, + std::string &strError) { if (_bStarted) { @@ -161,13 +171,13 @@ bool CParameterMgrPlatformConnector::setValidateSchemasOnStart( return true; } -bool CParameterMgrPlatformConnector::getValidateSchemasOnStart() +bool CParameterMgrPlatformConnector::getValidateSchemasOnStart() const { return _pParameterMgr->getValidateSchemasOnStart(); } // Start -bool CParameterMgrPlatformConnector::start(string& strError) +bool CParameterMgrPlatformConnector::start(string &strError) { // Create data structure if (!_pParameterMgr->load(strError)) { @@ -187,10 +197,18 @@ bool CParameterMgrPlatformConnector::isStarted() const } // Private logging -void CParameterMgrPlatformConnector::doLog(bool bIsWarning, const string& strLog) +void CParameterMgrPlatformConnector::info(const string &log) +{ + if (_pLogger) { + + _pLogger->info(log); + } +} + +void CParameterMgrPlatformConnector::warning(const string &log) { if (_pLogger) { - _pLogger->log(bIsWarning, strLog); + _pLogger->warning(log); } } diff --git a/parameter/ParameterType.cpp b/parameter/ParameterType.cpp index eb9fd3d..5472f27 100644 --- a/parameter/ParameterType.cpp +++ b/parameter/ParameterType.cpp @@ -31,7 +31,8 @@ #include "Parameter.h" #include "ArrayParameter.h" #include "ParameterAccessContext.h" -#include "Utility.h" + +#include <climits> #define base CTypeElement @@ -39,30 +40,25 @@ using std::string; const std::string CParameterType::gUnitPropertyName = "Unit"; -CParameterType::CParameterType(const string& strName) : base(strName), _uiSize(0) -{ -} - -CParameterType::~CParameterType() +CParameterType::CParameterType(const string &strName) : base(strName) { } // Object creation -void CParameterType::populate(CElement* pElement) const +void CParameterType::populate(CElement * /*elem*/) const { - (void)pElement; // Prevent further digging for instantiaton since we're leaf on the strcture tree } // Size -void CParameterType::setSize(uint32_t uiSize) +void CParameterType::setSize(size_t size) { - _uiSize = uiSize; + _size = size; } -uint32_t CParameterType::getSize() const +size_t CParameterType::getSize() const { - return _uiSize; + return _size; } // Unit @@ -71,44 +67,46 @@ string CParameterType::getUnit() const return _strUnit; } -void CParameterType::setUnit(const std::string& strUnit) +void CParameterType::setUnit(const std::string &strUnit) { _strUnit = strUnit; } // From IXmlSink -bool CParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { - setUnit(xmlElement.getAttributeString(gUnitPropertyName)); + xmlElement.getAttribute(gUnitPropertyName, _strUnit); return base::fromXml(xmlElement, serializingContext); } // From IXmlSource -void CParameterType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { base::toXml(xmlElement, serializingContext); setXmlUnitAttribute(xmlElement); } -void CParameterType::setXmlUnitAttribute(CXmlElement& xmlElement) const +void CParameterType::setXmlUnitAttribute(CXmlElement &xmlElement) const { - const string& unit = getUnit(); + const string &unit = getUnit(); if (!unit.empty()) { - xmlElement.setAttributeString(gUnitPropertyName, unit); + xmlElement.setAttribute(gUnitPropertyName, unit); } } // XML Serialization value space handling // Value space handling for configuration import/export -void CParameterType::handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const +void CParameterType::handleValueSpaceAttribute( + CXmlElement & /*xmlConfigurableElementSettingsElement*/, + CConfigurationAccessContext & /*ctx*/) const { - (void)xmlConfigurableElementSettingsElement; - (void)configurationAccessContext; // Do nothing by default } // Element properties -void CParameterType::showProperties(string& strResult) const +void CParameterType::showProperties(string &strResult) const { base::showProperties(strResult); @@ -118,7 +116,7 @@ void CParameterType::showProperties(string& strResult) const } // Scalar size - strResult += "Scalar size: " + CUtility::toString(getSize()) + " byte(s) \n"; + strResult += "Scalar size: " + std::to_string(getSize()) + " byte(s) \n"; } // Default value handling (simulation only) @@ -128,7 +126,7 @@ uint32_t CParameterType::getDefaultValue() const } // Parameter instantiation -CInstanceConfigurableElement* CParameterType::doInstantiate() const +CInstanceConfigurableElement *CParameterType::doInstantiate() const { if (isScalar()) { // Scalar parameter @@ -139,27 +137,27 @@ CInstanceConfigurableElement* CParameterType::doInstantiate() const } } -void CParameterType::signExtend(int32_t& iData) const +void CParameterType::signExtend(int32_t &iData) const { doSignExtend(iData); } -void CParameterType::signExtend(int64_t& iData) const +void CParameterType::signExtend(int64_t &iData) const { doSignExtend(iData); } // Generic sign extension template <typename type> -void CParameterType::doSignExtend(type& data) const +void CParameterType::doSignExtend(type &data) const { - uint32_t uiSizeInBits = getSize() * 8; - uint32_t uiShift = 8 * sizeof(data) - uiSizeInBits; - - if (uiShift) { - - data = (data << uiShift) >> uiShift; - } + size_t shift = CHAR_BIT * (sizeof(data) - getSize()); + // FIXME: If `data` has a signed type and nonnegative value, + // and `data × 2^shift` is representable in the result type, + // then that is the resulting value; + // otherwise, **the behavior is undefined**. + // ISO C99 (6.5.7/4) & ISO C++11 [expr.shift] + data = (data << shift) >> shift; } // Check data has no bit set outside available range (32 bits) @@ -183,33 +181,29 @@ bool CParameterType::doIsEncodable(type data, bool bIsSigned) const return true; } - uint32_t uiShift = getSize() * 8; + size_t shift = getSize() * 8; if (!bIsSigned) { // Check high bits are clean - return !(data >> uiShift); + return !(data >> shift); } else { // Negative value? - bool bIsValueExpectedNegative = (data & (1 << (uiShift - 1))) != 0; + bool bIsValueExpectedNegative = (data & (type(1) << (shift - 1))) != 0; // Check high bits are clean - return bIsValueExpectedNegative ? !(~data >> uiShift) : !(data >> uiShift); + return bIsValueExpectedNegative ? !(~data >> shift) : !(data >> shift); } } // Remove all bits set outside available range uint32_t CParameterType::makeEncodable(uint32_t uiData) const { - if (getSize() == sizeof(uint32_t)) { - - return uiData; - } - uint32_t uiSizeInBits = getSize() * 8; + size_t sizeInBits = getSize() * 8; - uint32_t uiMask = (1 << uiSizeInBits) - 1; + uint32_t uiMask = (1 << sizeInBits) - 1; return uiData & uiMask; } @@ -217,95 +211,65 @@ uint32_t CParameterType::makeEncodable(uint32_t uiData) const // Conversions (dynamic access) // Value access // Boolean -bool CParameterType::toBlackboard(bool bUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::toBlackboard(bool /*bUserValue*/, uint32_t & /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)bUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); - return false; } -bool CParameterType::fromBlackboard(bool& bUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::fromBlackboard(bool & /*bUserValue*/, uint32_t /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)bUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); - return false; } // Integer -bool CParameterType::toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::toBlackboard(uint32_t /*uiUserValue*/, uint32_t & /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)uiUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); - return false; } -bool CParameterType::fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::fromBlackboard(uint32_t & /*uiUserValue*/, uint32_t /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)uiUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); - return false; } // Signed Integer -bool CParameterType::toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::toBlackboard(int32_t /*iUserValue*/, uint32_t & /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)iUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); return false; } -bool CParameterType::fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::fromBlackboard(int32_t & /*iUserValue*/, uint32_t /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)iUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); return false; } // Double -bool CParameterType::toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::toBlackboard(double /*dUserValue*/, uint32_t & /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)dUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); return false; } -bool CParameterType::fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const +bool CParameterType::fromBlackboard(double & /*dUserValue*/, uint32_t /*uiValue*/, + CParameterAccessContext ¶meterAccessContext) const { - (void)dUserValue; - (void)uiValue; - (void)parameterAccessContext; - parameterAccessContext.setError("Unsupported conversion"); return false; } - - diff --git a/parameter/ParameterType.h b/parameter/ParameterType.h index cf58f7b..5cb32d9 100644 --- a/parameter/ParameterType.h +++ b/parameter/ParameterType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,6 +29,8 @@ */ #pragma once +#include "parameter_export.h" + #include <stdint.h> #include <limits> @@ -39,48 +41,70 @@ class CParameterAccessContext; class CConfigurationAccessContext; -class CParameterType : public CTypeElement +class PARAMETER_EXPORT CParameterType : public CTypeElement { public: - CParameterType(const std::string& strName); - virtual ~CParameterType(); + CParameterType(const std::string &strName); + virtual ~CParameterType() = default; // Size - uint32_t getSize() const; + size_t getSize() const; // Unit std::string getUnit() const; - void setUnit(const std::string& strUnit); + void setUnit(const std::string &strUnit); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; /// Conversions // String - virtual bool toBlackboard(const std::string& strValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const = 0; - virtual bool fromBlackboard(std::string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const = 0; + virtual bool toBlackboard(const std::string &strValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const = 0; + virtual bool fromBlackboard(std::string &strValue, const uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const = 0; // Boolean - virtual bool toBlackboard(bool bUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(bool& bUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(bool bUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(bool &bUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Integer - virtual bool toBlackboard(uint32_t uiUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(uint32_t& uiUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(uint32_t uiUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(uint32_t &uiUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Signed Integer - virtual bool toBlackboard(int32_t iUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(int32_t& iUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(int32_t iUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(int32_t &iUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; // Double - virtual bool toBlackboard(double dUserValue, uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const; - virtual bool fromBlackboard(double& dUserValue, uint32_t uiValue, CParameterAccessContext& parameterAccessContext) const; + virtual bool toBlackboard(double dUserValue, uint32_t &uiValue, + CParameterAccessContext ¶meterAccessContext) const; + virtual bool fromBlackboard(double &dUserValue, uint32_t uiValue, + CParameterAccessContext ¶meterAccessContext) const; - // XML Serialization value space handling - // Value space handling for configuration import/export - virtual void handleValueSpaceAttribute(CXmlElement& xmlConfigurableElementSettingsElement, CConfigurationAccessContext& configurationAccessContext) const; + /** Value space handling for settings import/export from/to XML + * + * During export, this method set the "ValueSpace" attribute of the future + * XML element according to the export context. + * + * During import, this method reads the "ValueSpace" attribute of the XML + * element being imported and sets the access context's value space + * accordingly. + * + * @param[in,out] xmlConfigurableElementSettingsElement the element being imported or exported + * @param[in,out] configurationAccessContext the import or export context + */ + virtual void handleValueSpaceAttribute( + CXmlElement &xmlConfigurableElementSettingsElement, + CConfigurationAccessContext &configurationAccessContext) const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // Default value handling (simulation only) virtual uint32_t getDefaultValue() const; @@ -88,22 +112,22 @@ public: /** * Sign extension (32 bits) * - * @param[in:out] iData the data which will be sign extended + * @param[in,out] iData the data which will be sign extended */ - void signExtend(int32_t& iData) const; + void signExtend(int32_t &iData) const; /** * Sign extension (64 bits) * - * @param[in:out] iData the data which will be sign extended + * @param[in,out] iData the data which will be sign extended */ - void signExtend(int64_t& iData) const; + void signExtend(int64_t &iData) const; protected: // Object creation - virtual void populate(CElement* pElement) const; + virtual void populate(CElement *pElement) const; // Size - void setSize(uint32_t uiSize); + void setSize(size_t size); // Check data has no bit set outside available range (based on byte size) and // check data is consistent with available range, with respect to its sign @@ -116,24 +140,26 @@ protected: template <typename type> type getMaxValue() const { - return getSize() < sizeof(type) ? - (static_cast<type>(1) << (getSize() * std::numeric_limits<unsigned char>::digits - 1)) - 1 : - std::numeric_limits<type>::max(); + return getSize() < sizeof(type) + ? (static_cast<type>(1) + << (getSize() * std::numeric_limits<unsigned char>::digits - 1)) - + 1 + : std::numeric_limits<type>::max(); } private: - void setXmlUnitAttribute(CXmlElement& xmlElement) const; + void setXmlUnitAttribute(CXmlElement &xmlElement) const; // Instantiation - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; // Generic Access template <typename type> - void doSignExtend(type& data) const; + void doSignExtend(type &data) const; template <typename type> bool doIsEncodable(type data, bool bIsSigned) const; // Size in bytes - uint32_t _uiSize; + size_t _size{0}; // Unit std::string _strUnit; diff --git a/parameter/PathNavigator.cpp b/parameter/PathNavigator.cpp index 47fc5c5..36deaea 100644 --- a/parameter/PathNavigator.cpp +++ b/parameter/PathNavigator.cpp @@ -30,12 +30,12 @@ #include "PathNavigator.h" #include "Tokenizer.h" -CPathNavigator::CPathNavigator(const std::string& strPath) : _uiCurrentIndex(0) +CPathNavigator::CPathNavigator(const std::string &strPath) { init(strPath); } -void CPathNavigator::init(const std::string& strPath) +void CPathNavigator::init(const std::string &strPath) { Tokenizer tokenizer(strPath, "/"); @@ -50,7 +50,7 @@ bool CPathNavigator::isPathValid() const } // Navigate through -bool CPathNavigator::navigateThrough(const std::string& strItemName, std::string& strError) +bool CPathNavigator::navigateThrough(const std::string &strItemName, std::string &strError) { if (!_bValid) { @@ -59,20 +59,20 @@ bool CPathNavigator::navigateThrough(const std::string& strItemName, std::string return false; } - std::string* pStrChildName = next(); + std::string *pStrChildName = next(); if (!pStrChildName) { - strError = "Path not complete: " + getCurrentPath() + - ", trying to access to " + strItemName; + strError = + "Path not complete: " + getCurrentPath() + ", trying to access to " + strItemName; return false; } if (*pStrChildName != strItemName) { - strError = "Path not found: " + getCurrentPath() + - ", expected: " + strItemName + " but found: " + *pStrChildName; + strError = "Path not found: " + getCurrentPath() + ", expected: " + strItemName + + " but found: " + *pStrChildName; return false; } @@ -80,11 +80,11 @@ bool CPathNavigator::navigateThrough(const std::string& strItemName, std::string return true; } -std::string* CPathNavigator::next() +std::string *CPathNavigator::next() { - if (_uiCurrentIndex < _astrItems.size()) { + if (_currentIndex < _astrItems.size()) { - return &_astrItems[_uiCurrentIndex++]; + return &_astrItems[_currentIndex++]; } return NULL; @@ -94,25 +94,23 @@ std::string CPathNavigator::getCurrentPath() const { std::string strPath = "/"; - if (!_uiCurrentIndex) { + if (!_currentIndex) { return strPath; } - uint32_t uiItem; + size_t item; + for (item = 0; item < _currentIndex - 1; item++) { - for (uiItem = 0; uiItem < _uiCurrentIndex - 1; uiItem++) { - - strPath += _astrItems[uiItem] + "/"; + strPath += _astrItems[item] + "/"; } - strPath += _astrItems[uiItem]; + strPath += _astrItems[item]; return strPath; } - -bool CPathNavigator::checkPathFormat(const std::string& strUpl) +bool CPathNavigator::checkPathFormat(const std::string &strUpl) { return strUpl[0] == '/'; } diff --git a/parameter/PathNavigator.h b/parameter/PathNavigator.h index 3db709a..e8df53d 100644 --- a/parameter/PathNavigator.h +++ b/parameter/PathNavigator.h @@ -36,25 +36,25 @@ class CPathNavigator { public: - CPathNavigator(const std::string& strPath); + CPathNavigator(const std::string &strPath); // Path validity bool isPathValid() const; // Navigate through - bool navigateThrough(const std::string& strItemName, std::string& strError); + bool navigateThrough(const std::string &strItemName, std::string &strError); // Nagivate - std::string* next(); + std::string *next(); // Current path std::string getCurrentPath() const; private: - void init(const std::string& strPath); - static bool checkPathFormat(const std::string& strUpl); + void init(const std::string &strPath); + static bool checkPathFormat(const std::string &strUpl); bool _bValid; std::vector<std::string> _astrItems; - uint32_t _uiCurrentIndex; + size_t _currentIndex{0}; }; diff --git a/parameter/Plugin.h b/parameter/Plugin.h new file mode 100644 index 0000000..137d96c --- /dev/null +++ b/parameter/Plugin.h @@ -0,0 +1,50 @@ +/* + * 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. + */ +#pragma once + +/** @file + * + * This file is intended to be used by the plugins. + * + * The compilation unit defining the entry point (aka the Subsystem Builder) + * should include this file a define a function corresponding to the one + * declared below. + */ + +#include <SubsystemLibrary.h> + +extern "C" { +#if defined(__clang__) || defined(__GNUC__) +__attribute__((visibility("default"))) +#elif defined(_MSC_VER) +__declspec(dllexport) +#endif + void PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1(CSubsystemLibrary*, core::log::Logger&); +} diff --git a/parameter/PluginLocation.cpp b/parameter/PluginLocation.cpp index 92f2ce9..1c98ce3 100644 --- a/parameter/PluginLocation.cpp +++ b/parameter/PluginLocation.cpp @@ -31,27 +31,25 @@ #define base CKindElement -CPluginLocation::CPluginLocation(const std::string& strName, const std::string& strKind) : base(strName, strKind) +CPluginLocation::CPluginLocation(const std::string &strName, const std::string &strKind) + : base(strName, strKind) { - } -const std::string& CPluginLocation::getFolder() const +const std::string &CPluginLocation::getFolder() const { return _strFolder; } -const std::list<std::string>& CPluginLocation::getPluginList() const +const std::list<std::string> &CPluginLocation::getPluginList() const { return _pluginList; } -bool CPluginLocation::fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) +bool CPluginLocation::fromXml(const CXmlElement &xmlElement, CXmlSerializingContext & /*ctx*/) { - (void) serializingContext; - // Retrieve folder - _strFolder = xmlElement.getAttributeString("Folder"); + xmlElement.getAttribute("Folder", _strFolder); // Get Info from children CXmlElement::CChildIterator childIterator(xmlElement); @@ -61,7 +59,7 @@ bool CPluginLocation::fromXml(const CXmlElement &xmlElement, CXmlSerializingCont while (childIterator.next(xmlPluginElement)) { // Fill Plugin List - _pluginList.push_back(xmlPluginElement.getAttributeString("Name")); + _pluginList.push_back(xmlPluginElement.getNameAttribute()); } // Don't dig diff --git a/parameter/PluginLocation.h b/parameter/PluginLocation.h index 3a8e131..2a663d2 100644 --- a/parameter/PluginLocation.h +++ b/parameter/PluginLocation.h @@ -36,19 +36,18 @@ class CPluginLocation : public CKindElement { public: - CPluginLocation(const std::string& strName, const std::string& strKind); + CPluginLocation(const std::string &strName, const std::string &strKind); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // Folder - const std::string& getFolder() const; + const std::string &getFolder() const; // Plugin list - const std::list<std::string>& getPluginList() const; + const std::list<std::string> &getPluginList() const; private: std::string _strFolder; std::list<std::string> _pluginList; - }; diff --git a/remote-processor/ConnectionSocket.h b/parameter/Results.h index 707579b..3f7a13c 100644 --- a/remote-processor/ConnectionSocket.h +++ b/parameter/Results.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2014, Intel Corporation +/* + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,16 +29,13 @@ */ #pragma once -#include "Socket.h" - +#include <list> #include <string> -class CConnectionSocket : public CSocket +namespace core { -public: - CConnectionSocket(); - // Connection - bool connect(const std::string& strRemote, uint16_t uiPort, std::string& strError); -}; +/** String list type which can hold list of error/info */ +typedef std::list<std::string> Results; +} /** core namespace */ diff --git a/parameter/Rule.h b/parameter/Rule.h index 42f420d..6affb26 100644 --- a/parameter/Rule.h +++ b/parameter/Rule.h @@ -40,10 +40,10 @@ class CRule : public CElement public: // Parse - virtual bool parse(CRuleParser& ruleParser, std::string& strError) = 0; + virtual bool parse(CRuleParser &ruleParser, std::string &strError) = 0; // Dump - virtual void dump(std::string& strResult) const = 0; + virtual std::string dump() const = 0; // Rule check virtual bool matches() const = 0; diff --git a/parameter/RuleParser.cpp b/parameter/RuleParser.cpp index e77b3c8..72424d2 100644 --- a/parameter/RuleParser.cpp +++ b/parameter/RuleParser.cpp @@ -30,27 +30,25 @@ #include "RuleParser.h" #include "CompoundRule.h" #include "SelectionCriterionRule.h" +#include "AlwaysAssert.hpp" #include <assert.h> using std::string; // Matches -const char* CRuleParser::_acDelimiters[CRuleParser::ENbStatuses] = { - "{", // EInit - "{} ", // EBeginCompoundRule - ",}", // EEndCompoundRule - ",}", // ECriterionRule - "{ ", // EContinue - "" // EDone +const char *CRuleParser::_acDelimiters[CRuleParser::ENbStatuses] = { + "{", // EInit + "{} ", // EBeginCompoundRule + ",}", // EEndCompoundRule + ",}", // ECriterionRule + "{ ", // EContinue + "" // EDone }; -CRuleParser::CRuleParser(const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition) : - _strApplicationRule(strApplicationRule), - _pSelectionCriteriaDefinition(pSelectionCriteriaDefinition), - _uiCurrentPos(0), - _uiCurrentDeepness(0), - _eStatus(CRuleParser::EInit), - _pRootRule(NULL) +CRuleParser::CRuleParser(const string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition) + : _strApplicationRule(strApplicationRule), + _pSelectionCriteriaDefinition(pSelectionCriteriaDefinition) { } @@ -60,7 +58,7 @@ CRuleParser::~CRuleParser() } // Parse -bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) +bool CRuleParser::parse(CCompoundRule *pParentRule, string &strError) { while (true) { // Iterate till next relevant delimiter @@ -68,11 +66,11 @@ bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) return false; } - switch(_eStatus) { + switch (_eStatus) { case EBeginCompoundRule: { // Create new compound rule - CCompoundRule* pCompoundRule = new CCompoundRule; + CCompoundRule *pCompoundRule = new CCompoundRule; // Parse if (!pCompoundRule->parse(*this, strError)) { @@ -106,7 +104,7 @@ bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) break; case ECriterionRule: { // Create new criterion rule - CSelectionCriterionRule* pCriterionRule = new CSelectionCriterionRule; + CSelectionCriterionRule *pCriterionRule = new CSelectionCriterionRule; // Parse if (!pCriterionRule->parse(*this, strError)) { @@ -116,6 +114,7 @@ bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) return false; } + ALWAYS_ASSERT(pParentRule != NULL, "Invalid parent rule given to rule parser"); // Chain pParentRule->addChild(pCriterionRule); @@ -134,7 +133,6 @@ bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) return false; } - } default: assert(0); @@ -146,11 +144,11 @@ bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) } // Iterate -bool CRuleParser::iterate(string& strError) +bool CRuleParser::iterate(string &strError) { string::size_type delimiter; - assert(_uiCurrentPos <= _strApplicationRule.length()); + ALWAYS_ASSERT(_uiCurrentPos <= _strApplicationRule.length(), "Current Position outside range"); // Consume spaces if ((delimiter = _strApplicationRule.find_first_not_of(" ", _uiCurrentPos)) != string::npos) { @@ -160,20 +158,22 @@ bool CRuleParser::iterate(string& strError) } // Parse - if ((_uiCurrentPos != _strApplicationRule.length()) && ((delimiter = _strApplicationRule.find_first_of(_acDelimiters[_eStatus], _uiCurrentPos)) != string::npos)) { + if ((_uiCurrentPos != _strApplicationRule.length()) && + ((delimiter = _strApplicationRule.find_first_of(_acDelimiters[_eStatus], _uiCurrentPos)) != + string::npos)) { - switch(_strApplicationRule[delimiter]) { + switch (_strApplicationRule[delimiter]) { case '{': _eStatus = EBeginCompoundRule; // Extract type _strRuleType = _strApplicationRule.substr(_uiCurrentPos, delimiter - _uiCurrentPos); - _uiCurrentDeepness++; + _currentDeepness++; break; case '}': _eStatus = EEndCompoundRule; - if (!_uiCurrentDeepness--) { + if (!_currentDeepness--) { strError = "Missing opening brace"; @@ -193,7 +193,7 @@ bool CRuleParser::iterate(string& strError) _uiCurrentPos = delimiter + 1; } else { - if (_uiCurrentDeepness) { + if (_currentDeepness) { strError = "Missing closing brace"; @@ -214,21 +214,21 @@ bool CRuleParser::iterate(string& strError) } // Rule type -const string& CRuleParser::getType() const +const string &CRuleParser::getType() const { return _strRuleType; } // Criteria defintion -const CSelectionCriteriaDefinition* CRuleParser::getSelectionCriteriaDefinition() const +const CSelectionCriteriaDefinition *CRuleParser::getSelectionCriteriaDefinition() const { return _pSelectionCriteriaDefinition; } // Root rule -CCompoundRule* CRuleParser::grabRootRule() +CCompoundRule *CRuleParser::grabRootRule() { - CCompoundRule* pRootRule = _pRootRule; + CCompoundRule *pRootRule = _pRootRule; assert(pRootRule); @@ -238,7 +238,7 @@ CCompoundRule* CRuleParser::grabRootRule() } // Next word -bool CRuleParser::next(string& strNext, string& strError) +bool CRuleParser::next(string &strNext, string &strError) { string::size_type delimiter; diff --git a/parameter/RuleParser.h b/parameter/RuleParser.h index 803ea3e..74c1863 100644 --- a/parameter/RuleParser.h +++ b/parameter/RuleParser.h @@ -38,7 +38,8 @@ class CSelectionCriteriaDefinition; class CRuleParser { public: - enum Status { + enum Status + { EInit, EBeginCompoundRule, EEndCompoundRule, @@ -49,46 +50,46 @@ public: ENbStatuses }; - CRuleParser(const std::string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition); + CRuleParser(const std::string &strApplicationRule, + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition); ~CRuleParser(); // Parse - bool parse(CCompoundRule* pParentRule, std::string& strError); + bool parse(CCompoundRule *pParentRule, std::string &strError); // Iterate - bool iterate(std::string& strError); + bool iterate(std::string &strError); // Next word - bool next(std::string& strNext, std::string& strError); + bool next(std::string &strNext, std::string &strError); // Rule type - const std::string& getType() const; + const std::string &getType() const; // Criteria defintion - const CSelectionCriteriaDefinition* getSelectionCriteriaDefinition() const; + const CSelectionCriteriaDefinition *getSelectionCriteriaDefinition() const; // Root rule - CCompoundRule* grabRootRule(); -private: + CCompoundRule *grabRootRule(); - CRuleParser(const CRuleParser&); - CRuleParser& operator=(const CRuleParser&); +private: + CRuleParser(const CRuleParser &); + CRuleParser &operator=(const CRuleParser &); // Rule definition std::string _strApplicationRule; // Criteria defintion - const CSelectionCriteriaDefinition* _pSelectionCriteriaDefinition; + const CSelectionCriteriaDefinition *_pSelectionCriteriaDefinition; /** String iterator */ - std::string::size_type _uiCurrentPos; + std::string::size_type _uiCurrentPos{0}; // Deepness - uint32_t _uiCurrentDeepness; + size_t _currentDeepness{0}; // Current Type std::string _strRuleType; // Status - Status _eStatus; + Status _eStatus{EInit}; // Root rule - CCompoundRule* _pRootRule; + CCompoundRule *_pRootRule{nullptr}; // Matches - static const char* _acDelimiters[ENbStatuses]; + static const char *_acDelimiters[ENbStatuses]; }; - diff --git a/parameter/SelectionCriteria.cpp b/parameter/SelectionCriteria.cpp index 87ad76e..0939e60 100644 --- a/parameter/SelectionCriteria.cpp +++ b/parameter/SelectionCriteria.cpp @@ -45,26 +45,29 @@ std::string CSelectionCriteria::getKind() const } // Selection Criteria/Type creation -CSelectionCriterionType* CSelectionCriteria::createSelectionCriterionType(bool bIsInclusive) +CSelectionCriterionType *CSelectionCriteria::createSelectionCriterionType(bool bIsInclusive) { return getSelectionCriterionLibrary()->createSelectionCriterionType(bIsInclusive); } -CSelectionCriterion* CSelectionCriteria::createSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pSelectionCriterionType) +CSelectionCriterion *CSelectionCriteria::createSelectionCriterion( + const std::string &strName, const CSelectionCriterionType *pType, core::log::Logger &logger) { - return getSelectionCriteriaDefinition()->createSelectionCriterion(strName, pSelectionCriterionType); + return getSelectionCriteriaDefinition()->createSelectionCriterion(strName, pType, logger); } // Selection criterion retrieval -CSelectionCriterion* CSelectionCriteria::getSelectionCriterion(const std::string& strName) +CSelectionCriterion *CSelectionCriteria::getSelectionCriterion(const std::string &strName) { return getSelectionCriteriaDefinition()->getSelectionCriterion(strName); } // List available criteria -void CSelectionCriteria::listSelectionCriteria(std::list<std::string>& lstrResult, bool bWithTypeInfo, bool bHumanReadable) const +void CSelectionCriteria::listSelectionCriteria(std::list<std::string> &lstrResult, + bool bWithTypeInfo, bool bHumanReadable) const { - getSelectionCriteriaDefinition()->listSelectionCriteria(lstrResult, bWithTypeInfo, bHumanReadable); + getSelectionCriteriaDefinition()->listSelectionCriteria(lstrResult, bWithTypeInfo, + bHumanReadable); } // Reset the modified status of the children @@ -74,17 +77,18 @@ void CSelectionCriteria::resetModifiedStatus() } // Children access -CSelectionCriterionLibrary* CSelectionCriteria::getSelectionCriterionLibrary() +CSelectionCriterionLibrary *CSelectionCriteria::getSelectionCriterionLibrary() { - return static_cast<CSelectionCriterionLibrary*>(getChild(ESelectionCriterionLibrary)); + return static_cast<CSelectionCriterionLibrary *>(getChild(ESelectionCriterionLibrary)); } -CSelectionCriteriaDefinition* CSelectionCriteria::getSelectionCriteriaDefinition() +CSelectionCriteriaDefinition *CSelectionCriteria::getSelectionCriteriaDefinition() { - return static_cast<CSelectionCriteriaDefinition*>(getChild(ESelectionCriteriaDefinition)); + return static_cast<CSelectionCriteriaDefinition *>(getChild(ESelectionCriteriaDefinition)); } -const CSelectionCriteriaDefinition* CSelectionCriteria::getSelectionCriteriaDefinition() const +const CSelectionCriteriaDefinition *CSelectionCriteria::getSelectionCriteriaDefinition() const { - return static_cast<const CSelectionCriteriaDefinition*>(getChild(ESelectionCriteriaDefinition)); + return static_cast<const CSelectionCriteriaDefinition *>( + getChild(ESelectionCriteriaDefinition)); } diff --git a/parameter/SelectionCriteria.h b/parameter/SelectionCriteria.h index 122b8a2..22f4de1 100644 --- a/parameter/SelectionCriteria.h +++ b/parameter/SelectionCriteria.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -33,6 +33,7 @@ #include "Element.h" #include "SelectionCriterionType.h" #include "SelectionCriterion.h" +#include <log/Logger.h> #include <string> @@ -42,32 +43,38 @@ class ISelectionCriterionObserver; class CSelectionCriteria : public CElement { - enum ChildElementType { + enum ChildElementType + { ESelectionCriterionLibrary, ESelectionCriteriaDefinition }; + public: CSelectionCriteria(); // Selection Criteria/Type creation - CSelectionCriterionType* createSelectionCriterionType(bool bIsInclusive); - CSelectionCriterion* createSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pSelectionCriterionType); + CSelectionCriterionType *createSelectionCriterionType(bool bIsInclusive); + CSelectionCriterion *createSelectionCriterion(const std::string &strName, + const CSelectionCriterionType *pType, + core::log::Logger &logger); // Selection criterion retrieval - CSelectionCriterion* getSelectionCriterion(const std::string& strName); + CSelectionCriterion *getSelectionCriterion(const std::string &strName); // Selection Criterion definition - const CSelectionCriteriaDefinition* getSelectionCriteriaDefinition() const; + const CSelectionCriteriaDefinition *getSelectionCriteriaDefinition() const; // List available criteria - void listSelectionCriteria(std::list<std::string>& strResult, bool bWithTypeInfo, bool bHumanReadable) const; + void listSelectionCriteria(std::list<std::string> &strResult, bool bWithTypeInfo, + bool bHumanReadable) const; // Base virtual std::string getKind() const; // Reset the modified status of the children void resetModifiedStatus(); + private: // Children access - CSelectionCriterionLibrary* getSelectionCriterionLibrary(); - CSelectionCriteriaDefinition* getSelectionCriteriaDefinition(); + CSelectionCriterionLibrary *getSelectionCriterionLibrary(); + CSelectionCriteriaDefinition *getSelectionCriteriaDefinition(); }; diff --git a/parameter/SelectionCriteriaDefinition.cpp b/parameter/SelectionCriteriaDefinition.cpp index d7c4228..12f1aa2 100644 --- a/parameter/SelectionCriteriaDefinition.cpp +++ b/parameter/SelectionCriteriaDefinition.cpp @@ -30,19 +30,16 @@ #include "SelectionCriteriaDefinition.h" #include "SelectionCriterion.h" -CSelectionCriteriaDefinition::CSelectionCriteriaDefinition() -{ -} - std::string CSelectionCriteriaDefinition::getKind() const { return "SelectionCriteriaDefinition"; } // Selection Criterion creation -CSelectionCriterion* CSelectionCriteriaDefinition::createSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pSelectionCriterionType) +CSelectionCriterion *CSelectionCriteriaDefinition::createSelectionCriterion( + const std::string &strName, const CSelectionCriterionType *pType, core::log::Logger &logger) { - CSelectionCriterion* pSelectionCriterion = new CSelectionCriterion(strName, pSelectionCriterionType); + CSelectionCriterion *pSelectionCriterion = new CSelectionCriterion(strName, pType, logger); addChild(pSelectionCriterion); @@ -50,18 +47,21 @@ CSelectionCriterion* CSelectionCriteriaDefinition::createSelectionCriterion(cons } // Selection Criterion access -const CSelectionCriterion* CSelectionCriteriaDefinition::getSelectionCriterion(const std::string& strName) const +const CSelectionCriterion *CSelectionCriteriaDefinition::getSelectionCriterion( + const std::string &strName) const { - return static_cast<const CSelectionCriterion*>(findChild(strName)); + return static_cast<const CSelectionCriterion *>(findChild(strName)); } -CSelectionCriterion* CSelectionCriteriaDefinition::getSelectionCriterion(const std::string& strName) +CSelectionCriterion *CSelectionCriteriaDefinition::getSelectionCriterion(const std::string &strName) { - return static_cast<CSelectionCriterion*>(findChild(strName)); + return static_cast<CSelectionCriterion *>(findChild(strName)); } // List available criteria -void CSelectionCriteriaDefinition::listSelectionCriteria(std::list<std::string>& lstrResult, bool bWithTypeInfo, bool bHumanReadable) const +void CSelectionCriteriaDefinition::listSelectionCriteria(std::list<std::string> &lstrResult, + bool bWithTypeInfo, + bool bHumanReadable) const { // Propagate size_t uiNbChildren = getNbChildren(); @@ -69,9 +69,11 @@ void CSelectionCriteriaDefinition::listSelectionCriteria(std::list<std::string>& for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CSelectionCriterion* pSelectionCriterion = static_cast<const CSelectionCriterion*>(getChild(uiChild)); + const CSelectionCriterion *pSelectionCriterion = + static_cast<const CSelectionCriterion *>(getChild(uiChild)); - lstrResult.push_back(pSelectionCriterion->getFormattedDescription(bWithTypeInfo, bHumanReadable)); + lstrResult.push_back( + pSelectionCriterion->getFormattedDescription(bWithTypeInfo, bHumanReadable)); } } @@ -81,11 +83,11 @@ void CSelectionCriteriaDefinition::resetModifiedStatus() // Propagate size_t uiNbChildren = getNbChildren(); size_t uiChild; - CSelectionCriterion* pSelectionCriterion; + CSelectionCriterion *pSelectionCriterion; for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - pSelectionCriterion = static_cast<CSelectionCriterion*>(getChild(uiChild)); + pSelectionCriterion = static_cast<CSelectionCriterion *>(getChild(uiChild)); pSelectionCriterion->resetModifiedStatus(); } diff --git a/parameter/SelectionCriteriaDefinition.h b/parameter/SelectionCriteriaDefinition.h index 617b379..a8fa75a 100644 --- a/parameter/SelectionCriteriaDefinition.h +++ b/parameter/SelectionCriteriaDefinition.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,23 +31,25 @@ #include "Element.h" #include "SelectionCriterion.h" +#include <log/Logger.h> class ISelectionCriterionObserver; class CSelectionCriteriaDefinition : public CElement { public: - CSelectionCriteriaDefinition(); - // Selection Criterion creation - CSelectionCriterion* createSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pSelectionCriterionType); + CSelectionCriterion *createSelectionCriterion(const std::string &strName, + const CSelectionCriterionType *pType, + core::log::Logger &logger); // Selection Criterion access - const CSelectionCriterion* getSelectionCriterion(const std::string& strName) const; - CSelectionCriterion* getSelectionCriterion(const std::string& strName); + const CSelectionCriterion *getSelectionCriterion(const std::string &strName) const; + CSelectionCriterion *getSelectionCriterion(const std::string &strName); // List available criteria - void listSelectionCriteria(std::list<std::string>& lstrResult, bool bWithTypeInfo, bool bHumanReadable) const; + void listSelectionCriteria(std::list<std::string> &lstrResult, bool bWithTypeInfo, + bool bHumanReadable) const; // Base virtual std::string getKind() const; @@ -55,4 +57,3 @@ public: // Reset the modified status of the children void resetModifiedStatus(); }; - diff --git a/parameter/SelectionCriterion.cpp b/parameter/SelectionCriterion.cpp index e45c993..f99abec 100644 --- a/parameter/SelectionCriterion.cpp +++ b/parameter/SelectionCriterion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,12 +29,17 @@ */ #include "SelectionCriterion.h" -#include "AutoLog.h" #include "Utility.h" +#include <log/Logger.h> #define base CElement -CSelectionCriterion::CSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pType) : base(strName), _iState(0), _pType(pType), _uiNbModifications(0) +using namespace core; + +CSelectionCriterion::CSelectionCriterion(const std::string &strName, + const CSelectionCriterionType *pType, + core::log::Logger &logger) + : base(strName), _pType(pType), _logger(logger) { } @@ -62,13 +67,17 @@ void CSelectionCriterion::setCriterionState(int iState) _iState = iState; - log_info("Selection criterion changed event: %s", getFormattedDescription(false, false).c_str()); + _logger.info() << "Selection criterion changed event: " + << getFormattedDescription(false, false); - // Check if the previous criterion value has been taken into account (i.e. at least one Configuration was applied + // Check if the previous criterion value has been taken into account (i.e. at least one + // Configuration was applied // since the last criterion change) if (_uiNbModifications != 0) { - log_warning("Selection criterion \"%s\" has been modified %d time(s) without any configuration application", getName().c_str(), _uiNbModifications); + _logger.warning() << "Selection criterion '" << getName() << "' has been modified " + << _uiNbModifications + << " time(s) without any configuration application"; } // Track the number of modifications for this criterion @@ -88,7 +97,7 @@ std::string CSelectionCriterion::getCriterionName() const } // Type -const ISelectionCriterionTypeInterface* CSelectionCriterion::getCriterionType() const +const ISelectionCriterionTypeInterface *CSelectionCriterion::getCriterionType() const { return _pType; } @@ -117,7 +126,8 @@ bool CSelectionCriterion::excludes(int iState) const } /// User request -std::string CSelectionCriterion::getFormattedDescription(bool bWithTypeInfo, bool bHumanReadable) const +std::string CSelectionCriterion::getFormattedDescription(bool bWithTypeInfo, + bool bHumanReadable) const { std::string strFormattedDescription; @@ -126,7 +136,7 @@ std::string CSelectionCriterion::getFormattedDescription(bool bWithTypeInfo, boo if (bWithTypeInfo) { // Display type info - CUtility::appendTitle(strFormattedDescription, getName() + ":"); + utility::appendTitle(strFormattedDescription, getName() + ":"); // States strFormattedDescription += "Possible states "; @@ -155,27 +165,26 @@ std::string CSelectionCriterion::getFormattedDescription(bool bWithTypeInfo, boo if (bWithTypeInfo) { // Type Kind strFormattedDescription += ", type kind: "; - strFormattedDescription += _pType->isTypeInclusive() ? "inclusive" : "exclusive"; + strFormattedDescription += _pType->isTypeInclusive() ? "inclusive" : "exclusive"; } // Current State - strFormattedDescription += ", current state: " + - _pType->getFormattedState(_iState); + strFormattedDescription += ", current state: " + _pType->getFormattedState(_iState); - if (bWithTypeInfo) { + if (bWithTypeInfo) { // States - strFormattedDescription += ", states: " + - _pType->listPossibleValues(); + strFormattedDescription += ", states: " + _pType->listPossibleValues(); } } return strFormattedDescription; } // XML export -void CSelectionCriterion::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CSelectionCriterion::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Current Value - xmlElement.setAttributeString("Value", _pType->getFormattedState(_iState)); + xmlElement.setAttribute("Value", _pType->getFormattedState(_iState)); // Serialize Type node _pType->toXml(xmlElement, serializingContext); diff --git a/parameter/SelectionCriterion.h b/parameter/SelectionCriterion.h index cf99035..76ec0ff 100644 --- a/parameter/SelectionCriterion.h +++ b/parameter/SelectionCriterion.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -32,13 +32,18 @@ #include "Element.h" #include "SelectionCriterionType.h" #include "SelectionCriterionInterface.h" +#include <log/Logger.h> +#include <NonCopyable.hpp> #include <string> -class CSelectionCriterion : public CElement, public ISelectionCriterionInterface +class CSelectionCriterion : public CElement, + public ISelectionCriterionInterface, + private utility::NonCopyable { public: - CSelectionCriterion(const std::string& strName, const CSelectionCriterionType* pType); + CSelectionCriterion(const std::string &strName, const CSelectionCriterionType *pType, + core::log::Logger &logger); /// From ISelectionCriterionInterface // State @@ -47,7 +52,7 @@ public: // Name virtual std::string getCriterionName() const; // Type - virtual const ISelectionCriterionTypeInterface* getCriterionType() const; + virtual const ISelectionCriterionTypeInterface *getCriterionType() const; // Modified status bool hasBeenModified() const; void resetModifiedStatus(); @@ -71,13 +76,17 @@ public: * @param[in] serializingContext The serializing context * */ - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; + private: // Current state - int _iState; + int _iState{0}; // Type - const CSelectionCriterionType* _pType; - // Counter to know how many modifications have been applied to this criterion - uint8_t _uiNbModifications; -}; + const CSelectionCriterionType *_pType; + /** Counter to know how many modifications have been applied to this criterion */ + uint32_t _uiNbModifications{0}; + + /** Application logger */ + core::log::Logger &_logger; +}; diff --git a/parameter/SelectionCriterionLibrary.cpp b/parameter/SelectionCriterionLibrary.cpp index 6910e41..fc9e943 100644 --- a/parameter/SelectionCriterionLibrary.cpp +++ b/parameter/SelectionCriterionLibrary.cpp @@ -31,19 +31,15 @@ #define base CElement -CSelectionCriterionLibrary::CSelectionCriterionLibrary() -{ -} - std::string CSelectionCriterionLibrary::getKind() const { return "SelectionCriterionLibrary"; } // Type creation -CSelectionCriterionType* CSelectionCriterionLibrary::createSelectionCriterionType(bool bIsInclusive) +CSelectionCriterionType *CSelectionCriterionLibrary::createSelectionCriterionType(bool bIsInclusive) { - CSelectionCriterionType* pSelectionCriterionType = new CSelectionCriterionType(bIsInclusive); + CSelectionCriterionType *pSelectionCriterionType = new CSelectionCriterionType(bIsInclusive); addChild(pSelectionCriterionType); diff --git a/parameter/SelectionCriterionLibrary.h b/parameter/SelectionCriterionLibrary.h index bb19777..a152258 100644 --- a/parameter/SelectionCriterionLibrary.h +++ b/parameter/SelectionCriterionLibrary.h @@ -35,10 +35,8 @@ class CSelectionCriterionLibrary : public CElement { public: - CSelectionCriterionLibrary(); - // Type creation - CSelectionCriterionType* createSelectionCriterionType(bool bIsInclusive); + CSelectionCriterionType *createSelectionCriterionType(bool bIsInclusive); // CElement virtual std::string getKind() const; diff --git a/parameter/SelectionCriterionRule.cpp b/parameter/SelectionCriterionRule.cpp index c376bb3..8c22045 100644 --- a/parameter/SelectionCriterionRule.cpp +++ b/parameter/SelectionCriterionRule.cpp @@ -40,16 +40,9 @@ using std::string; -const CSelectionCriterionRule::SMatchingRuleDescription CSelectionCriterionRule::_astMatchesWhen[CSelectionCriterionRule::ENbMatchesWhen] = { - { "Is", true }, - { "IsNot", true }, - { "Includes", false }, - { "Excludes", false } -}; - -CSelectionCriterionRule::CSelectionCriterionRule() : _pSelectionCriterion(NULL), _eMatchesWhen(CSelectionCriterionRule::EIs), _iMatchValue(0) -{ -} +const CSelectionCriterionRule::SMatchingRuleDescription + CSelectionCriterionRule::_astMatchesWhen[CSelectionCriterionRule::ENbMatchesWhen] = { + {"Is", true}, {"IsNot", true}, {"Includes", false}, {"Excludes", false}}; // Class kind string CSelectionCriterionRule::getKind() const @@ -58,19 +51,18 @@ string CSelectionCriterionRule::getKind() const } // Content dumping -void CSelectionCriterionRule::logValue(string& strValue, CErrorContext& errorContext) const +string CSelectionCriterionRule::logValue(utility::ErrorContext & /*cxt*/) const { - (void)errorContext; - // Dump rule - dump(strValue); + return dump(); } // Parse -bool CSelectionCriterionRule::parse(CRuleParser& ruleParser, string& strError) +bool CSelectionCriterionRule::parse(CRuleParser &ruleParser, string &strError) { // Criterion - _pSelectionCriterion = ruleParser.getSelectionCriteriaDefinition()->getSelectionCriterion(ruleParser.getType()); + _pSelectionCriterion = + ruleParser.getSelectionCriteriaDefinition()->getSelectionCriterion(ruleParser.getType()); // Check existence if (!_pSelectionCriterion) { @@ -116,18 +108,15 @@ bool CSelectionCriterionRule::parse(CRuleParser& ruleParser, string& strError) } // Dump -void CSelectionCriterionRule::dump(string& strResult) const +string CSelectionCriterionRule::dump() const { - // Criterion - strResult += _pSelectionCriterion->getName(); - strResult += " "; - // Verb - strResult += _astMatchesWhen[_eMatchesWhen].pcMatchesWhen; - strResult += " "; // Value - string strValue; - _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, strValue); - strResult += strValue; + string value; + _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, value); + + // "<Name> <Verb> <Value>" + return string(_pSelectionCriterion->getName()) + " " + + _astMatchesWhen[_eMatchesWhen].pcMatchesWhen + " " + value; } // Rule check @@ -135,7 +124,7 @@ bool CSelectionCriterionRule::matches() const { assert(_pSelectionCriterion); - switch(_eMatchesWhen) { + switch (_eMatchesWhen) { case EIs: return _pSelectionCriterion->is(_iMatchValue); case EIsNot: @@ -151,41 +140,52 @@ bool CSelectionCriterionRule::matches() const } // From IXmlSink -bool CSelectionCriterionRule::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CSelectionCriterionRule::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Retrieve actual context - CXmlDomainImportContext& xmlDomainImportContext = static_cast<CXmlDomainImportContext&>(serializingContext); + CXmlDomainImportContext &xmlDomainImportContext = + static_cast<CXmlDomainImportContext &>(serializingContext); // Get selection criterion - string strSelectionCriterion = xmlElement.getAttributeString("SelectionCriterion"); + string strSelectionCriterion; + xmlElement.getAttribute("SelectionCriterion", strSelectionCriterion); - _pSelectionCriterion = xmlDomainImportContext.getSelectionCriteriaDefinition()->getSelectionCriterion(strSelectionCriterion); + _pSelectionCriterion = + xmlDomainImportContext.getSelectionCriteriaDefinition()->getSelectionCriterion( + strSelectionCriterion); // Check existence if (!_pSelectionCriterion) { - xmlDomainImportContext.setError("Couldn't find selection criterion " + strSelectionCriterion + " in " + getKind() + " " + xmlElement.getPath()); + xmlDomainImportContext.setError("Couldn't find selection criterion " + + strSelectionCriterion + " in " + getKind() + " " + + xmlElement.getPath()); return false; } // Get MatchesWhen - string strMatchesWhen = xmlElement.getAttributeString("MatchesWhen"); + string strMatchesWhen; + xmlElement.getAttribute("MatchesWhen", strMatchesWhen); string strError; if (!setMatchesWhen(strMatchesWhen, strError)) { - xmlDomainImportContext.setError("Wrong MatchesWhen attribute " + strMatchesWhen + " in " + getKind() + " " + xmlElement.getPath() + ": " + strError); + xmlDomainImportContext.setError("Wrong MatchesWhen attribute " + strMatchesWhen + " in " + + getKind() + " " + xmlElement.getPath() + ": " + strError); return false; } // Get Value - string strValue = xmlElement.getAttributeString("Value"); + string strValue; + xmlElement.getAttribute("Value", strValue); if (!_pSelectionCriterion->getCriterionType()->getNumericalValue(strValue, _iMatchValue)) { - xmlDomainImportContext.setError("Wrong Value attribute value " + strValue + " in " + getKind() + " " + xmlElement.getPath()); + xmlDomainImportContext.setError("Wrong Value attribute value " + strValue + " in " + + getKind() + " " + xmlElement.getPath()); return false; } @@ -195,44 +195,42 @@ bool CSelectionCriterionRule::fromXml(const CXmlElement& xmlElement, CXmlSeriali } // From IXmlSource -void CSelectionCriterionRule::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CSelectionCriterionRule::toXml(CXmlElement &xmlElement, CXmlSerializingContext & /*ctx*/) const { - (void)serializingContext; - assert(_pSelectionCriterion); // Set selection criterion - xmlElement.setAttributeString("SelectionCriterion", _pSelectionCriterion->getName()); + xmlElement.setAttribute("SelectionCriterion", _pSelectionCriterion->getName()); // Set MatchesWhen - xmlElement.setAttributeString("MatchesWhen", _astMatchesWhen[_eMatchesWhen].pcMatchesWhen); + xmlElement.setAttribute("MatchesWhen", _astMatchesWhen[_eMatchesWhen].pcMatchesWhen); // Set Value string strValue; - _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, strValue); + _pSelectionCriterion->getCriterionType()->getLiteralValue(_iMatchValue, strValue); - xmlElement.setAttributeString("Value", strValue); + xmlElement.setAttribute("Value", strValue); } // XML MatchesWhen attribute parsing -bool CSelectionCriterionRule::setMatchesWhen(const string& strMatchesWhen, string& strError) +bool CSelectionCriterionRule::setMatchesWhen(const string &strMatchesWhen, string &strError) { - uint32_t uiMatchesWhen; - - for (uiMatchesWhen = 0; uiMatchesWhen < ENbMatchesWhen; uiMatchesWhen++) { + for (size_t matchesWhen = 0; matchesWhen < ENbMatchesWhen; matchesWhen++) { - const SMatchingRuleDescription* pstMatchingRuleDescription = &_astMatchesWhen[uiMatchesWhen]; + const SMatchingRuleDescription *pstMatchingRuleDescription = &_astMatchesWhen[matchesWhen]; if (strMatchesWhen == pstMatchingRuleDescription->pcMatchesWhen) { // Found it! // Get Type - const ISelectionCriterionTypeInterface* pSelectionCriterionType = _pSelectionCriterion->getCriterionType(); + const ISelectionCriterionTypeInterface *pSelectionCriterionType = + _pSelectionCriterion->getCriterionType(); // Check compatibility if relevant - if (!pSelectionCriterionType->isTypeInclusive() && !pstMatchingRuleDescription->bExclusiveTypeCompatible) { + if (!pSelectionCriterionType->isTypeInclusive() && + !pstMatchingRuleDescription->bExclusiveTypeCompatible) { strError = "Value incompatible with exclusive kind of type"; @@ -240,7 +238,7 @@ bool CSelectionCriterionRule::setMatchesWhen(const string& strMatchesWhen, strin } // Store - _eMatchesWhen = (MatchesWhen)uiMatchesWhen; + _eMatchesWhen = (MatchesWhen)matchesWhen; return true; } diff --git a/parameter/SelectionCriterionRule.h b/parameter/SelectionCriterionRule.h index 70bddc2..c51bfa2 100644 --- a/parameter/SelectionCriterionRule.h +++ b/parameter/SelectionCriterionRule.h @@ -38,7 +38,8 @@ class CSelectionCriterion; class CSelectionCriterionRule : public CRule { // Matching rules - enum MatchesWhen { + enum MatchesWhen + { EIs, EIsNot, EIncludes, @@ -49,47 +50,46 @@ class CSelectionCriterionRule : public CRule // Matching rule description struct SMatchingRuleDescription { - const char* pcMatchesWhen; + const char *pcMatchesWhen; bool bExclusiveTypeCompatible; }; public: - CSelectionCriterionRule(); - // Parse - virtual bool parse(CRuleParser& ruleParser, std::string& strError); + virtual bool parse(CRuleParser &ruleParser, std::string &strError); // Dump - virtual void dump(std::string& strResult) const; + std::string dump() const override; // Rule check virtual bool matches() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // Class kind virtual std::string getKind() const; + protected: // Content dumping - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; + std::string logValue(utility::ErrorContext &errorContext) const override; + private: // XML MatchesWhen attribute parsing - bool setMatchesWhen(const std::string& strMatchesWhen, std::string& strError); + bool setMatchesWhen(const std::string &strMatchesWhen, std::string &strError); // Selection criterion - const CSelectionCriterion* _pSelectionCriterion; + const CSelectionCriterion *_pSelectionCriterion{nullptr}; // MatchesWhen - MatchesWhen _eMatchesWhen; + MatchesWhen _eMatchesWhen{EIs}; // Value - int32_t _iMatchValue; + int32_t _iMatchValue{0}; // Used for XML MatchesWhen attribute parsing static const SMatchingRuleDescription _astMatchesWhen[ENbMatchesWhen]; }; - diff --git a/parameter/SelectionCriterionType.cpp b/parameter/SelectionCriterionType.cpp index ce633c6..3354702 100644 --- a/parameter/SelectionCriterionType.cpp +++ b/parameter/SelectionCriterionType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,6 +29,8 @@ */ #include "SelectionCriterionType.h" #include "Tokenizer.h" +#include <sstream> +#include <climits> #define base CElement @@ -49,12 +51,16 @@ std::string CSelectionCriterionType::getKind() const } // From ISelectionCriterionTypeInterface -bool CSelectionCriterionType::addValuePair(int iValue, const std::string& strValue) +bool CSelectionCriterionType::addValuePair(int iValue, const std::string &strValue, + std::string &strError) { // Check 1 bit set only for inclusive types if (_bInclusive && (!iValue || (iValue & (iValue - 1)))) { - log_warning("Rejecting value pair association: 0x%X - %s for Selection Criterion Type %s", iValue, strValue.c_str(), getName().c_str()); + std::ostringstream error; + error << "Rejecting value pair association: 0x" << std::hex << iValue << " - " << strValue + << " for Selection Criterion Type " << getName(); + strError = error.str(); return false; } @@ -62,16 +68,29 @@ bool CSelectionCriterionType::addValuePair(int iValue, const std::string& strVal // Check already inserted if (_numToLitMap.find(strValue) != _numToLitMap.end()) { - log_warning("Rejecting value pair association (literal already present): 0x%X - %s for Selection Criterion Type %s", iValue, strValue.c_str(), getName().c_str()); + std::ostringstream error; + error << "Rejecting value pair association (literal already present): 0x" << std::hex + << iValue << " - " << strValue << " for Selection Criterion Type " << getName(); + strError = error.str(); return false; } + for (NumToLitMapConstIt it = _numToLitMap.begin(); it != _numToLitMap.end(); ++it) { + if (it->second == iValue) { + std::ostringstream error; + error << "Rejecting value pair association (numerical already present):" + << " 0x" << std::hex << iValue << " - " << strValue + << " for Selection Criterion Type " << getName(); + strError = error.str(); + return false; + } + } _numToLitMap[strValue] = iValue; return true; } -bool CSelectionCriterionType::getNumericalValue(const std::string& strValue, int& iValue) const +bool CSelectionCriterionType::getNumericalValue(const std::string &strValue, int &iValue) const { if (_bInclusive) { @@ -96,7 +115,8 @@ bool CSelectionCriterionType::getNumericalValue(const std::string& strValue, int return getAtomicNumericalValue(strValue, iValue); } -bool CSelectionCriterionType::getAtomicNumericalValue(const std::string& strValue, int& iValue) const +bool CSelectionCriterionType::getAtomicNumericalValue(const std::string &strValue, + int &iValue) const { NumToLitMapConstIt it = _numToLitMap.find(strValue); @@ -109,7 +129,7 @@ bool CSelectionCriterionType::getAtomicNumericalValue(const std::string& strValu return false; } -bool CSelectionCriterionType::getLiteralValue(int iValue, std::string& strValue) const +bool CSelectionCriterionType::getLiteralValue(int iValue, std::string &strValue) const { NumToLitMapConstIt it; @@ -163,12 +183,11 @@ std::string CSelectionCriterionType::getFormattedState(int iValue) const if (_bInclusive) { // Need to go through all set bit - uint32_t uiBit; bool bFirst = true; - for (uiBit = 0; uiBit < sizeof(iValue) * 8; uiBit++) { + for (size_t bit = 0; bit < sizeof(iValue) * CHAR_BIT; bit++) { - int iSingleBitValue = iValue & (1 << uiBit); + int iSingleBitValue = iValue & (1 << bit); // Check if current bit is set if (!iSingleBitValue) { @@ -209,10 +228,11 @@ std::string CSelectionCriterionType::getFormattedState(int iValue) const } // From IXmlSource -void CSelectionCriterionType::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CSelectionCriterionType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // Type Kind - xmlElement.setAttributeString("Kind", isTypeInclusive() ? "Inclusive" : "Exclusive"); + xmlElement.setAttribute("Kind", isTypeInclusive() ? "Inclusive" : "Exclusive"); // Value pairs as children NumToLitMapConstIt it; @@ -223,9 +243,9 @@ void CSelectionCriterionType::toXml(CXmlElement& xmlElement, CXmlSerializingCont xmlElement.createChild(childValuePairElement, "ValuePair"); // Literal - childValuePairElement.setAttributeString("Literal", it->first); + childValuePairElement.setAttribute("Literal", it->first); // Numerical - childValuePairElement.setAttributeSignedInteger("Numerical", it->second); + childValuePairElement.setAttribute("Numerical", it->second); } base::toXml(xmlElement, serializingContext); diff --git a/parameter/SelectionCriterionType.h b/parameter/SelectionCriterionType.h index ef4176a..5c13c8f 100644 --- a/parameter/SelectionCriterionType.h +++ b/parameter/SelectionCriterionType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -42,7 +42,7 @@ public: CSelectionCriterionType(bool bIsInclusive); // From ISelectionCriterionTypeInterface - virtual bool addValuePair(int iValue, const std::string& strValue); + virtual bool addValuePair(int iValue, const std::string &strValue, std::string &strError); /** * Retrieve the numerical value from the std::string representation of the criterion type. * @@ -53,8 +53,8 @@ public: * * @return true if integer value retrieved from the std::string one, false otherwise. */ - virtual bool getNumericalValue(const std::string& strValue, int& iValue) const; - virtual bool getLiteralValue(int iValue, std::string& strValue) const; + virtual bool getNumericalValue(const std::string &strValue, int &iValue) const; + virtual bool getLiteralValue(int iValue, std::string &strValue) const; virtual bool isTypeInclusive() const; // Value list @@ -70,10 +70,11 @@ public: * @param[in] serializingContext The serializing context * */ - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // From CElement virtual std::string getKind() const; + private: /** * Retrieve the numerical value from the std::string representation of the criterion type. @@ -84,10 +85,9 @@ private: * * @return true if integer value retrieved from the std::string one, false otherwise. */ - bool getAtomicNumericalValue(const std::string& strValue, int& iValue) const; + bool getAtomicNumericalValue(const std::string &strValue, int &iValue) const; bool _bInclusive; std::map<std::string, int> _numToLitMap; static const std::string _strDelimiter; /**< Inclusive criterion type delimiter. */ }; - diff --git a/parameter/SimulatedBackSynchronizer.cpp b/parameter/SimulatedBackSynchronizer.cpp index 5f60aba..ca48ae3 100644 --- a/parameter/SimulatedBackSynchronizer.cpp +++ b/parameter/SimulatedBackSynchronizer.cpp @@ -32,7 +32,8 @@ #define base CBackSynchronizer -CSimulatedBackSynchronizer::CSimulatedBackSynchronizer(const CConfigurableElement* pConfigurableElement, CParameterBlackboard* pParameterBlackboard) +CSimulatedBackSynchronizer::CSimulatedBackSynchronizer( + const CConfigurableElement *pConfigurableElement, CParameterBlackboard *pParameterBlackboard) : base(pConfigurableElement), _parameterAccessContext(_strError) { _parameterAccessContext.setParameterBlackboard(pParameterBlackboard); @@ -42,11 +43,11 @@ CSimulatedBackSynchronizer::CSimulatedBackSynchronizer(const CConfigurableElemen void CSimulatedBackSynchronizer::sync() { // Set default values to simulate back synchronization - std::list<const CConfigurableElement*>::const_iterator it; + std::list<const CConfigurableElement *>::const_iterator it; for (it = _needingBackSyncList.begin(); it != _needingBackSyncList.end(); ++it) { - const CConfigurableElement* pConfigurableElement = *it; + const CConfigurableElement *pConfigurableElement = *it; pConfigurableElement->setDefaultValues(_parameterAccessContext); } diff --git a/parameter/SimulatedBackSynchronizer.h b/parameter/SimulatedBackSynchronizer.h index 6acf090..f561b89 100644 --- a/parameter/SimulatedBackSynchronizer.h +++ b/parameter/SimulatedBackSynchronizer.h @@ -39,14 +39,15 @@ class CParameterBlackboard; class CSimulatedBackSynchronizer : public CBackSynchronizer { public: - CSimulatedBackSynchronizer(const CConfigurableElement* pConfigurableElement, CParameterBlackboard* pParameterBlackboard); + CSimulatedBackSynchronizer(const CConfigurableElement *pConfigurableElement, + CParameterBlackboard *pParameterBlackboard); // Back synchronization virtual void sync(); + private: // Fake error for parameter context creation std::string _strError; // Parameter context CParameterAccessContext _parameterAccessContext; }; - diff --git a/parameter/StringParameter.cpp b/parameter/StringParameter.cpp index 8ba5b16..0651bf6 100644 --- a/parameter/StringParameter.cpp +++ b/parameter/StringParameter.cpp @@ -37,7 +37,8 @@ using std::string; -CStringParameter::CStringParameter(const string& strName, const CTypeElement* pTypeElement) : base(strName, pTypeElement) +CStringParameter::CStringParameter(const string &strName, const CTypeElement *pTypeElement) + : base(strName, pTypeElement) { } @@ -46,44 +47,48 @@ CInstanceConfigurableElement::Type CStringParameter::getType() const return EStringParameter; } -uint32_t CStringParameter::getFootPrint() const +size_t CStringParameter::getFootPrint() const { return getSize(); } -uint32_t CStringParameter::getSize() const +size_t CStringParameter::getSize() const { - return static_cast<const CStringParameterType*>(getTypeElement())->getMaxLength() + 1; + return static_cast<const CStringParameterType *>(getTypeElement())->getMaxLength() + 1; } // Used for simulation and virtual subsystems -void CStringParameter::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +void CStringParameter::setDefaultValues(CParameterAccessContext ¶meterAccessContext) const { // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); pBlackboard->writeString("", getOffset()); } // Actual parameter access (tuning) -bool CStringParameter::doSetValue(const string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +bool CStringParameter::doSetValue(const string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { if (strValue.length() >= getSize()) { - - parameterAccessContext.setError("Maximum length exceeded"); + using std::to_string; + parameterAccessContext.setError("Can not set a string of length " + + to_string(strValue.length()) + ": maximum length is " + + std::to_string(getSize() - 1)); return false; } // Write blackboard - CParameterBlackboard* pBlackboard = parameterAccessContext.getParameterBlackboard(); + CParameterBlackboard *pBlackboard = parameterAccessContext.getParameterBlackboard(); - pBlackboard->writeString(strValue, uiOffset); + pBlackboard->writeString(strValue, offset); return true; } -void CStringParameter::doGetValue(string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const +void CStringParameter::doGetValue(string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const { - parameterAccessContext.getParameterBlackboard()->readString(strValue, uiOffset); + parameterAccessContext.getParameterBlackboard()->readString(strValue, offset); } diff --git a/parameter/StringParameter.h b/parameter/StringParameter.h index 6a60e9f..6adede9 100644 --- a/parameter/StringParameter.h +++ b/parameter/StringParameter.h @@ -36,22 +36,24 @@ class CStringParameter : public CBaseParameter { public: - CStringParameter(const std::string& strName, const CTypeElement* pTypeElement); + CStringParameter(const std::string &strName, const CTypeElement *pTypeElement); // Instantiation, allocation - virtual uint32_t getFootPrint() const; + virtual size_t getFootPrint() const; // Type virtual Type getType() const; + protected: // Used for simulation and virtual subsystems - virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const; + virtual void setDefaultValues(CParameterAccessContext ¶meterAccessContext) const; // Actual value access (tuning) - virtual bool doSetValue(const std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; - virtual void doGetValue(std::string& strValue, uint32_t uiOffset, CParameterAccessContext& parameterAccessContext) const; + virtual bool doSetValue(const std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const; + virtual void doGetValue(std::string &strValue, size_t offset, + CParameterAccessContext ¶meterAccessContext) const; // Size - uint32_t getSize() const; + size_t getSize() const; }; - diff --git a/parameter/StringParameterType.cpp b/parameter/StringParameterType.cpp index 321dc97..df9230d 100644 --- a/parameter/StringParameterType.cpp +++ b/parameter/StringParameterType.cpp @@ -35,7 +35,7 @@ using std::string; -CStringParameterType::CStringParameterType(const string& strName) : base(strName), _uiMaxLength(0) +CStringParameterType::CStringParameterType(const string &strName) : base(strName) { } @@ -46,42 +46,44 @@ string CStringParameterType::getKind() const } // Element properties -void CStringParameterType::showProperties(string& strResult) const +void CStringParameterType::showProperties(string &strResult) const { base::showProperties(strResult); // Max length strResult += "Max length: "; - strResult += CUtility::toString(_uiMaxLength); + strResult += std::to_string(_maxLength); strResult += "\n"; } // From IXmlSink -bool CStringParameterType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CStringParameterType::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // MaxLength - _uiMaxLength = xmlElement.getAttributeInteger("MaxLength"); + xmlElement.getAttribute("MaxLength", _maxLength); // Base return base::fromXml(xmlElement, serializingContext); } -CInstanceConfigurableElement* CStringParameterType::doInstantiate() const +CInstanceConfigurableElement *CStringParameterType::doInstantiate() const { return new CStringParameter(getName(), this); } // Max length -uint32_t CStringParameterType::getMaxLength() const +size_t CStringParameterType::getMaxLength() const { - return _uiMaxLength; + return _maxLength; } // From IXmlSource -void CStringParameterType::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const +void CStringParameterType::toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const { // MaxLength - xmlElement.setAttributeInteger("MaxLength", _uiMaxLength); + xmlElement.setAttribute("MaxLength", _maxLength); base::toXml(xmlElement, serializingContext); } diff --git a/parameter/StringParameterType.h b/parameter/StringParameterType.h index e1b2513..9d8786f 100644 --- a/parameter/StringParameterType.h +++ b/parameter/StringParameterType.h @@ -38,26 +38,27 @@ class CStringParameterType : public CTypeElement { public: - CStringParameterType(const std::string& strName); + CStringParameterType(const std::string &strName); // Max length - uint32_t getMaxLength() const; + size_t getMaxLength() const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // CElement virtual std::string getKind() const; + private: // Instantiation - virtual CInstanceConfigurableElement* doInstantiate() const; + virtual CInstanceConfigurableElement *doInstantiate() const; // Max length in bytes - uint32_t _uiMaxLength; + size_t _maxLength{0}; }; diff --git a/parameter/Subsystem.cpp b/parameter/Subsystem.cpp index 6b0264b..43e633d 100644 --- a/parameter/Subsystem.cpp +++ b/parameter/Subsystem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -35,17 +35,17 @@ #include "ConfigurationAccessContext.h" #include "SubsystemObjectCreator.h" #include "MappingData.h" -#include "Utility.h" #include <assert.h> #include <sstream> -#define base CConfigurableElementWithMapping +#define base CConfigurableElement using std::string; using std::list; -using std::ostringstream; -CSubsystem::CSubsystem(const string& strName) : base(strName), _pComponentLibrary(new CComponentLibrary), _pInstanceDefinition(new CInstanceDefinition), _bBigEndian(false), _pMappingData(NULL) +CSubsystem::CSubsystem(const string &strName, core::log::Logger &logger) + : base(strName), _pComponentLibrary(new CComponentLibrary), + _pInstanceDefinition(new CInstanceDefinition), _logger(logger) { // Note: A subsystem contains instance components // InstanceDefintion and ComponentLibrary objects are then not chosen to be children @@ -54,20 +54,17 @@ CSubsystem::CSubsystem(const string& strName) : base(strName), _pComponentLibrar CSubsystem::~CSubsystem() { - // Remove subsystem objects - SubsystemObjectListIterator subsystemObjectIt; + // FIXME use unique_ptr, would make this method empty - for (subsystemObjectIt = _subsystemObjectList.begin(); subsystemObjectIt != _subsystemObjectList.end(); ++subsystemObjectIt) { + for (auto *subsystemObject : _subsystemObjectList) { - delete *subsystemObjectIt; + delete subsystemObject; } // Remove susbsystem creators - uint32_t uiIndex; + for (auto *subsystemObjectCreator : _subsystemObjectCreatorArray) { - for (uiIndex = 0; uiIndex < _subsystemObjectCreatorArray.size(); uiIndex++) { - - delete _subsystemObjectCreatorArray[uiIndex]; + delete subsystemObjectCreator; } // Order matters! @@ -82,12 +79,6 @@ string CSubsystem::getKind() const return "Subsystem"; } -// Susbsystem Endianness -bool CSubsystem::isBigEndian() const -{ - return _bBigEndian; -} - // Susbsystem sanity bool CSubsystem::isAlive() const { @@ -95,22 +86,23 @@ bool CSubsystem::isAlive() const } // Resynchronization after subsystem restart needed -bool CSubsystem::needResync(bool bClear) +bool CSubsystem::needResync(bool /*bClear*/) { - (void)bClear; - return false; } -// From IXmlSink -bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CSubsystem::structureFromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Subsystem class does not rely on generic fromXml algorithm of Element class. // So, setting here the description if found as XML attribute. - setDescription(getXmlDescriptionAttribute(xmlElement)); + string description; + xmlElement.getAttribute(gDescriptionPropertyName, description); + setDescription(description); // Context - CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext); + CXmlParameterSerializingContext ¶meterBuildContext = + static_cast<CXmlParameterSerializingContext &>(serializingContext); // Install temporary component library for further component creation parameterBuildContext.setComponentLibrary(_pComponentLibrary); @@ -118,11 +110,16 @@ bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& CXmlElement childElement; // Manage mapping attribute - if (xmlElement.hasAttribute("Mapping")) { + string rawMapping; + xmlElement.getAttribute("Mapping", rawMapping); + if (!rawMapping.empty()) { + std::string error; _pMappingData = new CMappingData; - if (!_pMappingData->fromXml(xmlElement, serializingContext)) { + if (!_pMappingData->init(rawMapping, error)) { + serializingContext.setError("Invalid Mapping data from XML element '" + + xmlElement.getPath() + "': " + error); return false; } } @@ -154,23 +151,10 @@ bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& return false; } - // Endianness - _bBigEndian = xmlElement.getAttributeBoolean("Endianness", "Big"); - return true; } -// XML configuration settings parsing -bool CSubsystem::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const -{ - // Fix Endianness - configurationAccessContext.setBigEndianSubsystem(_bBigEndian); - - return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, configurationAccessContext); -} - - -bool CSubsystem::mapSubsystemElements(string& strError) +bool CSubsystem::mapSubsystemElements(string &strError) { // Default mapping context CMappingContext context(_contextMappingKeyArray.size()); @@ -180,12 +164,12 @@ bool CSubsystem::mapSubsystemElements(string& strError) _contextStack.push(context); // Map all instantiated subelements in subsystem - size_t uiNbChildren = getNbChildren(); - size_t uiChild; + size_t nbChildren = getNbChildren(); - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { + for (size_t child = 0; child < nbChildren; child++) { - CInstanceConfigurableElement* pInstanceConfigurableChildElement = static_cast<CInstanceConfigurableElement*>(getChild(uiChild)); + CInstanceConfigurableElement *pInstanceConfigurableChildElement = + static_cast<CInstanceConfigurableElement *>(getChild(child)); if (!pInstanceConfigurableChildElement->map(*this, strError)) { @@ -195,70 +179,61 @@ bool CSubsystem::mapSubsystemElements(string& strError) return true; } -// Parameter access -bool CSubsystem::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const -{ - // Deal with Endianness - parameterAccessContext.setBigEndianSubsystem(_bBigEndian); - - return base::accessValue(pathNavigator, strValue, bSet, parameterAccessContext); -} - // Formats the mapping of the ConfigurableElements string CSubsystem::formatMappingDataList( - const list<const CConfigurableElement*>& configurableElementPath) const + const list<const CConfigurableElement *> &configurableElementPath) const { // The list is parsed in reverse order because it has been filled from the leaf to the trunk // of the tree. When formatting the mapping, we want to start from the subsystem level - ostringstream ossStream; - list<const CConfigurableElement*>::const_reverse_iterator it; + std::list<string> mappings; + list<const CConfigurableElement *>::const_reverse_iterator it; for (it = configurableElementPath.rbegin(); it != configurableElementPath.rend(); ++it) { - const CInstanceConfigurableElement* pInstanceConfigurableElement = - static_cast<const CInstanceConfigurableElement*>(*it); - - ossStream << pInstanceConfigurableElement->getFormattedMapping() << ", "; + auto maybeMapping = (*it)->getFormattedMapping(); + if (not maybeMapping.empty()) { + mappings.push_back(maybeMapping); + } } - return ossStream.str(); + + return utility::asString(mappings, ", "); } // Find the CSubystemObject containing a specific CInstanceConfigurableElement -const CSubsystemObject* CSubsystem::findSubsystemObjectFromConfigurableElement( - const CInstanceConfigurableElement* pInstanceConfigurableElement) const { - - const CSubsystemObject* pSubsystemObject = NULL; +const CSubsystemObject *CSubsystem::findSubsystemObjectFromConfigurableElement( + const CInstanceConfigurableElement *pInstanceConfigurableElement) const +{ - list<CSubsystemObject*>::const_iterator it; + list<CSubsystemObject *>::const_iterator it; for (it = _subsystemObjectList.begin(); it != _subsystemObjectList.end(); ++it) { // Check if one of the SubsystemObjects is associated with a ConfigurableElement // corresponding to the expected one - pSubsystemObject = *it; + const CSubsystemObject *pSubsystemObject = *it; + if (pSubsystemObject->getConfigurableElement() == pInstanceConfigurableElement) { - break; + return pSubsystemObject; } } - return pSubsystemObject; + return nullptr; } void CSubsystem::findSubsystemLevelMappingKeyValue( - const CInstanceConfigurableElement* pInstanceConfigurableElement, - string& strMappingKey, - string& strMappingValue) const + const CInstanceConfigurableElement *pInstanceConfigurableElement, string &strMappingKey, + string &strMappingValue) const { // Find creator to get key name - std::vector<CSubsystemObjectCreator*>::const_iterator it; - for (it = _subsystemObjectCreatorArray.begin(); - it != _subsystemObjectCreatorArray.end(); ++it) { + std::vector<CSubsystemObjectCreator *>::const_iterator it; + for (it = _subsystemObjectCreatorArray.begin(); it != _subsystemObjectCreatorArray.end(); + ++it) { - const CSubsystemObjectCreator* pSubsystemObjectCreator = *it; + const CSubsystemObjectCreator *pSubsystemObjectCreator = *it; strMappingKey = pSubsystemObjectCreator->getMappingKey(); // Check if the ObjectCreator MappingKey corresponds to the element mapping data - const string* pStrValue; + const string *pStrValue; if (pInstanceConfigurableElement->getMappingData(strMappingKey, pStrValue)) { strMappingValue = *pStrValue; @@ -270,11 +245,11 @@ void CSubsystem::findSubsystemLevelMappingKeyValue( // Formats the mapping data as a comma separated list of key value pairs string CSubsystem::getFormattedSubsystemMappingData( - const CInstanceConfigurableElement* pInstanceConfigurableElement) const + const CInstanceConfigurableElement *pInstanceConfigurableElement) const { // Find the SubsystemObject related to pInstanceConfigurableElement - const CSubsystemObject* pSubsystemObject = findSubsystemObjectFromConfigurableElement( - pInstanceConfigurableElement); + const CSubsystemObject *pSubsystemObject = + findSubsystemObjectFromConfigurableElement(pInstanceConfigurableElement); // Exit if node does not correspond to a SubsystemObject if (pSubsystemObject == NULL) { @@ -291,7 +266,7 @@ string CSubsystem::getFormattedSubsystemMappingData( return strMappingKey + ":" + pSubsystemObject->getFormattedMappingValue(); } -string CSubsystem::getMapping(list<const CConfigurableElement*>& configurableElementPath) const +string CSubsystem::getMapping(list<const CConfigurableElement *> &configurableElementPath) const { if (configurableElementPath.empty()) { @@ -299,71 +274,55 @@ string CSubsystem::getMapping(list<const CConfigurableElement*>& configurableEle } // Get the first element, which is the element containing the amended mapping - const CInstanceConfigurableElement* pInstanceConfigurableElement = - static_cast<const CInstanceConfigurableElement*>(configurableElementPath.front()); - configurableElementPath.pop_front(); - // Now the list only contains elements whose mapping are related to the context + const CInstanceConfigurableElement *pInstanceConfigurableElement = + static_cast<const CInstanceConfigurableElement *>(configurableElementPath.front()); // Format context mapping data string strValue = formatMappingDataList(configurableElementPath); // Print the mapping of the first node, which corresponds to a SubsystemObject - strValue += getFormattedSubsystemMappingData(pInstanceConfigurableElement); + auto subsystemObjectAmendedMapping = + getFormattedSubsystemMappingData(pInstanceConfigurableElement); + if (not subsystemObjectAmendedMapping.empty()) { + strValue += ", " + subsystemObjectAmendedMapping; + } return strValue; } -void CSubsystem::logValue(string& strValue, CErrorContext& errorContext) const -{ - CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext); - - // Deal with Endianness - parameterAccessContext.setBigEndianSubsystem(_bBigEndian); - - return base::logValue(strValue, errorContext); -} - // Used for simulation and virtual subsystems -void CSubsystem::setDefaultValues(CParameterAccessContext& parameterAccessContext) const +void CSubsystem::setDefaultValues(CParameterAccessContext ¶meterAccessContext) const { - // Deal with Endianness - parameterAccessContext.setBigEndianSubsystem(_bBigEndian); - base::setDefaultValues(parameterAccessContext); } // Belonging subsystem -const CSubsystem* CSubsystem::getBelongingSubsystem() const +const CSubsystem *CSubsystem::getBelongingSubsystem() const { return this; } // Subsystem context mapping keys publication -void CSubsystem::addContextMappingKey(const string& strMappingKey) +void CSubsystem::addContextMappingKey(const string &strMappingKey) { _contextMappingKeyArray.push_back(strMappingKey); } // Subsystem object creator publication (strong reference) -void CSubsystem::addSubsystemObjectFactory(CSubsystemObjectCreator* pSubsystemObjectCreator) +void CSubsystem::addSubsystemObjectFactory(CSubsystemObjectCreator *pSubsystemObjectCreator) { _subsystemObjectCreatorArray.push_back(pSubsystemObjectCreator); } // Generic error handling from derived subsystem classes -string CSubsystem::getMappingError( - const string& strKey, - const string& strMessage, - const CConfigurableElementWithMapping* pConfigurableElementWithMapping) const +string CSubsystem::getMappingError(const string &strKey, const string &strMessage, + const CConfigurableElement *pConfigurableElement) const { - return getName() + " " + getKind() + " " + - "mapping:\n" + strKey + " " + - "error: \"" + strMessage + "\" " + - "for element " + pConfigurableElementWithMapping->getPath(); + return getName() + " " + getKind() + " " + "mapping:\n" + strKey + " " + "error: \"" + + strMessage + "\" " + "for element " + pConfigurableElement->getPath(); } - -bool CSubsystem::getMappingData(const std::string& strKey, const std::string*& pStrValue) const +bool CSubsystem::getMappingData(const std::string &strKey, const std::string *&pStrValue) const { if (_pMappingData) { @@ -372,25 +331,30 @@ bool CSubsystem::getMappingData(const std::string& strKey, const std::string*& p return false; } +// Returns the formatted mapping +std::string CSubsystem::getFormattedMapping() const +{ + if (!_pMappingData) { + return ""; + } + return _pMappingData->asString(); +} + // Mapping generic context handling -bool CSubsystem::handleMappingContext( - const CConfigurableElementWithMapping* pConfigurableElementWithMapping, - CMappingContext& context, - string& strError) const +bool CSubsystem::handleMappingContext(const CConfigurableElement *pConfigurableElement, + CMappingContext &context, string &strError) const { // Feed context with found mapping data - uint32_t uiItem; - - for (uiItem = 0; uiItem < _contextMappingKeyArray.size(); uiItem++) { + for (size_t item = 0; item < _contextMappingKeyArray.size(); item++) { - const string& strKey = _contextMappingKeyArray[uiItem]; - const string* pStrValue; + const string &strKey = _contextMappingKeyArray[item]; + const string *pStrValue; - if (pConfigurableElementWithMapping->getMappingData(strKey, pStrValue)) { + if (pConfigurableElement->getMappingData(strKey, pStrValue)) { // Assign item to context - if (!context.setItem(uiItem, &strKey, pStrValue)) { + if (!context.setItem(item, &strKey, pStrValue)) { - strError = getMappingError(strKey, "Already set", pConfigurableElementWithMapping); + strError = getMappingError(strKey, "Already set", pConfigurableElement); return false; } @@ -401,30 +365,26 @@ bool CSubsystem::handleMappingContext( // Subsystem object creation handling bool CSubsystem::handleSubsystemObjectCreation( - CInstanceConfigurableElement* pInstanceConfigurableElement, - CMappingContext& context, bool& bHasCreatedSubsystemObject, string& strError) + CInstanceConfigurableElement *pInstanceConfigurableElement, CMappingContext &context, + bool &bHasCreatedSubsystemObject, string &strError) { - uint32_t uiItem; bHasCreatedSubsystemObject = false; - for (uiItem = 0; uiItem < _subsystemObjectCreatorArray.size(); uiItem++) { - - const CSubsystemObjectCreator* pSubsystemObjectCreator = - _subsystemObjectCreatorArray[uiItem]; + for (const auto *pSubsystemObjectCreator : _subsystemObjectCreatorArray) { // Mapping key string strKey = pSubsystemObjectCreator->getMappingKey(); // Object id - const string* pStrValue; + const string *pStrValue; if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) { // First check context consistency // (required ancestors must have been set prior to object creation) - uint32_t uiAncestorKey; uint32_t uiAncestorMask = pSubsystemObjectCreator->getAncestorMask(); - for (uiAncestorKey = 0; uiAncestorKey < _contextMappingKeyArray.size(); uiAncestorKey++) { + for (size_t uiAncestorKey = 0; uiAncestorKey < _contextMappingKeyArray.size(); + uiAncestorKey++) { if (!((1 << uiAncestorKey) & uiAncestorMask)) { // Ancestor not required @@ -433,8 +393,9 @@ bool CSubsystem::handleSubsystemObjectCreation( // Check ancestor was provided if (!context.iSet(uiAncestorKey)) { - strError = getMappingError(strKey, _contextMappingKeyArray[uiAncestorKey] + - " not set", pInstanceConfigurableElement); + strError = + getMappingError(strKey, _contextMappingKeyArray[uiAncestorKey] + " not set", + pInstanceConfigurableElement); return false; } @@ -444,9 +405,9 @@ bool CSubsystem::handleSubsystemObjectCreation( if (pInstanceConfigurableElement->getFootPrint() > pSubsystemObjectCreator->getMaxConfigurableElementSize()) { - string strSizeError = "Size should not exceed " + - CUtility::toString( - pSubsystemObjectCreator->getMaxConfigurableElementSize()); + string strSizeError = + "Size should not exceed " + + std::to_string(pSubsystemObjectCreator->getMaxConfigurableElementSize()); strError = getMappingError(strKey, strSizeError, pInstanceConfigurableElement); @@ -455,7 +416,7 @@ bool CSubsystem::handleSubsystemObjectCreation( // Do create object and keep its track _subsystemObjectList.push_back(pSubsystemObjectCreator->objectCreate( - *pStrValue, pInstanceConfigurableElement, context)); + *pStrValue, pInstanceConfigurableElement, context, _logger)); // Indicate subsytem creation to caller bHasCreatedSubsystemObject = true; @@ -471,15 +432,14 @@ bool CSubsystem::handleSubsystemObjectCreation( // From IMapper // Handle a configurable element mapping -bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, - bool& bKeepDiving, string& strError) +bool CSubsystem::mapBegin(CInstanceConfigurableElement *pInstanceConfigurableElement, + bool &bKeepDiving, string &strError) { // Get current context CMappingContext context = _contextStack.top(); // Add mapping in context - if (!handleMappingContext(pInstanceConfigurableElement, context, - strError)) { + if (!handleMappingContext(pInstanceConfigurableElement, context, strError)) { return false; } @@ -493,40 +453,39 @@ bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableEle // Deal with ambiguous usage of parameter blocks bool bShouldCreateSubsystemObject = true; - switch(pInstanceConfigurableElement->getType()) { + switch (pInstanceConfigurableElement->getType()) { - case CInstanceConfigurableElement::EComponent: - case CInstanceConfigurableElement::EParameterBlock: - // Subsystem object creation is optional in parameter blocks - bShouldCreateSubsystemObject = false; - // No break - case CInstanceConfigurableElement::EBitParameterBlock: - case CInstanceConfigurableElement::EParameter: - case CInstanceConfigurableElement::EStringParameter: + case CInstanceConfigurableElement::EComponent: + case CInstanceConfigurableElement::EParameterBlock: + // Subsystem object creation is optional in parameter blocks + bShouldCreateSubsystemObject = false; + // No break + case CInstanceConfigurableElement::EBitParameterBlock: + case CInstanceConfigurableElement::EParameter: + case CInstanceConfigurableElement::EStringParameter: - bool bHasCreatedSubsystemObject; + bool bHasCreatedSubsystemObject; - if (!handleSubsystemObjectCreation(pInstanceConfigurableElement, context, - bHasCreatedSubsystemObject, strError)) { + if (!handleSubsystemObjectCreation(pInstanceConfigurableElement, context, + bHasCreatedSubsystemObject, strError)) { - return false; - } - // Check for creation error - if (bShouldCreateSubsystemObject && !bHasCreatedSubsystemObject) { + return false; + } + // Check for creation error + if (bShouldCreateSubsystemObject && !bHasCreatedSubsystemObject) { - strError = getMappingError("Not found", - "Subsystem object mapping key is missing", - pInstanceConfigurableElement); - return false; - } - // Not created and no error, keep diving - bKeepDiving = !bHasCreatedSubsystemObject; + strError = getMappingError("Not found", "Subsystem object mapping key is missing", + pInstanceConfigurableElement); + return false; + } + // Not created and no error, keep diving + bKeepDiving = !bHasCreatedSubsystemObject; - return true; + return true; - default: - assert(0); - return false; + default: + assert(0); + return false; } } diff --git a/parameter/Subsystem.h b/parameter/Subsystem.h index e537352..af7e1fb 100644 --- a/parameter/Subsystem.h +++ b/parameter/Subsystem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,10 +29,13 @@ */ #pragma once +#include "parameter_export.h" + #include "ConfigurableElement.h" -#include "ConfigurableElementWithMapping.h" #include "Mapper.h" #include "MappingContext.h" +#include <log/Logger.h> + #include <list> #include <stack> #include <string> @@ -45,19 +48,23 @@ class CSubsystemObjectCreator; class CInstanceConfigurableElement; class CMappingData; -class CSubsystem : public CConfigurableElementWithMapping, private IMapper +class PARAMETER_EXPORT CSubsystem : public CConfigurableElement, private IMapper { // Subsystem objects iterator - typedef std::list<CSubsystemObject*>::const_iterator SubsystemObjectListIterator; + typedef std::list<CSubsystemObject *>::const_iterator SubsystemObjectListIterator; + public: - CSubsystem(const std::string& strName); + /** + * Class Constructor + * + * @param[in] strName subsystem name + * @param[in] logger the main logger of the application + */ + CSubsystem(const std::string &strName, core::log::Logger &logger); virtual ~CSubsystem(); - // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); - - // Susbsystem Endianness - bool isBigEndian() const; + virtual bool structureFromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext); // Susbsystem sanity virtual bool isAlive() const; @@ -65,18 +72,17 @@ public: // Resynchronization after subsystem restart needed virtual bool needResync(bool bClear); - // XML configuration settings parsing - virtual bool serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const; - // from CElement virtual std::string getKind() const; - virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const; + virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const; + std::string getFormattedMapping() const override; /** * Fetch mapping data of an element. * - * The mapping is represented as a std::string of all the mapping data (key:value) defined in the + * The mapping is represented as a std::string of all the mapping data (key:value) defined in + * the * context of the element. * This method gathers the mapping data found in each Element of the configurableElementPath * list to format the resulting std::string. @@ -87,36 +93,35 @@ public: * * @return Formatted std::string of the mapping data */ - virtual std::string getMapping(std::list<const CConfigurableElement*>& configurableElementPath) const; + virtual std::string getMapping( + std::list<const CConfigurableElement *> &configurableElementPath) const; protected: - // Parameter access - virtual bool accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const; - virtual void logValue(std::string& strValue, CErrorContext& errorContext) const; // Used for simulation and virtual subsystems - virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const; + virtual void setDefaultValues(CParameterAccessContext ¶meterAccessContext) const; /// Functionality intendedn for derived Subsystems // Subsystem context mapping keys publication - void addContextMappingKey(const std::string& strMappingKey); + void addContextMappingKey(const std::string &strMappingKey); // Subsystem object creator publication (strong reference) - void addSubsystemObjectFactory(CSubsystemObjectCreator* pSubsystemObjectCreator); + void addSubsystemObjectFactory(CSubsystemObjectCreator *pSubsystemObjectCreator); + private: - CSubsystem(const CSubsystem&); - CSubsystem& operator=(const CSubsystem&); + CSubsystem(const CSubsystem &); + CSubsystem &operator=(const CSubsystem &); // Belonging subsystem - virtual const CSubsystem* getBelongingSubsystem() const; + virtual const CSubsystem *getBelongingSubsystem() const; // Mapping execution - bool mapSubsystemElements(std::string& strError); + bool mapSubsystemElements(std::string &strError); /** * Handle a configurable element mapping. * * Add context mappings to the context and instantiate a subsystem object if needed. * - * @param[in:out] pInstanceConfigurableElement The configurable element + * @param[in,out] pInstanceConfigurableElement The configurable element * @param[out] bKeepDiving Keep diving for mapping keys Is set to true if a subsystem object (tree leave) has been instantiated. Undetermined on error @@ -125,7 +130,8 @@ private: * * @return true on success, false on failure */ - virtual bool mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, std::string& strError); + virtual bool mapBegin(CInstanceConfigurableElement *pInstanceConfigurableElement, + bool &bKeepDiving, std::string &strError); virtual void mapEnd(); // Mapping access @@ -136,14 +142,12 @@ private: * * @param[in] strKey The key on which the error refers * @param[in] strMessage The error message - * @param[in] pConfigurableElementWithMapping The element on which the error refers + * @param[in] pConfigurableElement The element on which the error refers * * returns The formated error std::string */ - std::string getMappingError( - const std::string& strKey, - const std::string& strMessage, - const CConfigurableElementWithMapping* pConfigurableElementWithMapping) const; + std::string getMappingError(const std::string &strKey, const std::string &strMessage, + const CConfigurableElement *pConfigurableElement) const; /** * Format the mapping data of the ConfigurableElements that have been gathered through recursive @@ -156,7 +160,7 @@ private: * @return String containing the formatted mapping */ std::string formatMappingDataList( - const std::list<const CConfigurableElement*>& configurableElementPath) const; + const std::list<const CConfigurableElement *> &configurableElementPath) const; /** * Find the SubystemObject which contains a specific CInstanceConfigurableElement. @@ -167,8 +171,8 @@ private: * * @return A pointer to the SubsystemObject related to pInstanceConfigurableElement */ - const CSubsystemObject* findSubsystemObjectFromConfigurableElement( - const CInstanceConfigurableElement* pInstanceConfigurableElement) const; + const CSubsystemObject *findSubsystemObjectFromConfigurableElement( + const CInstanceConfigurableElement *pInstanceConfigurableElement) const; /** * Find the mapping data defined for the CInstanceConfigurableElement given in parameter, that @@ -182,9 +186,8 @@ private: * @param[out] strMappingValue Mapping value contained in pInstanceConfigurableElement */ void findSubsystemLevelMappingKeyValue( - const CInstanceConfigurableElement* pInstanceConfigurableElement, - std::string& strMappingKey, - std::string& strMappingValue) const; + const CInstanceConfigurableElement *pInstanceConfigurableElement, + std::string &strMappingKey, std::string &strMappingValue) const; /** * Formats the mapping of a SubsystemObject @@ -194,28 +197,26 @@ private: * @return String containing the formatted mapping */ std::string getFormattedSubsystemMappingData( - const CInstanceConfigurableElement* pInstanceConfigurableElement) const; + const CInstanceConfigurableElement *pInstanceConfigurableElement) const; /** * Generic context handling * * Feed context with mapping data of the current element * - * @param[in] pConfigurableElementWithMapping The element containing mapping data + * @param[in] pConfigurableElement The element containing mapping data * @param[out] context The context mapping to update with the current element mapping values * @param[out] strError The formated error std::string * * @return true on success */ - bool handleMappingContext( - const CConfigurableElementWithMapping* pConfigurableElementWithMapping, - CMappingContext& context, - std::string& strError) const; + bool handleMappingContext(const CConfigurableElement *pConfigurableElement, + CMappingContext &context, std::string &strError) const; /** * Looks if a subsystem object needs to be instantiated for the given configurable * element, then instantiate it if needed. * - * @param[in:out] pInstanceConfigurableElement The configurable element to check + * @param[in,out] pInstanceConfigurableElement The configurable element to check * for instanciation * @param[in] context The mapping values container * @param[out] bHasCreatedSubsystemObject If a subsystem object has been instantiated. @@ -225,29 +226,29 @@ private: * * @return true on success, false on failure */ - bool handleSubsystemObjectCreation(CInstanceConfigurableElement* pInstanceConfigurableElement, - CMappingContext& context, bool& bHasCreatedSubsystemObject, - std::string& strError); + bool handleSubsystemObjectCreation(CInstanceConfigurableElement *pInstanceConfigurableElement, + CMappingContext &context, bool &bHasCreatedSubsystemObject, + std::string &strError); // Subsystem context mapping keys std::vector<std::string> _contextMappingKeyArray; // Subsystem object creator map - std::vector<CSubsystemObjectCreator*> _subsystemObjectCreatorArray; + std::vector<CSubsystemObjectCreator *> _subsystemObjectCreatorArray; // Subsystem sync objects (house keeping) - std::list<CSubsystemObject*> _subsystemObjectList; + std::list<CSubsystemObject *> _subsystemObjectList; // Mapping Context stack std::stack<CMappingContext> _contextStack; // Subelements - CComponentLibrary* _pComponentLibrary; - CInstanceDefinition* _pInstanceDefinition; - - // Endianness - bool _bBigEndian; + CComponentLibrary *_pComponentLibrary; + CInstanceDefinition *_pInstanceDefinition; //! Contains the mapping info at Subsystem level - CMappingData* _pMappingData; + CMappingData *_pMappingData{nullptr}; + + /** Logger which has to be provided to subsystem objects */ + core::log::Logger &_logger; }; diff --git a/parameter/SubsystemElementBuilder.cpp b/parameter/SubsystemElementBuilder.cpp index c166113..96a0be2 100644 --- a/parameter/SubsystemElementBuilder.cpp +++ b/parameter/SubsystemElementBuilder.cpp @@ -30,12 +30,12 @@ #include "SubsystemElementBuilder.h" #include "SubsystemLibrary.h" -CSubsystemElementBuilder::CSubsystemElementBuilder(const CSubsystemLibrary* pSubsystemLibrary) : - CElementBuilder(), _pSubsystemLibrary(pSubsystemLibrary) +CSubsystemElementBuilder::CSubsystemElementBuilder(const CSubsystemLibrary *pSubsystemLibrary) + : CElementBuilder(), _pSubsystemLibrary(pSubsystemLibrary) { } -CElement* CSubsystemElementBuilder::createElement(const CXmlElement& xmlElement) const +CElement *CSubsystemElementBuilder::createElement(const CXmlElement &xmlElement) const { return _pSubsystemLibrary->createElement(xmlElement); } diff --git a/parameter/SubsystemElementBuilder.h b/parameter/SubsystemElementBuilder.h index d0465bf..4dfe78f 100644 --- a/parameter/SubsystemElementBuilder.h +++ b/parameter/SubsystemElementBuilder.h @@ -36,11 +36,10 @@ class CSubsystemLibrary; class CSubsystemElementBuilder : public CElementBuilder { public: - CSubsystemElementBuilder(const CSubsystemLibrary* pSubsystemLibrary); + CSubsystemElementBuilder(const CSubsystemLibrary *pSubsystemLibrary); - virtual CElement* createElement(const CXmlElement& xmlElement) const; + virtual CElement *createElement(const CXmlElement &xmlElement) const; private: - const CSubsystemLibrary* _pSubsystemLibrary; + const CSubsystemLibrary *_pSubsystemLibrary; }; - diff --git a/parameter/SubsystemLibrary.h b/parameter/SubsystemLibrary.h index 78a497e..f3082e2 100644 --- a/parameter/SubsystemLibrary.h +++ b/parameter/SubsystemLibrary.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,17 +31,28 @@ #include "DefaultElementLibrary.h" #include "VirtualSubsystem.h" -#include "NamedElementBuilderTemplate.h" +#include "LoggingElementBuilderTemplate.h" #include <string> -class CSubsystemLibrary : - public CDefaultElementLibrary<TNamedElementBuilderTemplate<CVirtualSubsystem> > +/** Plugin entry point symbol + * + * Needs to be implemented by plugin libraries. This function's purpose is to + * register element builders; + * + * "V1" refers to the version of this entry-point API. + */ +#define PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1 ParameterFrameworkPluginEntryPointMagicV1 + +class CSubsystemLibrary + : public CDefaultElementLibrary<TLoggingElementBuilderTemplate<CVirtualSubsystem>> { private: // Builder type (based on element's name attribute) - virtual std::string getBuilderType(const CXmlElement& xmlElement) const + virtual std::string getBuilderType(const CXmlElement &xmlElement) const { // Xml element's name attribute - return xmlElement.getAttributeString("Type"); + std::string type; + xmlElement.getAttribute("Type", type); + return type; } }; diff --git a/parameter/SubsystemObject.cpp b/parameter/SubsystemObject.cpp index e6b7b44..1b7b8f1 100644 --- a/parameter/SubsystemObject.cpp +++ b/parameter/SubsystemObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -34,6 +34,7 @@ #include "ParameterAccessContext.h" #include "MappingContext.h" #include "ParameterType.h" +#include "convert.hpp" #include <assert.h> #include <stdlib.h> #include <string.h> @@ -42,11 +43,10 @@ using std::string; -CSubsystemObject::CSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement) - : _pInstanceConfigurableElement(pInstanceConfigurableElement), - _uiDataSize(pInstanceConfigurableElement->getFootPrint()), - _pucBlackboardLocation(NULL), - _uiAccessedIndex(0) +CSubsystemObject::CSubsystemObject(CInstanceConfigurableElement *pInstanceConfigurableElement, + core::log::Logger &logger) + : _logger(logger), _pInstanceConfigurableElement(pInstanceConfigurableElement), + _dataSize(pInstanceConfigurableElement->getFootPrint()) { // Syncer _pInstanceConfigurableElement->setSyncer(this); @@ -64,35 +64,19 @@ string CSubsystemObject::getFormattedMappingValue() const } // Blackboard data location -uint8_t* CSubsystemObject::getBlackboardLocation() const +uint8_t *CSubsystemObject::getBlackboardLocation() const { - return _pucBlackboardLocation; + return _blackboard->getLocation(getOffset()); } // Size -uint32_t CSubsystemObject::getSize() const +size_t CSubsystemObject::getSize() const { - return _uiDataSize; -} - -// Conversion utility -uint32_t CSubsystemObject::asInteger(const string& strValue) -{ - return strtoul(strValue.c_str(), NULL, 0); -} - -string CSubsystemObject::asString(uint32_t uiValue) -{ - std::ostringstream ostr; - - ostr << uiValue; - - return ostr.str(); + return _dataSize; } int CSubsystemObject::toPlainInteger( - const CInstanceConfigurableElement *instanceConfigurableElement, - int sizeOptimizedData) + const CInstanceConfigurableElement *instanceConfigurableElement, int sizeOptimizedData) { if (instanceConfigurableElement) { @@ -108,31 +92,31 @@ int CSubsystemObject::toPlainInteger( } // Default back synchronization -void CSubsystemObject::setDefaultValues(CParameterBlackboard& parameterBlackboard) const +void CSubsystemObject::setDefaultValues(CParameterBlackboard ¶meterBlackboard) const { string strError; // Create access context - CParameterAccessContext parameterAccessContext(strError, ¶meterBlackboard, false); + CParameterAccessContext parameterAccessContext(strError, ¶meterBlackboard); // Just implement back synchronization with default values _pInstanceConfigurableElement->setDefaultValues(parameterAccessContext); } // Synchronization -bool CSubsystemObject::sync(CParameterBlackboard& parameterBlackboard, bool bBack, string& strError) +bool CSubsystemObject::sync(CParameterBlackboard ¶meterBlackboard, bool bBack, string &strError) { // Get blackboard location - _pucBlackboardLocation = parameterBlackboard.getLocation(_pInstanceConfigurableElement->getOffset()); + _blackboard = ¶meterBlackboard; // Access index init - _uiAccessedIndex = 0; + _accessedIndex = 0; #ifdef SIMULATION return true; #endif // Retrieve subsystem - const CSubsystem* pSubsystem = _pInstanceConfigurableElement->getBelongingSubsystem(); + const CSubsystem *pSubsystem = _pInstanceConfigurableElement->getBelongingSubsystem(); // Get it's health insdicator bool bIsSubsystemAlive = pSubsystem->isAlive(); @@ -146,15 +130,10 @@ bool CSubsystemObject::sync(CParameterBlackboard& parameterBlackboard, bool bBac // Synchronize to/from HW if (!bIsSubsystemAlive || !accessHW(bBack, strError)) { - strError = string("Unable to ") + (bBack ? "back" : "forward") + " synchronize configurable element " + - _pInstanceConfigurableElement->getPath() + ": " + strError; - - log_warning("%s", strError.c_str()); - // Fall back to parameter default initialization if (bBack) { - setDefaultValues(parameterBlackboard); + setDefaultValues(parameterBlackboard); } return false; } @@ -163,17 +142,15 @@ bool CSubsystemObject::sync(CParameterBlackboard& parameterBlackboard, bool bBac } // Sync to/from HW -bool CSubsystemObject::sendToHW(string& strError) +bool CSubsystemObject::sendToHW(string &strError) { strError = "Send to HW interface not implemented at subsystem level"; return false; } -bool CSubsystemObject::receiveFromHW(string& strError) +bool CSubsystemObject::receiveFromHW(string & /*strError*/) { - (void)strError; - // Back synchronization is not supported at subsystem level. // Rely on blackboard content @@ -181,7 +158,7 @@ bool CSubsystemObject::receiveFromHW(string& strError) } // Fall back HW access -bool CSubsystemObject::accessHW(bool bReceive, string& strError) +bool CSubsystemObject::accessHW(bool bReceive, string &strError) { // Default access fall back if (bReceive) { @@ -194,68 +171,32 @@ bool CSubsystemObject::accessHW(bool bReceive, string& strError) } // Blackboard access from subsystems -void CSubsystemObject::blackboardRead(void* pvData, uint32_t uiSize) -{ - assert(_uiAccessedIndex + uiSize <= _uiDataSize); - - memcpy(pvData, _pucBlackboardLocation + _uiAccessedIndex, uiSize); - - _uiAccessedIndex += uiSize; -} - -void CSubsystemObject::blackboardWrite(const void* pvData, uint32_t uiSize) -{ - assert(_uiAccessedIndex + uiSize <= _uiDataSize); - - memcpy(_pucBlackboardLocation + _uiAccessedIndex, pvData, uiSize); - - _uiAccessedIndex += uiSize; -} - -// Logging -void CSubsystemObject::log_info(std::string strMessage, ...) const +void CSubsystemObject::blackboardRead(void *pvData, size_t size) { - char *pacBuffer; - va_list listPointer; - - va_start(listPointer, strMessage); - - vasprintf(&pacBuffer, strMessage.c_str(), listPointer); - - va_end(listPointer); - - if (pacBuffer != NULL) { - _pInstanceConfigurableElement->log_info("%s", pacBuffer); - } + _blackboard->readBuffer(pvData, size, getOffset() + _accessedIndex); - free(pacBuffer); + _accessedIndex += size; } -void CSubsystemObject::log_warning(std::string strMessage, ...) const +void CSubsystemObject::blackboardWrite(const void *pvData, size_t size) { - char *pacBuffer; - va_list listPointer; + _blackboard->writeBuffer(pvData, size, getOffset() + _accessedIndex); - va_start(listPointer, strMessage); - - vasprintf(&pacBuffer, strMessage.c_str(), listPointer); - - va_end(listPointer); - - if (pacBuffer != NULL) { - _pInstanceConfigurableElement->log_warning("%s", pacBuffer); - } - - free(pacBuffer); + _accessedIndex += size; } // Configurable element retrieval -const CInstanceConfigurableElement* CSubsystemObject::getConfigurableElement() const +const CInstanceConfigurableElement *CSubsystemObject::getConfigurableElement() const { return _pInstanceConfigurableElement; } // Belonging Subsystem retrieval -const CSubsystem* CSubsystemObject::getSubsystem() const +const CSubsystem *CSubsystemObject::getSubsystem() const { return _pInstanceConfigurableElement->getBelongingSubsystem(); } + +size_t CSubsystemObject::getOffset() const +{ + return _pInstanceConfigurableElement->getOffset(); +} diff --git a/parameter/SubsystemObject.h b/parameter/SubsystemObject.h index 2ba2123..2400573 100644 --- a/parameter/SubsystemObject.h +++ b/parameter/SubsystemObject.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,19 +29,23 @@ */ #pragma once +#include "parameter_export.h" + #include "Syncer.h" -#include <stdint.h> +#include <log/Logger.h> +#include <stdint.h> #include <string> class CInstanceConfigurableElement; class CMappingContext; class CSubsystem; -class CSubsystemObject : private ISyncer +class PARAMETER_EXPORT CSubsystemObject : private ISyncer { public: - CSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement); + CSubsystemObject(CInstanceConfigurableElement *pInstanceConfigurableElement, + core::log::Logger &logger); virtual ~CSubsystemObject(); /** @@ -52,16 +56,15 @@ public: virtual std::string getFormattedMappingValue() const; // Configurable element retrieval - const CInstanceConfigurableElement* getConfigurableElement() const; + const CInstanceConfigurableElement *getConfigurableElement() const; protected: - // Blackboard data location - uint8_t* getBlackboardLocation() const; + /** FIXME: plugins should not have direct access to blackboard memory. + * Ie: This method should be removed or return a abstracted iterator. + */ + uint8_t *getBlackboardLocation() const; // Size - uint32_t getSize() const; - // Conversion utility - static uint32_t asInteger(const std::string& strValue); - static std::string asString(uint32_t uiValue); + size_t getSize() const; /** * Conversion of int8, int16, int32 to int (taking care of sign extension) @@ -75,43 +78,52 @@ protected: int sizeOptimizedData); // Sync to/from HW - virtual bool sendToHW(std::string& strError); - virtual bool receiveFromHW(std::string& strError); + virtual bool sendToHW(std::string &strError); + virtual bool receiveFromHW(std::string &strError); // Fall back HW access - virtual bool accessHW(bool bReceive, std::string& strError); + virtual bool accessHW(bool bReceive, std::string &strError); // Blackboard access from subsystems - void blackboardRead(void* pvData, uint32_t uiSize); - void blackboardWrite(const void* pvData, uint32_t uiSize); - // Logging - // Copy the string format because: - // - passing char * would break compatibility - // - passing a const std::string & in forbiden by the c++ standard - // as va_start second argument must not be a reference. - void log_info(std::string strMessage, ...) const; - void log_warning(std::string strMessage, ...) const; + void blackboardRead(void *pvData, size_t size); + void blackboardWrite(const void *pvData, size_t size); // Belonging Subsystem retrieval - const CSubsystem* getSubsystem() const; + const CSubsystem *getSubsystem() const; + + /** Logging methods + *@{ + */ + core::log::details::Info info() const { return _logger.info(); } + core::log::details::Warning warning() const { return _logger.warning(); } + /* @} */ private: // from ISyncer - virtual bool sync(CParameterBlackboard& parameterBlackboard, bool bBack, std::string& strError); + /** This method is not supposed to be overridden by plugins + * as if not called, plugins will not work (sets _blackboard). + */ + bool sync(CParameterBlackboard ¶meterBlackboard, bool bBack, + std::string &strError) override final; // Default back synchronization - void setDefaultValues(CParameterBlackboard& parameterBlackboard) const; + void setDefaultValues(CParameterBlackboard ¶meterBlackboard) const; + + /** @return the offset in the main blackboard of the sync values. */ + size_t getOffset() const; // Prevent unsupported operators - CSubsystemObject(const CSubsystemObject&); + CSubsystemObject(const CSubsystemObject &); // Define affection operator - const CSubsystemObject& operator=(const CSubsystemObject&); + const CSubsystemObject &operator=(const CSubsystemObject &); + + /** Application Logger */ + core::log::Logger &_logger; // Instance element to sync from/to - CInstanceConfigurableElement* _pInstanceConfigurableElement; + CInstanceConfigurableElement *_pInstanceConfigurableElement; // Data size - uint32_t _uiDataSize; + size_t _dataSize; // Blackboard data location - uint8_t* _pucBlackboardLocation; + CParameterBlackboard *_blackboard{nullptr}; // Accessed index for Subsystem read/write from/to blackboard - uint32_t _uiAccessedIndex; + size_t _accessedIndex{0}; }; - diff --git a/parameter/SubsystemObjectCreator.cpp b/parameter/SubsystemObjectCreator.cpp index 66c1cac..69e007a 100644 --- a/parameter/SubsystemObjectCreator.cpp +++ b/parameter/SubsystemObjectCreator.cpp @@ -31,13 +31,16 @@ using std::string; -CSubsystemObjectCreator::CSubsystemObjectCreator(const string& strMappingKey, uint32_t uiAncestorIdMask, uint32_t uiMaxConfigurableElementSize) - : _strMappingKey(strMappingKey), _uiAncestorIdMask(uiAncestorIdMask), _uiMaxConfigurableElementSize(uiMaxConfigurableElementSize) +CSubsystemObjectCreator::CSubsystemObjectCreator(const string &strMappingKey, + uint32_t uiAncestorIdMask, + size_t maxConfigurableElementSize) + : _strMappingKey(strMappingKey), _uiAncestorIdMask(uiAncestorIdMask), + _maxConfigurableElementSize(maxConfigurableElementSize) { } // Accessors -const string& CSubsystemObjectCreator::getMappingKey() const +const string &CSubsystemObjectCreator::getMappingKey() const { return _strMappingKey; } @@ -47,7 +50,7 @@ uint32_t CSubsystemObjectCreator::getAncestorMask() const return _uiAncestorIdMask; } -uint32_t CSubsystemObjectCreator::getMaxConfigurableElementSize() const +size_t CSubsystemObjectCreator::getMaxConfigurableElementSize() const { - return _uiMaxConfigurableElementSize; + return _maxConfigurableElementSize; } diff --git a/parameter/SubsystemObjectCreator.h b/parameter/SubsystemObjectCreator.h index ed6e79d..8a4b098 100644 --- a/parameter/SubsystemObjectCreator.h +++ b/parameter/SubsystemObjectCreator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,24 +29,30 @@ */ #pragma once +#include "parameter_export.h" + #include "SubsystemObject.h" #include "MappingContext.h" #include <string> -class CSubsystemObjectCreator +class PARAMETER_EXPORT CSubsystemObjectCreator { public: - CSubsystemObjectCreator(const std::string& strMappingKey, uint32_t uiAncestorIdMask, uint32_t uiMaxConfigurableElementSize); + CSubsystemObjectCreator(const std::string &strMappingKey, uint32_t uiAncestorIdMask, + size_t maxConfigurableElementSize); // Accessors - const std::string& getMappingKey() const; + const std::string &getMappingKey() const; uint32_t getAncestorMask() const; - uint32_t getMaxConfigurableElementSize() const; + size_t getMaxConfigurableElementSize() const; // Object creation - virtual CSubsystemObject* objectCreate(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context) const = 0; + virtual CSubsystemObject *objectCreate( + const std::string &strMappingValue, + CInstanceConfigurableElement *pInstanceConfigurableElement, const CMappingContext &context, + core::log::Logger &logger) const = 0; - virtual ~CSubsystemObjectCreator() {} + virtual ~CSubsystemObjectCreator() = default; private: // Mapping key @@ -54,6 +60,5 @@ private: // Mask of must-be-specified ancestors uint32_t _uiAncestorIdMask; // Masximum expected size for configurable elment (-1 means none) - uint32_t _uiMaxConfigurableElementSize; + size_t _maxConfigurableElementSize; }; - diff --git a/parameter/SubsystemObjectFactory.h b/parameter/SubsystemObjectFactory.h index 3ac7835..9881227 100644 --- a/parameter/SubsystemObjectFactory.h +++ b/parameter/SubsystemObjectFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,16 +31,25 @@ #include "SubsystemObjectCreator.h" #include <string> +#include <limits> template <class SubsystemObjectType> class TSubsystemObjectFactory : public CSubsystemObjectCreator { public: - TSubsystemObjectFactory(const std::string& strMappingKey, uint32_t uiAncestorIdMask, uint32_t uiMaxConfigurableElementSize = -1) : CSubsystemObjectCreator(strMappingKey, uiAncestorIdMask, uiMaxConfigurableElementSize) {} + TSubsystemObjectFactory(const std::string &strMappingKey, uint32_t uiAncestorIdMask, + size_t maxConfigurableElementSize = std::numeric_limits<size_t>::max()) + : CSubsystemObjectCreator(strMappingKey, uiAncestorIdMask, maxConfigurableElementSize) + { + } // Object creation - virtual CSubsystemObject* objectCreate(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context) const + virtual CSubsystemObject *objectCreate( + const std::string &strMappingValue, + CInstanceConfigurableElement *pInstanceConfigurableElement, const CMappingContext &context, + core::log::Logger &logger) const { - return new SubsystemObjectType(strMappingValue, pInstanceConfigurableElement, context); + return new SubsystemObjectType(strMappingValue, pInstanceConfigurableElement, context, + logger); } }; diff --git a/parameter/SubsystemPlugins.h b/parameter/SubsystemPlugins.h index aa9e32c..c5eb1c6 100644 --- a/parameter/SubsystemPlugins.h +++ b/parameter/SubsystemPlugins.h @@ -36,13 +36,11 @@ class CSubsystemPlugins : public CKindElement { public: - CSubsystemPlugins(const std::string& strName, const std::string& strKind) : CKindElement(strName, strKind) + CSubsystemPlugins(const std::string &strName, const std::string &strKind) + : CKindElement(strName, strKind) { } private: - virtual bool childrenAreDynamic() const - { - return true; - } + virtual bool childrenAreDynamic() const { return true; } }; diff --git a/parameter/Syncer.h b/parameter/Syncer.h index f119028..279dba3 100644 --- a/parameter/Syncer.h +++ b/parameter/Syncer.h @@ -36,8 +36,9 @@ class CParameterBlackboard; class ISyncer { public: - virtual bool sync(CParameterBlackboard& parameterBlackboard, bool bBack, std::string& strError) = 0; + virtual bool sync(CParameterBlackboard ¶meterBlackboard, bool bBack, + std::string &strError) = 0; protected: - virtual ~ISyncer() {} + virtual ~ISyncer() = default; }; diff --git a/parameter/SyncerSet.cpp b/parameter/SyncerSet.cpp index 9daf2a6..c27245c 100644 --- a/parameter/SyncerSet.cpp +++ b/parameter/SyncerSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -30,18 +30,14 @@ #include "SyncerSet.h" #include "Syncer.h" -CSyncerSet::CSyncerSet() -{ -} - -const CSyncerSet& CSyncerSet::operator+=(ISyncer* pRightSyncer) +const CSyncerSet &CSyncerSet::operator+=(ISyncer *pRightSyncer) { _syncerSet.insert(pRightSyncer); return *this; } -const CSyncerSet& CSyncerSet::operator+=(const CSyncerSet& rightSyncerSet) +const CSyncerSet &CSyncerSet::operator+=(const CSyncerSet &rightSyncerSet) { if (&rightSyncerSet != this) { @@ -56,7 +52,8 @@ void CSyncerSet::clear() _syncerSet.clear(); } -bool CSyncerSet::sync(CParameterBlackboard& parameterBlackboard, bool bBack, std::list<std::string>* plstrError) const +bool CSyncerSet::sync(CParameterBlackboard ¶meterBlackboard, bool bBack, + core::Results *errors) const { bool bSuccess = true; @@ -67,13 +64,13 @@ bool CSyncerSet::sync(CParameterBlackboard& parameterBlackboard, bool bBack, std for (it = _syncerSet.begin(); it != _syncerSet.end(); ++it) { - ISyncer* pSyncer = *it; + ISyncer *pSyncer = *it; if (!pSyncer->sync(parameterBlackboard, bBack, strError)) { - if (plstrError) { + if (errors != NULL) { - plstrError->push_back(strError); + errors->push_back(strError); } bSuccess = false; } diff --git a/parameter/SyncerSet.h b/parameter/SyncerSet.h index 7e37f45..a1bff8d 100644 --- a/parameter/SyncerSet.h +++ b/parameter/SyncerSet.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,29 +29,33 @@ */ #pragma once +#include "Results.h" #include <set> -#include <string> -#include <list> class ISyncer; class CParameterBlackboard; class CSyncerSet { - typedef std::set<ISyncer*>::const_iterator SyncerSetConstIterator; -public: - CSyncerSet(); + typedef std::set<ISyncer *>::const_iterator SyncerSetConstIterator; +public: // Filling - const CSyncerSet& operator+=(ISyncer* pRightSyncer); - const CSyncerSet& operator+=(const CSyncerSet& rightSyncerSet); + const CSyncerSet &operator+=(ISyncer *pRightSyncer); + const CSyncerSet &operator+=(const CSyncerSet &rightSyncerSet); // Clearing void clear(); - // Sync - bool sync(CParameterBlackboard& parameterBlackboard, bool bBack, std::list<std::string>* plstrError) const; + /** Sync the blackboard + * + * @param parameterBlackboard blackboard associated to syncer + * @param[in] bBack indicates if we want to back synchronise or to forward synchronise + * @param[out] errors, errors encountered during restoration + * @return true if success false otherwise + */ + bool sync(CParameterBlackboard ¶meterBlackboard, bool bBack, core::Results *errors) const; private: - std::set<ISyncer*> _syncerSet; + std::set<ISyncer *> _syncerSet; }; diff --git a/parameter/SystemClass.cpp b/parameter/SystemClass.cpp index ae4f747..21c7a86 100644 --- a/parameter/SystemClass.cpp +++ b/parameter/SystemClass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,43 +27,36 @@ * (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 <dlfcn.h> -#include <dirent.h> #include <algorithm> -#include <ctype.h> #include "SystemClass.h" #include "SubsystemLibrary.h" -#include "AutoLog.h" #include "VirtualSubsystem.h" -#include "NamedElementBuilderTemplate.h" -#include <assert.h> +#include "LoggingElementBuilderTemplate.h" +#include <cassert> #include "PluginLocation.h" +#include "DynamicLibrary.hpp" #include "Utility.h" +#include "Memory.hpp" #define base CConfigurableElement +#ifndef PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1 +#error Missing PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1 macro definition +#endif +#define QUOTE(X) #X +#define MACRO_TO_STR(X) QUOTE(X) +const char CSystemClass::entryPointSymbol[] = + MACRO_TO_STR(PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1); +using PluginEntryPointV1 = void (*)(CSubsystemLibrary *, core::log::Logger &); + using std::list; using std::string; -/** - * A plugin file name is of the form: - * lib<type>-subsystem.so or lib<type>-subsystem._host.so - * - * The plugin symbol is of the form: - * get<TYPE>SubsystemBuilder -*/ -// Plugin file naming -const char* gpcPluginSuffix = "-subsystem"; -const char* gpcPluginPrefix = "lib"; - -// Plugin symbol naming -const char* gpcPluginSymbolPrefix = "get"; -const char* gpcPluginSymbolSuffix = "SubsystemBuilder"; +// FIXME: integrate SystemClass to core namespace +using namespace core; -// Used by subsystem plugins -typedef void (*GetSubsystemBuilder)(CSubsystemLibrary*); - -CSystemClass::CSystemClass() : _pSubsystemLibrary(new CSubsystemLibrary) +CSystemClass::CSystemClass(log::Logger &logger) + : _pSubsystemLibrary(new CSubsystemLibrary()), _logger(logger) { } @@ -74,14 +67,6 @@ CSystemClass::~CSystemClass() // Destroy child subsystems *before* unloading the libraries (otherwise crashes will occur // as unmapped code will be referenced) clean(); - - // Close all previously opened subsystem libraries - list<void*>::const_iterator it; - - for (it = _subsystemLibraryHandleList.begin(); it != _subsystemLibraryHandleList.end(); ++it) { - - dlclose(*it); - } } bool CSystemClass::childrenAreDynamic() const @@ -94,53 +79,59 @@ string CSystemClass::getKind() const return "SystemClass"; } -bool CSystemClass::loadSubsystems(string& strError, - const CSubsystemPlugins* pSubsystemPlugins, - bool bVirtualSubsystemFallback) +bool CSystemClass::getMappingData(const std::string & /*strKey*/, + const std::string *& /*pStrValue*/) const { - CAutoLog autoLog_info(this, "Loading subsystem plugins"); + // Although it could make sense to have mapping in the system class, + // just like at subsystem level, it is currently not supported. + return false; +} +string CSystemClass::getFormattedMapping() const +{ + return ""; +} + +bool CSystemClass::loadSubsystems(string &strError, const CSubsystemPlugins *pSubsystemPlugins, + bool bVirtualSubsystemFallback) +{ // Start clean _pSubsystemLibrary->clean(); + typedef TLoggingElementBuilderTemplate<CVirtualSubsystem> VirtualSubsystemBuilder; // Add virtual subsystem builder - _pSubsystemLibrary->addElementBuilder("Virtual", - new TNamedElementBuilderTemplate<CVirtualSubsystem>()); + _pSubsystemLibrary->addElementBuilder("Virtual", new VirtualSubsystemBuilder(_logger)); // Set virtual subsytem as builder fallback if required - _pSubsystemLibrary->enableDefaultMechanism(bVirtualSubsystemFallback); + if (bVirtualSubsystemFallback) { + _pSubsystemLibrary->setDefaultBuilder( + utility::make_unique<VirtualSubsystemBuilder>(_logger)); + } // Add subsystem defined in shared libraries - list<string> lstrError; - bool bLoadPluginsSuccess = loadSubsystemsFromSharedLibraries(lstrError, pSubsystemPlugins); - - if (bLoadPluginsSuccess) { - log_info("All subsystem plugins successfully loaded"); - } else { - // Log plugin as warning if no fallback available - log_table(!bVirtualSubsystemFallback, lstrError); - } + core::Results errors; + bool bLoadPluginsSuccess = loadSubsystemsFromSharedLibraries(errors, pSubsystemPlugins); - if (!bVirtualSubsystemFallback) { - // Any problem reported is an error as there is no fallback. - // Fill strError for caller. - CUtility::asString(lstrError, strError); - } + // Fill strError for caller, he has to decide if there is a problem depending on + // bVirtualSubsystemFallback value + strError = utility::asString(errors); return bLoadPluginsSuccess || bVirtualSubsystemFallback; } -bool CSystemClass::loadSubsystemsFromSharedLibraries(list<string>& lstrError, - const CSubsystemPlugins* pSubsystemPlugins) +bool CSystemClass::loadSubsystemsFromSharedLibraries(core::Results &errors, + const CSubsystemPlugins *pSubsystemPlugins) { // Plugin list list<string> lstrPluginFiles; - uint32_t uiPluginLocation; + size_t pluginLocation; - for (uiPluginLocation = 0; uiPluginLocation < pSubsystemPlugins->getNbChildren(); uiPluginLocation++) { + for (pluginLocation = 0; pluginLocation < pSubsystemPlugins->getNbChildren(); + pluginLocation++) { // Get Folder for current Plugin Location - const CPluginLocation* pPluginLocation = static_cast<const CPluginLocation*>(pSubsystemPlugins->getChild(uiPluginLocation)); + const CPluginLocation *pPluginLocation = + static_cast<const CPluginLocation *>(pSubsystemPlugins->getChild(pluginLocation)); string strFolder(pPluginLocation->getFolder()); if (!strFolder.empty()) { @@ -149,7 +140,7 @@ bool CSystemClass::loadSubsystemsFromSharedLibraries(list<string>& lstrError, // Iterator on Plugin List: list<string>::const_iterator it; - const list<string>& pluginList = pPluginLocation->getPluginList(); + const list<string> &pluginList = pPluginLocation->getPluginList(); for (it = pluginList.begin(); it != pluginList.end(); ++it) { @@ -167,7 +158,7 @@ bool CSystemClass::loadSubsystemsFromSharedLibraries(list<string>& lstrError, // process failed to load at least one of them // Attempt to load the complete list - if (!loadPlugins(lstrPluginFiles, lstrError)) { + if (!loadPlugins(lstrPluginFiles, errors)) { // Unable to load at least one plugin break; @@ -176,41 +167,16 @@ bool CSystemClass::loadSubsystemsFromSharedLibraries(list<string>& lstrError, if (!lstrPluginFiles.empty()) { // Unable to load at least one plugin - string strPluginUnloaded; - CUtility::asString(lstrPluginFiles, strPluginUnloaded, ", "); - - lstrError.push_back("Unable to load the following plugins: " + strPluginUnloaded + "."); + errors.push_back("Unable to load the following plugins: " + + utility::asString(lstrPluginFiles, ", ") + "."); return false; } return true; } -// Plugin symbol computation -string CSystemClass::getPluginSymbol(const string& strPluginPath) -{ - // Extract plugin type out of file name - string strPluginSuffix = gpcPluginSuffix; - string strPluginPrefix = gpcPluginPrefix; - - // Remove folder and library prefix - size_t iPluginTypePos = strPluginPath.rfind('/') + 1 + strPluginPrefix.length(); - - // Get index of -subsystem.so or -subsystem_host.so suffix - size_t iSubsystemPos = strPluginPath.find(strPluginSuffix, iPluginTypePos); - - // Get type (between iPluginTypePos and iSubsystemPos) - string strPluginType = strPluginPath.substr(iPluginTypePos, iSubsystemPos - iPluginTypePos); - - // Make it upper case - std::transform(strPluginType.begin(), strPluginType.end(), strPluginType.begin(), ::toupper); - - // Get plugin symbol - return gpcPluginSymbolPrefix + strPluginType + gpcPluginSymbolSuffix; -} - // Plugin loading -bool CSystemClass::loadPlugins(list<string>& lstrPluginFiles, list<string>& lstrError) +bool CSystemClass::loadPlugins(list<string> &lstrPluginFiles, core::Results &errors) { assert(lstrPluginFiles.size()); @@ -222,39 +188,24 @@ bool CSystemClass::loadPlugins(list<string>& lstrPluginFiles, list<string>& lstr string strPluginFileName = *it; - log_info("Attempting to load subsystem plugin path \"%s\"", strPluginFileName.c_str()); - // Load attempt - void* lib_handle = dlopen(strPluginFileName.c_str(), RTLD_LAZY); + try { + auto library = utility::make_unique<DynamicLibrary>(strPluginFileName); - if (!lib_handle) { + // Load symbol from library + auto subSystemBuilder = library->getSymbol<PluginEntryPointV1>(entryPointSymbol); - const char *err = dlerror(); - // Failed - if (err == NULL) { - lstrError.push_back("dlerror failed"); - } else { - lstrError.push_back("Plugin load failed: " + string(err)); - } - // Next plugin - ++it; - - continue; - } - - // Store libraries handles - _subsystemLibraryHandleList.push_back(lib_handle); + // Store libraries handles + _subsystemLibraryHandleList.push_back(std::move(library)); - // Get plugin symbol - string strPluginSymbol = getPluginSymbol(strPluginFileName); + // Fill library + subSystemBuilder(_pSubsystemLibrary, _logger); - // Load symbol from library - GetSubsystemBuilder pfnGetSubsystemBuilder = (GetSubsystemBuilder)dlsym(lib_handle, strPluginSymbol.c_str()); + } catch (std::exception &e) { + errors.push_back(e.what()); - if (!pfnGetSubsystemBuilder) { - - lstrError.push_back("Subsystem plugin " + strPluginFileName + - " does not contain " + strPluginSymbol + " symbol."); + // Next plugin + ++it; continue; } @@ -262,9 +213,6 @@ bool CSystemClass::loadPlugins(list<string>& lstrPluginFiles, list<string>& lstr // Account for this success bAtLeastOneSubsystemPluginSuccessfullyLoaded = true; - // Fill library - pfnGetSubsystemBuilder(_pSubsystemLibrary); - // Remove successfully loaded plugin from list and select next lstrPluginFiles.erase(it++); } @@ -272,24 +220,24 @@ bool CSystemClass::loadPlugins(list<string>& lstrPluginFiles, list<string>& lstr return bAtLeastOneSubsystemPluginSuccessfullyLoaded; } -const CSubsystemLibrary* CSystemClass::getSubsystemLibrary() const +const CSubsystemLibrary *CSystemClass::getSubsystemLibrary() const { return _pSubsystemLibrary; } -void CSystemClass::checkForSubsystemsToResync(CSyncerSet& syncerSet) +void CSystemClass::checkForSubsystemsToResync(CSyncerSet &syncerSet, core::Results &infos) { size_t uiNbChildren = getNbChildren(); size_t uiChild; for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - CSubsystem* pSubsystem = static_cast<CSubsystem*>(getChild(uiChild)); + CSubsystem *pSubsystem = static_cast<CSubsystem *>(getChild(uiChild)); // Collect and consume the need for a resync if (pSubsystem->needResync(true)) { - log_info("Resynchronizing subsystem: %s", pSubsystem->getName().c_str()); + infos.push_back("Resynchronizing subsystem: " + pSubsystem->getName()); // get all subsystem syncers pSubsystem->fillSyncerSet(syncerSet); } @@ -303,7 +251,7 @@ void CSystemClass::cleanSubsystemsNeedToResync() for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - CSubsystem* pSubsystem = static_cast<CSubsystem*>(getChild(uiChild)); + CSubsystem *pSubsystem = static_cast<CSubsystem *>(getChild(uiChild)); // Consume the need for a resync pSubsystem->needResync(true); diff --git a/parameter/SystemClass.h b/parameter/SystemClass.h index dd215a6..43a581b 100644 --- a/parameter/SystemClass.h +++ b/parameter/SystemClass.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,15 +31,23 @@ #include "ConfigurableElement.h" #include "SubsystemPlugins.h" +#include "Results.h" +#include <log/Logger.h> #include <list> #include <string> +#include <memory> class CSubsystemLibrary; +class DynamicLibrary; -class CSystemClass : public CConfigurableElement +class CSystemClass final : public CConfigurableElement { public: - CSystemClass(); + /** + * @param[in] logger the logger provided by the client + * it need to be given to the subsystem library + */ + CSystemClass(core::log::Logger &logger); virtual ~CSystemClass(); /** Load subsystem plugin and fill the corresponding libraries. @@ -52,10 +60,10 @@ public: * @return true if the plugins succesfully started or that a fallback is available, false otherwise. */ - bool loadSubsystems(std::string& strError, const CSubsystemPlugins* pSubsystemPlugins, + bool loadSubsystems(std::string &strError, const CSubsystemPlugins *pSubsystemPlugins, bool bVirtualSubsystemFallback = false); // Subsystem factory - const CSubsystemLibrary* getSubsystemLibrary() const; + const CSubsystemLibrary *getSubsystemLibrary() const; /** * Look for subsystems that need to be resynchronized. @@ -63,8 +71,9 @@ public: * and fill a syncer set with all syncers that need to be resynchronized * * @param[out] syncerSet The syncer set to fill + * @param[out] infos Relevant informations client may want to log */ - void checkForSubsystemsToResync(CSyncerSet& syncerSet); + void checkForSubsystemsToResync(CSyncerSet &syncerSet, core::Results &infos); /** * Reset subsystems need to resync flag. @@ -74,39 +83,46 @@ public: // base virtual std::string getKind() const; + bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const override; + std::string getFormattedMapping() const override; + private: - CSystemClass(const CSystemClass&); - CSystemClass& operator=(const CSystemClass&); + CSystemClass(const CSystemClass &); + CSystemClass &operator=(const CSystemClass &); // base virtual bool childrenAreDynamic() const; /** Load shared libraries subsystem plugins. * - * @param[out] lstrError is the list of error that occured during loadings. + * @param[out] errors is the list of error that occured during loadings. * @param[in] pSubsystemPlugins The plugins to load. * * @return true if all plugins have been succesfully loaded, false otherwises. */ - bool loadSubsystemsFromSharedLibraries(std::list<std::string>& lstrError, - const CSubsystemPlugins* pSubsystemPlugins); - - // Plugin symbol computation - static std::string getPluginSymbol(const std::string& strPluginPath); + bool loadSubsystemsFromSharedLibraries(core::Results &errors, + const CSubsystemPlugins *pSubsystemPlugins); /** Load subsystem plugin shared libraries. * - * @param[in:out] lstrPluginFiles is the path list of the plugins shared libraries to load. + * @param[in,out] lstrPluginFiles is the path list of the plugins shared libraries to load. * Successfully loaded plugins are removed from the list. - * @param[out] lstrError is the list of error that occured during loadings. + * @param[out] errors is the list of error that occured during loadings. * * @return true if at least one plugin has been succesfully loaded, false otherwise. * When false is returned, some plugins MIHGT have been loaded * but the lstrPluginFiles is accurate. */ - bool loadPlugins(std::list<std::string>& lstrPluginFiles, std::list<std::string>& lstrError); + bool loadPlugins(std::list<std::string> &lstrPluginFiles, core::Results &errors); // Subsystem factory - CSubsystemLibrary* _pSubsystemLibrary; - std::list<void*> _subsystemLibraryHandleList; /**< Contains the list of all open plugin libs. */ -}; + CSubsystemLibrary *_pSubsystemLibrary; + std::list<std::unique_ptr<DynamicLibrary>> + _subsystemLibraryHandleList; /**< Contains the list of all open plugin libs. */ + + /** Application Logger we need to provide to plugins */ + core::log::Logger &_logger; + /** The entry point symbol that must be implemented by plugins + */ + static const char entryPointSymbol[]; +}; diff --git a/parameter/TypeElement.cpp b/parameter/TypeElement.cpp index 01b7137..e6b9276 100644 --- a/parameter/TypeElement.cpp +++ b/parameter/TypeElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,11 +31,13 @@ #include "MappingData.h" #include "Tokenizer.h" #include "InstanceConfigurableElement.h" +#include "Utility.h" +#include <list> #include <assert.h> #define base CElement -CTypeElement::CTypeElement(const std::string& strName) : base(strName), _uiArrayLength(0), _pMappingData(NULL) +CTypeElement::CTypeElement(const std::string &strName) : base(strName) { } @@ -46,12 +48,12 @@ CTypeElement::~CTypeElement() bool CTypeElement::isScalar() const { - return !_uiArrayLength; + return !_arrayLength; } -uint32_t CTypeElement::getArrayLength() const +size_t CTypeElement::getArrayLength() const { - return _uiArrayLength; + return _arrayLength; } int CTypeElement::toPlainInteger(int iSizeOptimizedData) const @@ -59,7 +61,7 @@ int CTypeElement::toPlainInteger(int iSizeOptimizedData) const return iSizeOptimizedData; } -bool CTypeElement::getMappingData(const std::string& strKey, const std::string*& pStrValue) const +bool CTypeElement::getMappingData(const std::string &strKey, const std::string *&pStrValue) const { if (_pMappingData) { @@ -74,7 +76,7 @@ bool CTypeElement::hasMappingData() const } // Element properties -void CTypeElement::showProperties(std::string& strResult) const +void CTypeElement::showProperties(std::string &strResult) const { // The description attribute may be found in the type and not from instance. showDescriptionProperty(strResult); @@ -83,7 +85,7 @@ void CTypeElement::showProperties(std::string& strResult) const // which have a common base Element) } -void CTypeElement::populate(CElement* pElement) const +void CTypeElement::populate(CElement *pElement) const { // Populate children size_t uiChild; @@ -91,38 +93,40 @@ void CTypeElement::populate(CElement* pElement) const for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - const CTypeElement* pChildTypeElement = static_cast<const CTypeElement*>(getChild(uiChild)); + const CTypeElement *pChildTypeElement = + static_cast<const CTypeElement *>(getChild(uiChild)); - CInstanceConfigurableElement* pInstanceConfigurableChildElement = pChildTypeElement->instantiate(); + CInstanceConfigurableElement *pInstanceConfigurableChildElement = + pChildTypeElement->instantiate(); // Affiliate pElement->addChild(pInstanceConfigurableChildElement); } } -bool CTypeElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CTypeElement::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Array Length attribute - if (xmlElement.hasAttribute("ArrayLength")) { - - _uiArrayLength = xmlElement.getAttributeInteger("ArrayLength"); - } else { - _uiArrayLength = 0; // Scalar - } + xmlElement.getAttribute("ArrayLength", _arrayLength); // Manage mapping attribute - if (xmlElement.hasAttribute("Mapping")) { + std::string rawMapping; + if (xmlElement.getAttribute("Mapping", rawMapping) && !rawMapping.empty()) { - if (!getMappingData()->fromXml(xmlElement, serializingContext)) { + std::string error; + if (!getMappingData()->init(rawMapping, error)) { + serializingContext.setError("Invalid Mapping data from XML element '" + + xmlElement.getPath() + "': " + error); return false; } } return base::fromXml(xmlElement, serializingContext); } -CInstanceConfigurableElement* CTypeElement::instantiate() const +CInstanceConfigurableElement *CTypeElement::instantiate() const { - CInstanceConfigurableElement* pInstanceConfigurableElement = doInstantiate(); + CInstanceConfigurableElement *pInstanceConfigurableElement = doInstantiate(); // Populate populate(pInstanceConfigurableElement); @@ -130,7 +134,7 @@ CInstanceConfigurableElement* CTypeElement::instantiate() const return pInstanceConfigurableElement; } -CMappingData* CTypeElement::getMappingData() +CMappingData *CTypeElement::getMappingData() { if (!_pMappingData) { @@ -139,6 +143,30 @@ CMappingData* CTypeElement::getMappingData() return _pMappingData; } +std::string CTypeElement::getFormattedMapping(const CTypeElement *predecessor) const +{ + std::list<std::string> mappings; + std::string mapping; + + // Try predecessor type first, then myself (in order to have higher-level + // mappings displayed first) + if (predecessor) { + mapping = predecessor->getFormattedMapping(); + if (not mapping.empty()) { + mappings.push_back(mapping); + } + } + + // Explicitly call the root implementation instead of calling it virtually + // (otherwise, it will infinitely recurse). + mapping = CTypeElement::getFormattedMapping(); + if (not mapping.empty()) { + mappings.push_back(mapping); + } + + return utility::asString(mappings, ", "); +} + std::string CTypeElement::getFormattedMapping() const { if (_pMappingData) { @@ -149,11 +177,11 @@ std::string CTypeElement::getFormattedMapping() const } // From IXmlSource -void CTypeElement::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const +void CTypeElement::toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const { if (!isScalar()) { - xmlElement.setAttributeInteger("ArrayLength", getArrayLength()); + xmlElement.setAttribute("ArrayLength", getArrayLength()); } base::toXml(xmlElement, serializingContext); diff --git a/parameter/TypeElement.h b/parameter/TypeElement.h index 8f474c0..9d8f46f 100644 --- a/parameter/TypeElement.h +++ b/parameter/TypeElement.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,23 +29,25 @@ */ #pragma once +#include "parameter_export.h" + #include "Element.h" #include <string> class CMappingData; class CInstanceConfigurableElement; -class CTypeElement : public CElement +class PARAMETER_EXPORT CTypeElement : public CElement { public: - CTypeElement(const std::string& strName = ""); + CTypeElement(const std::string &strName = ""); virtual ~CTypeElement(); // Instantiation - CInstanceConfigurableElement* instantiate() const; + CInstanceConfigurableElement *instantiate() const; // Mapping info - virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const; + virtual bool getMappingData(const std::string &strKey, const std::string *&pStrValue) const; virtual bool hasMappingData() const; /** @@ -56,19 +58,19 @@ public: virtual std::string getFormattedMapping() const; // Element properties - virtual void showProperties(std::string& strResult) const; + virtual void showProperties(std::string &strResult) const; // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); // From IXmlSource - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const; + virtual void toXml(CXmlElement &xmlElement, CXmlSerializingContext &serializingContext) const; // Scalar or Array? bool isScalar() const; // Array Length - uint32_t getArrayLength() const; + size_t getArrayLength() const; /** * Converts size optimized integer input data (int8, int16, int32) to plain int @@ -81,19 +83,31 @@ public: protected: // Object creation - virtual void populate(CElement* pElement) const; + virtual void populate(CElement *pElement) const; + /** @Returns the mapping associated to the current type and its predecessor + * + * The meaning of predecessor depends on the TypeElement type: e.g. for a + * component instance, the predecessor is the ComponentType; for a + * ComponentType, the predecessor is its base type. + * + * The predecessor's mapping comes first, then the current type's mapping. + * + * @param[in] predecessor A pointer to the predecessor or NULL. + */ + std::string getFormattedMapping(const CTypeElement *predecessor) const; + private: - CTypeElement(const CTypeElement&); - CTypeElement& operator=(const CTypeElement&); + CTypeElement(const CTypeElement &); + CTypeElement &operator=(const CTypeElement &); // Actual instance creation - virtual CInstanceConfigurableElement* doInstantiate() const = 0; + virtual CInstanceConfigurableElement *doInstantiate() const = 0; // Mapping data creation and access - CMappingData* getMappingData(); + CMappingData *getMappingData(); // For Arrays. 0 means scalar - uint32_t _uiArrayLength; + size_t _arrayLength{0}; // Mapping info - CMappingData* _pMappingData; + CMappingData *_pMappingData{nullptr}; }; diff --git a/parameter/VirtualSubsystem.cpp b/parameter/VirtualSubsystem.cpp index 36027bf..4bb7a17 100644 --- a/parameter/VirtualSubsystem.cpp +++ b/parameter/VirtualSubsystem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,14 +29,18 @@ */ #include "VirtualSubsystem.h" #include "VirtualSyncer.h" +#include "SyncerSet.h" #define base CSubsystem using std::string; -CVirtualSubsystem::CVirtualSubsystem(const string& strName) - : base(strName), _pVirtualSyncer(new CVirtualSyncer(this)) +CVirtualSubsystem::CVirtualSubsystem(const string &strName, core::log::Logger &logger) + : base(strName, logger), _pVirtualSyncer(new CVirtualSyncer(this)) { + logger.warning() << "Subsystem " << strName + << " loaded as virtual. " + "Its parameters will not be synced with any external system."; } CVirtualSubsystem::~CVirtualSubsystem() @@ -45,17 +49,20 @@ CVirtualSubsystem::~CVirtualSubsystem() } // Syncer -ISyncer* CVirtualSubsystem::getSyncer() const +ISyncer *CVirtualSubsystem::getSyncer() const { return _pVirtualSyncer; } -// From IMapper -bool CVirtualSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, string& strError) +void CVirtualSubsystem::fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const { - (void)pInstanceConfigurableElement; - (void)strError; + syncerSet += _pVirtualSyncer; +} +// From IMapper +bool CVirtualSubsystem::mapBegin(CInstanceConfigurableElement * /*elem*/, bool &bKeepDiving, + string & /*strError*/) +{ // Do nothing: prevent any subsystem object from being mapped // Stop diving diff --git a/parameter/VirtualSubsystem.h b/parameter/VirtualSubsystem.h index 3a9c89b..8590361 100644 --- a/parameter/VirtualSubsystem.h +++ b/parameter/VirtualSubsystem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -35,21 +35,34 @@ class CVirtualSyncer; -class CVirtualSubsystem : public CSubsystem +class CVirtualSubsystem final : public CSubsystem { public: - CVirtualSubsystem(const std::string& strName); + /** + * @param[in] strName subsystem name + * @param[in] logger the main logger of the application + */ + CVirtualSubsystem(const std::string &strName, core::log::Logger &logger); virtual ~CVirtualSubsystem(); protected: // Syncer - virtual ISyncer* getSyncer() const; + virtual ISyncer *getSyncer() const; + + /** + * Fill Syncer Set From descendant nodes + * + * This functionality allows to collect the syncers when crawling down the + * parameter tree. + */ + void fillSyncerSetFromDescendant(CSyncerSet &syncerSet) const override; private: // From IMapper - virtual bool mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, std::string& strError); + virtual bool mapBegin(CInstanceConfigurableElement *pInstanceConfigurableElement, + bool &bKeepDiving, std::string &strError); virtual void mapEnd(); // Subsystem level dummy syncer - CVirtualSyncer* _pVirtualSyncer; + CVirtualSyncer *_pVirtualSyncer; }; diff --git a/parameter/VirtualSyncer.cpp b/parameter/VirtualSyncer.cpp index 5ab889f..5bb8ef4 100644 --- a/parameter/VirtualSyncer.cpp +++ b/parameter/VirtualSyncer.cpp @@ -33,17 +33,18 @@ using std::string; -CVirtualSyncer::CVirtualSyncer(const CConfigurableElement* pConfigurableElement) : _pConfigurableElement(pConfigurableElement) +CVirtualSyncer::CVirtualSyncer(const CConfigurableElement *pConfigurableElement) + : _pConfigurableElement(pConfigurableElement) { } // Synchronization -bool CVirtualSyncer::sync(CParameterBlackboard& parameterBlackboard, bool bBack, string& strError) +bool CVirtualSyncer::sync(CParameterBlackboard ¶meterBlackboard, bool bBack, string &strError) { // Synchronize to/from HW if (bBack) { // Create access context - CParameterAccessContext parameterAccessContext(strError, ¶meterBlackboard, false); + CParameterAccessContext parameterAccessContext(strError, ¶meterBlackboard); // Just implement back synchronization with default values _pConfigurableElement->setDefaultValues(parameterAccessContext); diff --git a/parameter/VirtualSyncer.h b/parameter/VirtualSyncer.h index 30254cb..3942678 100644 --- a/parameter/VirtualSyncer.h +++ b/parameter/VirtualSyncer.h @@ -36,10 +36,11 @@ class CConfigurableElement; class CVirtualSyncer : public ISyncer { public: - CVirtualSyncer(const CConfigurableElement* pConfigurableElement); + CVirtualSyncer(const CConfigurableElement *pConfigurableElement); // from ISyncer - virtual bool sync(CParameterBlackboard& parameterBlackboard, bool bBack, std::string& strError); + virtual bool sync(CParameterBlackboard ¶meterBlackboard, bool bBack, std::string &strError); + private: - const CConfigurableElement* _pConfigurableElement; + const CConfigurableElement *_pConfigurableElement; }; diff --git a/parameter/XmlDomainExportContext.h b/parameter/XmlDomainExportContext.h index 22ad995..02a517e 100644 --- a/parameter/XmlDomainExportContext.h +++ b/parameter/XmlDomainExportContext.h @@ -35,36 +35,22 @@ class CXmlDomainExportContext : public CXmlDomainSerializingContext { public: - CXmlDomainExportContext(std::string& strError, - bool bWithSettings = true, - bool bValueSpaceIsRaw = true, - bool bOutputRawFormatIsHex = true): - base(strError, bWithSettings), - _bValueSpaceIsRaw(bValueSpaceIsRaw), - _bOutputRawFormatIsHex(bOutputRawFormatIsHex) - {} - - // Value interpretation as Real or Raw - void setValueSpaceRaw(bool bIsRaw) + CXmlDomainExportContext(std::string &strError, bool bWithSettings = true, + bool bValueSpaceIsRaw = true, bool bOutputRawFormatIsHex = true) + : base(strError, bWithSettings), _bValueSpaceIsRaw(bValueSpaceIsRaw), + _bOutputRawFormatIsHex(bOutputRawFormatIsHex) { - _bValueSpaceIsRaw = bIsRaw; } - bool valueSpaceIsRaw() const - { - return _bValueSpaceIsRaw; - } + // Value interpretation as Real or Raw + void setValueSpaceRaw(bool bIsRaw) { _bValueSpaceIsRaw = bIsRaw; } + + bool valueSpaceIsRaw() const { return _bValueSpaceIsRaw; } // Output Raw Format for user get value interpretation - void setOutputRawFormat(bool bIsHex) - { - _bOutputRawFormatIsHex = bIsHex; - } + void setOutputRawFormat(bool bIsHex) { _bOutputRawFormatIsHex = bIsHex; } - bool outputRawFormatIsHex() const - { - return _bOutputRawFormatIsHex; - } + bool outputRawFormatIsHex() const { return _bOutputRawFormatIsHex; } private: typedef CXmlDomainSerializingContext base; @@ -74,5 +60,4 @@ private: // Output Raw Format bool _bOutputRawFormatIsHex; - }; diff --git a/parameter/XmlDomainImportContext.h b/parameter/XmlDomainImportContext.h index 11090b0..17404f1 100644 --- a/parameter/XmlDomainImportContext.h +++ b/parameter/XmlDomainImportContext.h @@ -38,23 +38,22 @@ class CXmlDomainImportContext : public CXmlDomainSerializingContext { public: - CXmlDomainImportContext(std::string& strError, bool bWithSettings, CSystemClass& systemClass): - base(strError, bWithSettings), _systemClass(systemClass), _bAutoValidationRequired(true) {} - - // System Class - CSystemClass& getSystemClass() const + CXmlDomainImportContext(std::string &strError, bool bWithSettings, CSystemClass &systemClass) + : base(strError, bWithSettings), _systemClass(systemClass) { - return _systemClass; } + // System Class + CSystemClass &getSystemClass() const { return _systemClass; } + // Criteria defintion void setSelectionCriteriaDefinition( - const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition) + const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition) { _pSelectionCriteriaDefinition = pSelectionCriteriaDefinition; } - const CSelectionCriteriaDefinition* getSelectionCriteriaDefinition() const + const CSelectionCriteriaDefinition *getSelectionCriteriaDefinition() const { return _pSelectionCriteriaDefinition; } @@ -65,21 +64,17 @@ public: _bAutoValidationRequired = bAutoValidationRequired; } - bool autoValidationRequired() const - { - return _bAutoValidationRequired; - } + bool autoValidationRequired() const { return _bAutoValidationRequired; } private: typedef CXmlDomainSerializingContext base; // System Class - CSystemClass& _systemClass; + CSystemClass &_systemClass; // Criteria defintion - const CSelectionCriteriaDefinition* _pSelectionCriteriaDefinition; + const CSelectionCriteriaDefinition *_pSelectionCriteriaDefinition{nullptr}; // Auto validation of configurations - bool _bAutoValidationRequired; + bool _bAutoValidationRequired{true}; }; - diff --git a/parameter/XmlDomainSerializingContext.h b/parameter/XmlDomainSerializingContext.h index 955d939..49c2733 100644 --- a/parameter/XmlDomainSerializingContext.h +++ b/parameter/XmlDomainSerializingContext.h @@ -36,15 +36,14 @@ class CXmlDomainSerializingContext : public CXmlElementSerializingContext { public: - CXmlDomainSerializingContext(std::string& strError, bool bWithSettings): - base(strError), _bWithSettings(bWithSettings) {} - - // Settings to be serialized or not - bool withSettings() const + CXmlDomainSerializingContext(std::string &strError, bool bWithSettings) + : base(strError), _bWithSettings(bWithSettings) { - return _bWithSettings; } + // Settings to be serialized or not + bool withSettings() const { return _bWithSettings; } + private: typedef CXmlElementSerializingContext base; diff --git a/parameter/XmlElementSerializingContext.cpp b/parameter/XmlElementSerializingContext.cpp index 6046d8e..491f160 100644 --- a/parameter/XmlElementSerializingContext.cpp +++ b/parameter/XmlElementSerializingContext.cpp @@ -28,39 +28,31 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "XmlElementSerializingContext.h" -#include <stdlib.h> #define base CXmlSerializingContext using std::string; -CXmlElementSerializingContext::CXmlElementSerializingContext(string& strError) : base(strError), _pElementLibrary(NULL) +CXmlElementSerializingContext::CXmlElementSerializingContext(string &strError) : base(strError) { } // Init -void CXmlElementSerializingContext::set(const CElementLibrary* pElementLibrary, const string& strXmlFolder, const string& strXmlSchemaFolder) +void CXmlElementSerializingContext::set(const CElementLibrary *pElementLibrary, + const string &xmlUri) { _pElementLibrary = pElementLibrary; - _strXmlFolder = strXmlFolder; - _strXmlSchemaFolder = strXmlSchemaFolder; + _xmlUri = xmlUri; } // ElementLibrary -const CElementLibrary* CXmlElementSerializingContext::getElementLibrary() const +const CElementLibrary *CXmlElementSerializingContext::getElementLibrary() const { return _pElementLibrary; } // XML Folder Path -const string& CXmlElementSerializingContext::getXmlFolder() const +const string &CXmlElementSerializingContext::getXmlUri() const { - return _strXmlFolder; + return _xmlUri; } - -// XML Schema Path -const string& CXmlElementSerializingContext::getXmlSchemaPathFolder() const -{ - return _strXmlSchemaFolder; -} - diff --git a/parameter/XmlElementSerializingContext.h b/parameter/XmlElementSerializingContext.h index dadb1da..3169d40 100644 --- a/parameter/XmlElementSerializingContext.h +++ b/parameter/XmlElementSerializingContext.h @@ -38,21 +38,18 @@ class CElementLibrary; class CXmlElementSerializingContext : public CXmlSerializingContext { public: - CXmlElementSerializingContext(std::string& strError); + CXmlElementSerializingContext(std::string &strError); // Init - void set(const CElementLibrary* pElementLibrary, const std::string& strXmlFolder, const std::string& strXmlSchemaFolder); + void set(const CElementLibrary *pElementLibrary, const std::string &xmlUri); // ElementLibrary - const CElementLibrary* getElementLibrary() const; + const CElementLibrary *getElementLibrary() const; - // XML File Path - const std::string& getXmlFolder() const; + // Xml URI + const std::string &getXmlUri() const; - // Schema Path - const std::string& getXmlSchemaPathFolder() const; private: - const CElementLibrary* _pElementLibrary; - std::string _strXmlFolder; - std::string _strXmlSchemaFolder; + const CElementLibrary *_pElementLibrary{nullptr}; + std::string _xmlUri; }; diff --git a/parameter/XmlFileIncluderElement.cpp b/parameter/XmlFileIncluderElement.cpp index d20a624..b736a24 100644 --- a/parameter/XmlFileIncluderElement.cpp +++ b/parameter/XmlFileIncluderElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -32,54 +32,43 @@ #include "XmlMemoryDocSink.h" #include "XmlElementSerializingContext.h" #include "ElementLibrary.h" -#include "AutoLog.h" #include <assert.h> #include <fstream> #define base CKindElement -CXmlFileIncluderElement::CXmlFileIncluderElement(const std::string& strName, - const std::string& strKind, - bool bValidateWithSchemas) - : base(strName, strKind), _bValidateSchemasOnStart(bValidateWithSchemas) +CXmlFileIncluderElement::CXmlFileIncluderElement(const std::string &strName, + const std::string &strKind, + bool bValidateWithSchemas, + const std::string &schemaBaseUri) + : base(strName, strKind), _bValidateSchemasOnStart(bValidateWithSchemas), + _schemaBaseUri(schemaBaseUri) { } // From IXmlSink -bool CXmlFileIncluderElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) +bool CXmlFileIncluderElement::fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) { // Context - CXmlElementSerializingContext& elementSerializingContext = static_cast<CXmlElementSerializingContext&>(serializingContext); + CXmlElementSerializingContext &elementSerializingContext = + static_cast<CXmlElementSerializingContext &>(serializingContext); // Parse included document - std::string strPath = xmlElement.getAttributeString("Path"); - - // Relative path? - if (strPath[0] != '/') { - - strPath = elementSerializingContext.getXmlFolder() + "/" + strPath; - } + std::string strPath; + xmlElement.getAttribute("Path", strPath); + strPath = CXmlDocSource::mkUri(elementSerializingContext.getXmlUri(), strPath); // Instantiate parser std::string strIncludedElementType = getIncludedElementType(); { - // Open a log section titled with loading file path - CAutoLog autolog(this, "Loading " + strPath); + _xmlDoc *doc = CXmlDocSource::mkXmlDoc(strPath, true, true, elementSerializingContext); - // Use a doc source that load data from a file - std::string strPathToXsdFile = elementSerializingContext.getXmlSchemaPathFolder() + "/" + - strIncludedElementType + ".xsd"; + CXmlDocSource docSource(doc, _bValidateSchemasOnStart, strIncludedElementType); - std::string xmlErrorMsg; - _xmlDoc *doc = CXmlDocSource::mkXmlDoc(strPath, true, true, xmlErrorMsg); - if (doc == NULL) { - elementSerializingContext.setError(xmlErrorMsg); - return false; + if (not _schemaBaseUri.empty()) { + docSource.setSchemaBaseUri(_schemaBaseUri); } - CXmlDocSource docSource(doc, _bValidateSchemasOnStart, - strPathToXsdFile, - strIncludedElementType); - if (!docSource.isParsable()) { elementSerializingContext.setError("Could not parse document \"" + strPath + "\""); @@ -93,7 +82,8 @@ bool CXmlFileIncluderElement::fromXml(const CXmlElement& xmlElement, CXmlSeriali docSource.getRootElement(childElement); // Create child element - CElement* pChild = elementSerializingContext.getElementLibrary()->createElement(childElement); + CElement *pChild = + elementSerializingContext.getElementLibrary()->createElement(childElement); if (pChild) { @@ -101,7 +91,8 @@ bool CXmlFileIncluderElement::fromXml(const CXmlElement& xmlElement, CXmlSeriali getParent()->addChild(pChild); } else { - elementSerializingContext.setError("Unable to create XML element " + childElement.getPath()); + elementSerializingContext.setError("Unable to create XML element " + + childElement.getPath()); return false; } diff --git a/parameter/XmlFileIncluderElement.h b/parameter/XmlFileIncluderElement.h index 9163356..144e078 100644 --- a/parameter/XmlFileIncluderElement.h +++ b/parameter/XmlFileIncluderElement.h @@ -37,13 +37,14 @@ class CXmlFileIncluderElement : public CKindElement { public: - CXmlFileIncluderElement(const std::string& strName, - const std::string& strKind, - bool bValidateWithSchemas); + CXmlFileIncluderElement(const std::string &strName, const std::string &strKind, + bool bValidateWithSchemas, const std::string &schemaBaseUri); // From IXmlSink - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + virtual bool fromXml(const CXmlElement &xmlElement, CXmlSerializingContext &serializingContext); + private: // Element type std::string getIncludedElementType() const; bool _bValidateSchemasOnStart; + const std::string _schemaBaseUri; }; diff --git a/parameter/XmlParameterSerializingContext.cpp b/parameter/XmlParameterSerializingContext.cpp index 12de305..c13c5ae 100644 --- a/parameter/XmlParameterSerializingContext.cpp +++ b/parameter/XmlParameterSerializingContext.cpp @@ -33,19 +33,20 @@ using std::string; -CXmlParameterSerializingContext::CXmlParameterSerializingContext(string& strError) : base(strError) +CXmlParameterSerializingContext::CXmlParameterSerializingContext(CParameterAccessContext &context, + string &strError) + : base(strError), mAccessContext(context) { } // ComponentLibrary -void CXmlParameterSerializingContext::setComponentLibrary(const CComponentLibrary* pComponentLibrary) +void CXmlParameterSerializingContext::setComponentLibrary( + const CComponentLibrary *pComponentLibrary) { _pComponentLibrary = pComponentLibrary; } -const CComponentLibrary* CXmlParameterSerializingContext::getComponentLibrary() const +const CComponentLibrary *CXmlParameterSerializingContext::getComponentLibrary() const { return _pComponentLibrary; } - - diff --git a/parameter/XmlParameterSerializingContext.h b/parameter/XmlParameterSerializingContext.h index 61306ce..05d5a9b 100644 --- a/parameter/XmlParameterSerializingContext.h +++ b/parameter/XmlParameterSerializingContext.h @@ -30,6 +30,7 @@ #pragma once #include "XmlElementSerializingContext.h" +#include "ParameterAccessContext.h" #include <string> @@ -38,11 +39,16 @@ class CComponentLibrary; class CXmlParameterSerializingContext : public CXmlElementSerializingContext { public: - CXmlParameterSerializingContext(std::string& strError); + CXmlParameterSerializingContext(CParameterAccessContext &context, std::string &strError); // ComponentLibrary - void setComponentLibrary(const CComponentLibrary* pComponentLibrary); - const CComponentLibrary* getComponentLibrary() const; + void setComponentLibrary(const CComponentLibrary *pComponentLibrary); + const CComponentLibrary *getComponentLibrary() const; + + CParameterAccessContext &getAccessContext() const { return mAccessContext; } + private: - const CComponentLibrary* _pComponentLibrary; + const CComponentLibrary *_pComponentLibrary{nullptr}; + + CParameterAccessContext &mAccessContext; }; diff --git a/utility/NaiveTokenizer.h b/parameter/include/CommandHandlerInterface.h index 67abc9a..50b7343 100644 --- a/utility/NaiveTokenizer.h +++ b/parameter/include/CommandHandlerInterface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,23 +27,41 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #pragma once -class NaiveTokenizer { +#include <string> +#include <vector> + +/** Class used to send commands to a parameter framework. + * @see the help command for more information on which command can be sent. + * @see ParameterMgrFullConnector::createCommandHandler to create an instance. + * + * This interface is primary designed to send commands without using a + * tcp socket for test purposes. + * + * Note: the fact that this class must be deleted by the client is because the + * PF interface is not c++11. + * TODO: When the interface will transition to C++11, return directly the + * CommandHandlerWrapper as this base class only use is to hide the + * move semantic that is not supported in C++03. + */ +class CommandHandlerInterface +{ public: - /** tokenize a space-separated string, handling quotes + /** Send a command synchronously and receive it's result. * - * The input is tokenized, using " " (space) as the tokenizer; multiple - * spaces are regarded as a single separator. If the input begins with a - * quote (either single (') or double (")), the next token will be all the - * characters (including spaces) until the next identical quote. - * Warning: This function modifies its argument in-place ! + * @see CParameterMgr::gastRemoteCommandParserItems for the list of possible + * command and their description. * - * It aims at reproducing the parsing of a shell. + * @param[in] command the command to execute. + * @param[in] arguments the command arguments. + * @param[out] output the result of the command. * - * @param[inout] line The string to be tokenized. Warning: modified in-place - * @return Pointer to the next token (which is actually the original value of 'line' + * return true in the command executed succesfuly, + * false otherwise. */ - static char* getNextToken(char** line); + virtual bool process(const std::string &command, const std::vector<std::string> &arguments, + std::string &output) = 0; + + virtual ~CommandHandlerInterface(){}; }; diff --git a/parameter/include/ElementHandle.h b/parameter/include/ElementHandle.h new file mode 100644 index 0000000..7d0888a --- /dev/null +++ b/parameter/include/ElementHandle.h @@ -0,0 +1,265 @@ +/* + * 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. + */ +#pragma once + +#include "parameter_export.h" + +#include <stdint.h> +#include <string> +#include <vector> + +/** Forward declaration of private classes. + * Client should not use those class. + * They are not part of the public api and may be remove/renamed in any release. + * @{ + */ +class CParameterMgr; +class CConfigurableElement; +class CBaseParameter; +/** @} */ + +/** TODO */ +class PARAMETER_EXPORT ElementHandle +{ +public: + /** @return element's name. */ + std::string getName() const; + + /** @return element's size in bytes. + * + * If the element size in bit is not a multiple of CHAR_BIT (8) + * it is rounded to the upper multiple. + * Effectively returning the element memory footprint. + */ + size_t getSize() const; + + /** @return true if the element is a parameter, false otherwise. */ + bool isParameter() const; + + /** @return a human readable description of the element. */ + std::string getDescription() const; + + /** @return is the element and all its descendant not in a domain. + * + * Only rogue elements are allowed to be set. + * */ + bool isRogue() const; + + /** @return true if the element is an array, false otherwise.*/ + bool isArray() const; + + /** @return the parameter array length. + * 0 if the element is not an array (scalar). + */ + size_t getArrayLength() const; + + /** @return element's path in the parameter hierarchy tree. */ + std::string getPath() const; + + /** @return element's kind. + * + * Ie: a string identifying the type of Element. + */ + std::string getKind() const; + + std::vector<ElementHandle> getChildren(); + + /** Get mapping data of the element context + * + * Retrieve mapping data associated to a given key if any. + * If the key is not present in this element, query ancestors. + * + * @param[in] strKey the input mapping key + * @param[out] strValue the resulting mapping value in case of success + * @return true for if mapping key exists, false otherwise + */ + bool getMappingData(const std::string &strKey, std::string &strValue) const; + + /** Gets element structure description as XML string + * + * @return the output XML string + */ + bool getStructureAsXML(std::string &xmlStructure, std::string &error) const; + + /** Gets element settings as XML string + * + * @param[out] xmlValue the values to get + * @param[out] error On failure (false returned) will contain a human + * readable description of the error. + * On success (true returned) the content is not + * specified. + * + * @note returned value format depends on the current ParameterMgr format + * control properties, including value space and output raw format. + * @see ParameterMgrPlatformConnector::setOutputRawFormat + * @see ParameterMgrPlatformConnector::setValueSpace + * + * @return true on success, false on failure + */ + bool getAsXML(std::string &xmlValue, std::string &error) const; + + /** Sets element settings as XML string + * + * @param[in] xmlValue the values to set + * @param[out] error On failure (false returned) will contain a human + * readable description of the error. + * On success (true returned) the content is not + * specified. + * + * @note + * - targeted element needs to be rogue for this operation to be allowed + * - structure of the passed XML element must match the targeted + * configurable element's one otherwise this operation will fail + * - expected value format depends on current value space. + * @see ParameterMgrPlatformConnector::valueSpaceIsRaw + * + * @return true on success, false otherwise + */ + bool setAsXML(const std::string &xmlValue, std::string &error); + + /** Gets element settings in binary format + * + * @param[out] bytesValue the output vector + * @param[out] error unused + * + * @returns true + */ + bool getAsBytes(std::vector<uint8_t> &bytesValue, std::string &error) const; + + /** Sets element settings in binary format + * + * @param[out] bytesValue the output vector + * @param[out] error On failure (false returned) will contain a human + * readable description of the error. + * On success (true returned) the content is not + * specified. + * + * @note + * - targeted element needs to be rogue for this operation to be allowed + * - size of the passed array must match that of the element + */ + bool setAsBytes(const std::vector<uint8_t> &bytesValue, std::string &error); + + /** Access (get or set) parameters as different types. + * + * Will fail if the element is not a paramete. + * Array access will fail if the parameter is not an array. + * + * @param value if get, the value to get (in parameter) + * if set, the value to set (out parameter) + * + * Setting an array requires the std::vector size to match the arrayLength. + * Ie: value.size() == arrayLength() + * + * @param[out] error On failure (false returned) will contain a human + * readable description of the error. + * On success (true returned) the content is not + * specified. + * @return true if the access was successful, + * false otherwise (see error for the detail) + * @{ + */ + + /** Boolean access @{ */ + bool getAsBoolean(bool &value, std::string &error) const; + bool setAsBoolean(bool value, std::string &error); + bool setAsBooleanArray(const std::vector<bool> &value, std::string &error); + bool getAsBooleanArray(std::vector<bool> &value, std::string &error) const; + /** @} */ + + /** Integer Access @{ */ + bool setAsInteger(uint32_t value, std::string &error); + bool getAsInteger(uint32_t &value, std::string &error) const; + bool setAsIntegerArray(const std::vector<uint32_t> &value, std::string &error); + bool getAsIntegerArray(std::vector<uint32_t> &value, std::string &error) const; + /** @} */ + + /** Signed Integer Access @{ */ + bool setAsSignedInteger(int32_t value, std::string &error); + bool getAsSignedInteger(int32_t &value, std::string &error) const; + bool setAsSignedIntegerArray(const std::vector<int32_t> &value, std::string &error); + bool getAsSignedIntegerArray(std::vector<int32_t> &value, std::string &error) const; + /** @} */ + + /** Double Access @{ */ + bool setAsDouble(double value, std::string &error); + bool getAsDouble(double &value, std::string &error) const; + bool setAsDoubleArray(const std::vector<double> &value, std::string &error); + bool getAsDoubleArray(std::vector<double> &value, std::string &error) const; + /** @} */ + + /** String Access @{ */ + bool setAsString(const std::string &value, std::string &error); + bool getAsString(std::string &value, std::string &error) const; + bool setAsStringArray(const std::vector<std::string> &value, std::string &error); + bool getAsStringArray(std::vector<std::string> &value, std::string &error) const; + /** @} */ + + /** @} */ + +protected: + ElementHandle(CConfigurableElement &element, CParameterMgr ¶meterMgr); + friend CParameterMgr; // So that it can build the handler + +private: + template <class T> + bool setAs(const T value, std::string &error) const; + template <class T> + bool getAs(T &value, std::string &error) const; + + CBaseParameter &getParameter(); + const CBaseParameter &getParameter() const; + + /** Check that the parameter value can be modify. + * + * @param arrayLength[in] If accessing as an array: the new value array length + * Otherwise: 0 + * @param error[out] If access is forbidden: a human readable message explaining why + * Otherwise: not modified. + * + * @return true if the parameter value can be retrieved, false otherwise. + */ + bool checkSetValidity(size_t arrayLength, std::string &error) const; + + /** Check that the parameter value can be retrieved. + * + * @param asArray[in] true if accessing as an array, false otherwise. + * @param error[out] If access is forbidden, a human readable message explaining why + * Otherwise, not modified. + * + * @return true if the parameter value can be retrieved, false otherwise. + */ + bool checkGetValidity(bool asArray, std::string &error) const; + + /** Reference to the handled Configurable element. */ + CConfigurableElement &mElement; + + CParameterMgr &mParameterMgr; +}; diff --git a/parameter/include/ParameterHandle.h b/parameter/include/ParameterHandle.h index 7dd9fcb..75f28e2 100644 --- a/parameter/include/ParameterHandle.h +++ b/parameter/include/ParameterHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,75 +29,25 @@ */ #pragma once -#include <stdint.h> -#include <string> -#include <vector> +#include "parameter_export.h" -class CBaseParameter; -class CParameterMgr; +#include "ElementHandle.h" -class CParameterHandle +/** Pre v3.1 Handle to a parameter. Kept for retro-compatibility. + * @deprecated This class has been deprecated in favor of ElementHandle, + * Use ElementHandle instead of CParameterHandle. + * It is a api retro-compatible superset of the pre v3.1 + * CParameterHandle class. + * @note Achieve retro-compatibility with a derived class instead of an alias + * (`typedef ElementHandle CParameterHandle`) as the later would break + * client compilation in case of client forward declaration. + */ +class PARAMETER_EXPORT CParameterHandle : public ElementHandle { -public: - CParameterHandle(const CBaseParameter* pParameter, CParameterMgr* pParameterMgr); - - // Parameter features - bool isRogue() const; - bool isArray() const; - // Array Length - uint32_t getArrayLength() const; // Returns 0 for scalar - // Parameter path - std::string getPath() const; - // Parameter kind - std::string getKind() const; - - // Boolean access - bool setAsBoolean(bool bValue, std::string& strError); - - /** - * Fetch the parameter value as a boolean. - * - * @param bValue Reference to a boolean variable where the value will be stored - * @param strError Error message if a problem occured - * - * @return true on success, false otherwise - */ - bool getAsBoolean(bool& bValue, std::string& strError) const; - bool setAsBooleanArray(const std::vector<bool>& abValues, std::string& strError); - bool getAsBooleanArray(std::vector<bool>& abValues, std::string& strError) const; - - // Integer Access - bool setAsInteger(uint32_t uiValue, std::string& strError); - bool getAsInteger(uint32_t& uiValue, std::string& strError) const; - bool setAsIntegerArray(const std::vector<uint32_t>& auiValues, std::string& strError); - bool getAsIntegerArray(std::vector<uint32_t>& auiValues, std::string& strError) const; - - // Signed Integer Access - bool setAsSignedInteger(int32_t iValue, std::string& strError); - bool getAsSignedInteger(int32_t& iValue, std::string& strError) const; - bool setAsSignedIntegerArray(const std::vector<int32_t>& aiValues, std::string& strError); - bool getAsSignedIntegerArray(std::vector<int32_t>& aiValues, std::string& strError) const; - - // Double Access - bool setAsDouble(double dValue, std::string& strError); - bool getAsDouble(double& dValue, std::string& strError) const; - bool setAsDoubleArray(const std::vector<double>& adValues, std::string& strError); - bool getAsDoubleArray(std::vector<double>& adValues, std::string& strError) const; - - // String Access - bool setAsString(const std::string& strValue, std::string& strError); - bool getAsString(std::string& strValue, std::string& strError) const; - bool setAsStringArray(const std::vector<std::string>& astrValues, std::string& strError); - bool getAsStringArray(std::vector<std::string>& astrValues, std::string& strError) const; - private: - // Access validity - bool checkAccessValidity(bool bSet, size_t uiArrayLength, std::string& strError) const; - - // Accessed parameter instance - const CBaseParameter* _pBaseParameter; - // Parameter Mgr - CParameterMgr* _pParameterMgr; - // Subsystem endianness - bool _bBigEndianSubsystem; + CParameterHandle(CConfigurableElement &element, CParameterMgr ¶meterMgr) + : ElementHandle(element, parameterMgr) + { + } + friend CParameterMgr; // So that it can build the handler }; diff --git a/parameter/include/ParameterMgrFullConnector.h b/parameter/include/ParameterMgrFullConnector.h index 4ee3b4f..c8c8d6e 100644 --- a/parameter/include/ParameterMgrFullConnector.h +++ b/parameter/include/ParameterMgrFullConnector.h @@ -29,10 +29,14 @@ */ #pragma once +#include "parameter_export.h" + #include "SelectionCriterionTypeInterface.h" #include "SelectionCriterionInterface.h" #include "ParameterHandle.h" #include "ParameterMgrLoggerForward.h" +#include "ParameterMgrPlatformConnector.h" +#include "CommandHandlerInterface.h" #include <string> #include <list> @@ -41,108 +45,48 @@ class CParameterMgr; -class CParameterMgrFullConnector +/** @note Since only C++11 components use this interface + * (contrary to the more restricted CParameterMgrPlatformConnector), + * could this api not be transition to c++11 ? + */ +class PARAMETER_EXPORT CParameterMgrFullConnector : public CParameterMgrPlatformConnector { - friend class CParameterMgrLogger<CParameterMgrFullConnector>; - public: - CParameterMgrFullConnector(const std::string& strConfigurationFilePath); - ~CParameterMgrFullConnector(); - - class ILogger - { - public: - virtual void log(bool bIsWarning, const std::string& strLog) = 0; - protected: - virtual ~ILogger() {} - }; - // Logging - /** Should be called before start */ - void setLogger(ILogger* pLogger); - + /** String list type which can hold list of error/info and can be presented to client */ + typedef std::list<std::string> Results; - bool start(std::string& strError); + CParameterMgrFullConnector(const std::string &strConfigurationFilePath); - // Dynamic parameter handling - CParameterHandle* createParameterHandle(const std::string& strPath, std::string& strError); - - ISelectionCriterionTypeInterface* createSelectionCriterionType(bool bIsInclusive); - ISelectionCriterionInterface* createSelectionCriterion(const std::string& strName, - const ISelectionCriterionTypeInterface* pSelectionCriterionType); - ISelectionCriterionInterface* getSelectionCriterion(const std::string& strName); - - /** Is the remote interface forcefully disabled ? - */ - bool getForceNoRemoteInterface() const; - - /** - * Forcefully disable the remote interface or cancel this policy. + /** Create and return a command handler for this ParameterMgr instance * - * Has no effect if called after calling start(). + * The caller owns the returned pointer and is responsible for deleting it + * before destroying the Connector object. * - * @param[in] bForceNoRemoteInterface disable the remote interface if true. + * @returns a Command Handler */ - void setForceNoRemoteInterface(bool bForceNoRemoteInterface); + CommandHandlerInterface *createCommandHandler(); - void applyConfigurations(); - - /** Should start fail in case of missing subsystems. - * - * @param[in] bFail: If set to true, parameterMgr start will fail on missing subsystems. - * If set to false, missing subsystems will fallback on virtual subsystem. - */ - void setFailureOnMissingSubsystem(bool bFail); - - /** Would start fail in case of missing subsystems. - * - * @return true if the subsystem will fail on missing subsystem, false otherwise. - */ - bool getFailureOnMissingSubsystem() const; - - /** Should start fail in failed settings load. - * - * @param[in] bFail: If set to true, parameterMgr start will fail on failed settings load. - * If set to false, failed settings load will be ignored. - */ - void setFailureOnFailedSettingsLoad(bool bFail); - /** Would start fail in case of failed settings load. - * - * @return failure on failed settings load policy state. - */ - bool getFailureOnFailedSettingsLoad(); - - /** Get the path to the directory containing the XML Schemas - * - * @returns the directory containing the XML Schemas + /** @deprecated Same as its overload without error handling. + * @note this deprecated method in not available in the python wrapper. */ - const std::string& getSchemaFolderLocation() const; + void setFailureOnMissingSubsystem(bool bFail); + using CParameterMgrPlatformConnector::setFailureOnMissingSubsystem; - /** Override the directory containing the XML Schemas - * - * @param[in] strSchemaFolderLocation directory containing the XML Schemas + /** @deprecated Same as its overload without error handling. + * @note this deprecated method in not available in the python wrapper. */ - void setSchemaFolderLocation(const std::string& strSchemaFolderLocation); + void setFailureOnFailedSettingsLoad(bool bFail); + using CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad; - /** Should .xml files be validated on start ? - * - * @param[in] bValidate: - * If set to true, parameterMgr will report an error - * when being unable to validate .xml files - * If set to false, no .xml/xsd validation will happen - * (default behaviour) - * - * @return false if unable to set, true otherwise. + /** @deprecated Same as its overload without error handling. + * @note this deprecated method in not available in the python wrapper. */ void setValidateSchemasOnStart(bool bValidate); + using CParameterMgrPlatformConnector::setValidateSchemasOnStart; - /** Would .xml files be validated on start? - * - * @return areSchemasValidated - */ - bool getValidateSchemasOnStart() const; //////////// Tuning ///////////// // Tuning mode - bool setTuningMode(bool bOn, std::string& strError); + bool setTuningMode(bool bOn, std::string &strError); bool isTuningModeOn() const; // Current value space for user set/get value interpretation @@ -153,13 +97,16 @@ public: void setOutputRawFormat(bool bIsHex); bool isOutputRawFormatHex() const; // Automatic hardware synchronization control (during tuning session) - bool setAutoSync(bool bAutoSyncOn, std::string& strError); + bool setAutoSync(bool bAutoSyncOn, std::string &strError); bool isAutoSyncOn() const; - bool sync(std::string& strError); + bool sync(std::string &strError); // User set/get parameters - bool accessParameterValue(const std::string& strPath, std::string& strValue, bool bSet, std::string& strError); - bool accessConfigurationValue(const std::string &strDomain, const std::string &strConfiguration, const std::string& strPath, std::string& strValue, bool bSet, std::string& strError); + bool accessParameterValue(const std::string &strPath, std::string &strValue, bool bSet, + std::string &strError); + bool accessConfigurationValue(const std::string &strDomain, const std::string &strConfiguration, + const std::string &strPath, std::string &strValue, bool bSet, + std::string &strError); /** * Returns the element mapping corresponding to the path given in parameter. @@ -169,34 +116,57 @@ public: * * @return true if a mapping was found for this element */ - bool getParameterMapping(const std::string& strPath, std::string& strValue) const; + bool getParameterMapping(const std::string &strPath, std::string &strValue) const; ////////// Configuration/Domains handling ////////////// // Creation/Deletion - bool createDomain(const std::string& strName, std::string& strError); - bool deleteDomain(const std::string& strName, std::string& strError); - bool renameDomain(const std::string& strName, const std::string& strNewName, std::string& strError); - bool deleteAllDomains(std::string& strError); - bool setSequenceAwareness(const std::string& strName, bool bSequenceAware, std::string& strResult); - bool getSequenceAwareness(const std::string& strName, bool& bSequenceAware, std::string& strResult); - bool createConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); - bool deleteConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); - bool renameConfiguration(const std::string& strDomain, const std::string& strConfiguration, const std::string& strNewConfiguration, std::string& strError); + bool createDomain(const std::string &strName, std::string &strError); + bool deleteDomain(const std::string &strName, std::string &strError); + bool renameDomain(const std::string &strName, const std::string &strNewName, + std::string &strError); + bool deleteAllDomains(std::string &strError); + bool setSequenceAwareness(const std::string &strName, bool bSequenceAware, + std::string &strResult); + bool getSequenceAwareness(const std::string &strName, bool &bSequenceAware, + std::string &strResult); + bool createConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); + bool deleteConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); + bool renameConfiguration(const std::string &strDomain, const std::string &strConfiguration, + const std::string &strNewConfiguration, std::string &strError); + + /** Restore a configuration + * + * @param[in] strDomain the domain name + * @param[in] strConfiguration the configuration name + * @param[out] errors, errors encountered during restoration + * @return true if success false otherwise + */ + bool restoreConfiguration(const std::string &strDomain, const std::string &strConfiguration, + Results &errors); - // Save/Restore - bool restoreConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::list<std::string>& strError); - bool saveConfiguration(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); + bool saveConfiguration(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); // Configurable element - domain association - bool addConfigurableElementToDomain(const std::string& strDomain, const std::string& strConfigurableElementPath, std::string& strError); - bool removeConfigurableElementFromDomain(const std::string& strDomain, const std::string& strConfigurableElementPath, std::string& strError); - bool split(const std::string& strDomain, const std::string& strConfigurableElementPath, std::string& strError); - bool setElementSequence(const std::string& strDomain, const std::string& strConfiguration, const std::vector<std::string>& astrNewElementSequence, std::string& strError); - - bool setApplicationRule(const std::string& strDomain, const std::string& strConfiguration, - const std::string& strApplicationRule, std::string& strError); - bool getApplicationRule(const std::string& strDomain, const std::string& strConfiguration, - std::string& strResult); - bool clearApplicationRule(const std::string& strDomain, const std::string& strConfiguration, std::string& strError); + bool addConfigurableElementToDomain(const std::string &strDomain, + const std::string &strConfigurableElementPath, + std::string &strError); + bool removeConfigurableElementFromDomain(const std::string &strDomain, + const std::string &strConfigurableElementPath, + std::string &strError); + bool split(const std::string &strDomain, const std::string &strConfigurableElementPath, + std::string &strError); + bool setElementSequence(const std::string &strDomain, const std::string &strConfiguration, + const std::vector<std::string> &astrNewElementSequence, + std::string &strError); + + bool setApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + const std::string &strApplicationRule, std::string &strError); + bool getApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + std::string &strResult); + bool clearApplicationRule(const std::string &strDomain, const std::string &strConfiguration, + std::string &strError); /** * Method that imports Configurable Domains from an Xml source. @@ -210,8 +180,8 @@ public: * * @return false if any error occures */ - bool importDomainsXml(const std::string& strXmlSource, bool bWithSettings, bool bFromFile, - std::string& strError); + bool importDomainsXml(const std::string &strXmlSource, bool bWithSettings, bool bFromFile, + std::string &strError); /** * Method that imports a single Configurable Domain from an Xml source. * @@ -226,8 +196,8 @@ public: * * @return false if any error occurs */ - bool importSingleDomainXml(const std::string& xmlSource, bool overwrite, bool withSettings, - bool toFile, std::string& errorMsg); + bool importSingleDomainXml(const std::string &xmlSource, bool overwrite, bool withSettings, + bool fromFile, std::string &errorMsg); /** * Method that imports a single Configurable Domain from an string * describing an Xml source. @@ -241,9 +211,8 @@ public: * * @return false if any error occurs */ - bool importSingleDomainXml(const std::string& strXmlSource, bool bOverwrite, - std::string& strError); - + bool importSingleDomainXml(const std::string &strXmlSource, bool bOverwrite, + std::string &strError); /** * Method that exports Configurable Domains to an Xml destination. @@ -257,8 +226,8 @@ public: * * @return false if any error occures, true otherwise. */ - bool exportDomainsXml(std::string& strXmlDest, bool bWithSettings, bool bToFile, - std::string& strError) const; + bool exportDomainsXml(std::string &strXmlDest, bool bWithSettings, bool bToFile, + std::string &strError) const; /** * Method that exports a given Configurable Domain to an Xml destination. @@ -273,19 +242,11 @@ public: * * @return false if any error occurs, true otherwise. */ - bool exportSingleDomainXml(std::string& strXmlDest, const std::string& strDomainName, bool bWithSettings, - bool bToFile, std::string& strError) const; + bool exportSingleDomainXml(std::string &strXmlDest, const std::string &strDomainName, + bool bWithSettings, bool bToFile, std::string &strError) const; private: // disallow copying because this class manages raw pointers' lifecycle - CParameterMgrFullConnector(const CParameterMgrFullConnector&); - CParameterMgrFullConnector& operator=(const CParameterMgrFullConnector&); - - void doLog(bool bIsWarning, const std::string& strLog); - - CParameterMgr* _pParameterMgr; - - ILogger* _pLogger; - // Log wrapper - CParameterMgrLogger<CParameterMgrFullConnector>* _pParameterMgrLogger; + CParameterMgrFullConnector(const CParameterMgrFullConnector &); + CParameterMgrFullConnector &operator=(const CParameterMgrFullConnector &); }; diff --git a/parameter/include/ParameterMgrLoggerForward.h b/parameter/include/ParameterMgrLoggerForward.h index 28b26db..ad99931 100644 --- a/parameter/include/ParameterMgrLoggerForward.h +++ b/parameter/include/ParameterMgrLoggerForward.h @@ -30,4 +30,5 @@ #pragma once // Shared forward declaration, to ensure declaration alignment -template<class T> class CParameterMgrLogger; +template <class T> +class CParameterMgrLogger; diff --git a/parameter/include/ParameterMgrPlatformConnector.h b/parameter/include/ParameterMgrPlatformConnector.h index cd99215..3df9794 100644 --- a/parameter/include/ParameterMgrPlatformConnector.h +++ b/parameter/include/ParameterMgrPlatformConnector.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,43 +29,58 @@ */ #pragma once +#include "parameter_export.h" + #include "SelectionCriterionTypeInterface.h" #include "SelectionCriterionInterface.h" #include "ParameterHandle.h" +#include "ElementHandle.h" #include "ParameterMgrLoggerForward.h" class CParameterMgr; -class CParameterMgrPlatformConnector +class PARAMETER_EXPORT CParameterMgrPlatformConnector { friend class CParameterMgrLogger<CParameterMgrPlatformConnector>; + public: - // Logger interface + /** Interface to implement to provide a custom logger to the PF. + * + * Override info and warning methods to specify how each log level + * should be printed. + * + * @note Errors are always returned synchronously. Never logged. + */ class ILogger { public: - virtual void log(bool bIsWarning, const std::string& strLog) = 0; + virtual void info(const std::string &strLog) = 0; + virtual void warning(const std::string &strLog) = 0; + protected: virtual ~ILogger() {} }; // Construction - CParameterMgrPlatformConnector(const std::string& strConfigurationFilePath); - ~CParameterMgrPlatformConnector(); // Not virtual since not supposed to be derived! + CParameterMgrPlatformConnector(const std::string &strConfigurationFilePath); + virtual ~CParameterMgrPlatformConnector(); - // Selection Criteria interface. Beware returned objects are lent, clients shall not delete them! + // Selection Criteria interface. Beware returned objects are lent, clients shall not delete + // them! // Should be called before start - ISelectionCriterionTypeInterface* createSelectionCriterionType(bool bIsInclusive = false); - ISelectionCriterionInterface* createSelectionCriterion(const std::string& strName, const ISelectionCriterionTypeInterface* pSelectionCriterionType); + ISelectionCriterionTypeInterface *createSelectionCriterionType(bool bIsInclusive = false); + ISelectionCriterionInterface *createSelectionCriterion( + const std::string &strName, + const ISelectionCriterionTypeInterface *pSelectionCriterionType); // Selection criterion retrieval - ISelectionCriterionInterface* getSelectionCriterion(const std::string& strName) const; + ISelectionCriterionInterface *getSelectionCriterion(const std::string &strName) const; // Logging // Should be called before start - void setLogger(ILogger* pLogger); + void setLogger(ILogger *pLogger); // Start - bool start(std::string& strError); + bool start(std::string &strError); // Started state bool isStarted() const; @@ -76,7 +91,21 @@ public: // Dynamic parameter handling // Returned objects are owned by clients // Must be cassed after successfull start - CParameterHandle* createParameterHandle(const std::string& strPath, std::string& strError) const; + CParameterHandle *createParameterHandle(const std::string &strPath, + std::string &strError) const; + + /** Creates a handle to a configurable element. + * + * The returned object is owned by the client who is responsible to delete it. + * + * @param[in] path A string representing a path to a configurable element. + * @param[out] error On error: an human readable error message + * On success: undefined + * + * @return An element handle on success + * NULL on error + */ + ElementHandle *createElementHandle(const std::string &path, std::string &error) const; /** Is the remote interface forcefully disabled ? */ @@ -102,49 +131,51 @@ public: * * @return false if unable to set, true otherwise. */ - bool setFailureOnMissingSubsystem(bool bFail, std::string& strError); + bool setFailureOnMissingSubsystem(bool bFail, std::string &strError); /** Would start fail in case of missing subsystems. * * @return if the subsystem load will fail on missing subsystem. */ - bool getFailureOnMissingSubsystem(); + bool getFailureOnMissingSubsystem() const; /** Should start fail in failed settings load. * * Will fail if called on started instance. * - * @param[in] bFail: If set to true, parameterMgr start will fail on failed settings load. - * If set to false, failed settings load will be ignored. - * @param[out] strResult a string containing the result of the command. + * @param[in] bFail If set to true, parameterMgr start will fail on failed settings load. + * If set to false, failed settings load will be ignored. + * @param[out] strError On error: an human readable error message + * On success: undefined * * @return false if unable to set, true otherwise. */ - bool setFailureOnFailedSettingsLoad(bool bFail, std::string& strError); + bool setFailureOnFailedSettingsLoad(bool bFail, std::string &strError); /** Would start fail in case of failed settings load. * * @return failure on failed settings load policy state. */ - bool getFailureOnFailedSettingsLoad(); + bool getFailureOnFailedSettingsLoad() const; - /** Get the path to the directory containing the XML Schemas + /** Get the XML Schemas URI * - * @returns the directory containing the XML Schemas + * @returns the XML Schemas URI */ - const std::string& getSchemaFolderLocation() const; + const std::string &getSchemaUri() const; - /** Override the directory containing the XML Schemas + /** Override the XML Schemas URI * - * @param[in] strSchemaFolderLocation directory containing the XML Schemas + * @param[in] schemaUri the XML Schemas URI */ - void setSchemaFolderLocation(const std::string& strSchemaFolderLocation); + void setSchemaUri(const std::string &schemaUri); /** Should .xml files be validated on start ? * * @param[in] bValidate: * If set to true, parameterMgr will abort when being unable to validate .xml files * If set to false, no .xml/xsd validation will happen (default behaviour) - * @param[out] strResult a string containing the result of the command. + * @param[out] strError On error: an human readable error message + * On success: undefined * * @return false if unable to set, true otherwise. */ @@ -154,20 +185,22 @@ public: * * @return areSchemasValidated */ - bool getValidateSchemasOnStart(); + bool getValidateSchemasOnStart() const; private: - CParameterMgrPlatformConnector(const CParameterMgrPlatformConnector&); - CParameterMgrPlatformConnector& operator=(const CParameterMgrPlatformConnector&); + CParameterMgrPlatformConnector(const CParameterMgrPlatformConnector &); + CParameterMgrPlatformConnector &operator=(const CParameterMgrPlatformConnector &); // Private logging - void doLog(bool bIsWarning, const std::string& strLog); + void info(const std::string &log); + void warning(const std::string &log); +protected: + // Private logging + CParameterMgrLogger<CParameterMgrPlatformConnector> *_pParameterMgrLogger; // Implementation - CParameterMgr* _pParameterMgr; + CParameterMgr *_pParameterMgr; // State bool _bStarted; // Logging - ILogger* _pLogger; - // Private logging - CParameterMgrLogger<CParameterMgrPlatformConnector>* _pParameterMgrLogger; + ILogger *_pLogger; }; diff --git a/parameter/include/SelectionCriterionInterface.h b/parameter/include/SelectionCriterionInterface.h index d71eff3..6eb2d8a 100644 --- a/parameter/include/SelectionCriterionInterface.h +++ b/parameter/include/SelectionCriterionInterface.h @@ -39,7 +39,7 @@ public: virtual void setCriterionState(int iState) = 0; virtual int getCriterionState() const = 0; virtual std::string getCriterionName() const = 0; - virtual const ISelectionCriterionTypeInterface* getCriterionType() const = 0; + virtual const ISelectionCriterionTypeInterface *getCriterionType() const = 0; protected: virtual ~ISelectionCriterionInterface() {} diff --git a/parameter/include/SelectionCriterionTypeInterface.h b/parameter/include/SelectionCriterionTypeInterface.h index 0b62ee4..bebcfc7 100644 --- a/parameter/include/SelectionCriterionTypeInterface.h +++ b/parameter/include/SelectionCriterionTypeInterface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -34,13 +34,20 @@ class ISelectionCriterionTypeInterface { public: - virtual bool addValuePair(int iValue, const std::string& strValue) = 0; - virtual bool getNumericalValue(const std::string& strValue, int& iValue) const = 0; - virtual bool getLiteralValue(int iValue, std::string& strValue) const = 0; + /** + * Add a new pair [integer, litteral] which represents a criterion + * + * @param[in] iValue integer value + * @param[in] strValue litteral value + * @param[out] strError string containing error information we can provide to client + * @return true if succeed false otherwise + */ + virtual bool addValuePair(int iValue, const std::string &strValue, std::string &strError) = 0; + virtual bool getNumericalValue(const std::string &strValue, int &iValue) const = 0; + virtual bool getLiteralValue(int iValue, std::string &strValue) const = 0; virtual bool isTypeInclusive() const = 0; virtual std::string getFormattedState(int iValue) const = 0; protected: virtual ~ISelectionCriterionTypeInterface() {} }; - diff --git a/parameter/log/include/log/Context.h b/parameter/log/include/log/Context.h new file mode 100644 index 0000000..a3d5fd4 --- /dev/null +++ b/parameter/log/include/log/Context.h @@ -0,0 +1,72 @@ +/* + * 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. + */ +#pragma once + +#include "log/Logger.h" +#include <string> + +namespace core +{ +namespace log +{ + +/** Log formatter which provide context indentation */ +class Context +{ +public: + /** + * Class Constructor + * + * @param[in] logger application logger + * @param[in] context name of the context to open + */ + Context(Logger &logger, const std::string &context) : mLogger(logger) + { + mLogger.info() << context << " {"; + mLogger.mProlog += " "; + } + + /** Class Destructor */ + ~Context() + { + mLogger.mProlog.resize(mLogger.mProlog.size() - 4); + mLogger.info() << "}"; + } + +private: + Context(const Context &); + Context &operator=(const Context &); + + /** Application logger */ + Logger &mLogger; +}; + +} /** log namespace */ +} /** core namespace */ diff --git a/parameter/ErrorContext.h b/parameter/log/include/log/ILogger.h index ae2afe1..9b72813 100644 --- a/parameter/ErrorContext.h +++ b/parameter/log/include/log/ILogger.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,18 +31,21 @@ #include <string> -class CErrorContext +namespace core +{ +namespace log { -public: - CErrorContext(std::string& strError); - // Error - void setError(const std::string& strError); - void appendToError(const std::string& strAppend); - const std::string& getError() const; +/** Logger interface provided by client */ +class ILogger +{ +public: + virtual void info(const std::string &strLog) = 0; + virtual void warning(const std::string &strLog) = 0; -private: - // Error reference - std::string& _strError; +protected: + virtual ~ILogger() {} }; +} /** log namespace */ +} /** core namespace */ diff --git a/parameter/log/include/log/LogWrapper.h b/parameter/log/include/log/LogWrapper.h new file mode 100644 index 0000000..14624e4 --- /dev/null +++ b/parameter/log/include/log/LogWrapper.h @@ -0,0 +1,136 @@ +/* + * 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. + */ +#pragma once + +#include "log/ILogger.h" +#include "Utility.h" +#include <string> +#include <sstream> +#include <iterator> +#include <list> + +namespace core +{ +namespace log +{ +namespace details +{ + +/** + * Template log wrapper + * Simulate a stream which can be used instead of basic ILogger API. + * + * @tparam isWarning indicates which log canal to use + */ +template <bool isWarning> +class LogWrapper +{ +public: + /** @param logger the ILogger to wrap */ + LogWrapper(ILogger &logger, const std::string &prolog = "") : mLogger(logger), mProlog(prolog) + { + } + + /** + * Class copy constructor + * + * @param[in] logWrapper the instance to copy + */ + LogWrapper(const LogWrapper &logWrapper) + : mLogger(logWrapper.mLogger), mProlog(logWrapper.mProlog) + { + } + + /** Class destructor */ + ~LogWrapper() + { + if (!mLog.str().empty()) { + if (isWarning) { + mLogger.warning(mProlog + mLog.str()); + } else { + mLogger.info(mProlog + mLog.str()); + } + } + } + + /** + * Simulate stream behaviour + * + * @tparam T the type of the information to log + * @param[in] log the information to log + */ + template <class T> + LogWrapper &operator<<(const T &log) + { + mLog << log; + return *this; + } + + /** + * Simulate stream behaviour for string list + * + * @param[in] logs list of information to log + */ + LogWrapper &operator<<(const std::list<std::string> &logs) + { + std::string separator = "\n" + mProlog; + std::string formatedLogs = utility::asString(logs, separator); + + // Check if there is something in the log to know if we have to add a prefix + if (!mLog.str().empty() && mLog.str()[mLog.str().length() - 1] == separator[0]) { + *this << mProlog; + } + + *this << formatedLogs; + return *this; + } + +private: + LogWrapper &operator=(const LogWrapper &); + + /** Log stream holder */ + std::ostringstream mLog; + + /** Wrapped logger */ + ILogger &mLogger; + + /** Log Prefix */ + const std::string &mProlog; +}; + +/** Default information logger type */ +typedef details::LogWrapper<false> Info; + +/** Default warning logger type */ +typedef details::LogWrapper<true> Warning; + +} /** details namespace */ +} /** log namespace */ +} /** core namespace */ diff --git a/parameter/ConfigurableElementWithMapping.h b/parameter/log/include/log/Logger.h index b5f6a1f..b224d35 100644 --- a/parameter/ConfigurableElementWithMapping.h +++ b/parameter/log/include/log/Logger.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,27 +29,52 @@ */ #pragma once -#include "ConfigurableElement.h" -#include <string> +#include "log/ILogger.h" +#include "log/LogWrapper.h" -/** - * Base class for all Configurable Elements that can have a Mapping attribute. - * - * This class acts as an interface: it doesn't implement anything but only - * declares getMappingData as pure virtual fonction. +#include "NonCopyable.hpp" + +namespace core +{ +namespace log +{ + +/** Application logger object (Thread unsafe) + * Provide contextualisable logging API. + * Streams can be used through Info and Warning objects returned by dedicated + * methods. + * This is the class you want to use to log in the project. */ -class CConfigurableElementWithMapping : public CConfigurableElement { +class Logger : private utility::NonCopyable +{ public: - CConfigurableElementWithMapping(const std::string& strName) : CConfigurableElement(strName) {} - virtual ~CConfigurableElementWithMapping() {} + /** Context class is friend let the prolog by externally modified */ + friend class Context; + + /** @param[in] logger raw logger provided by client */ + Logger(ILogger &logger) : mLogger(logger) {} /** - * Get the value associated to a mapping key in the object's mapping + * Retrieve wrapped information logger * - * @param[in] strKey the mapping key - * @param[out] pStrValue the associated value + * @return Info logger + */ + details::Info info() { return details::Info(mLogger, mProlog); } + + /** + * Retrieve wrapped warning logger * - * @return true if @p strKey is found in the object's mapping, false if not + * @return Warning logger */ - virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const = 0; + details::Warning warning() { return details::Warning(mLogger, mProlog); } + +private: + /** Raw logger provided by client */ + ILogger &mLogger; + + /** Log prolog, owns the context indentation */ + std::string mProlog; }; + +} /** log namespace */ +} /** core namespace */ diff --git a/utility/Unused.h b/parameter/version.h.in index e55b7dd..264fbba 100644 --- a/utility/Unused.h +++ b/parameter/version.h.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,10 +27,4 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#ifndef UNUSED_H -#define UNUSED_H - -#define __unused __attribute__((__unused__)) - -#endif // UNUSED_H +#define PARAMETER_FRAMEWORK_VERSION "@NICE_PF_VERSION@" diff --git a/remote-process/Android.mk b/remote-process/Android.mk deleted file mode 100644 index a29b834..0000000 --- a/remote-process/Android.mk +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (c) 2011-2014, 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. - -LOCAL_PATH := $(call my-dir) - -#################### -# Common definitions - -common_src_files := \ - main.cpp - -common_module := remote-process -common_module_tags := optional - -common_cflags := \ - -Wall \ - -Werror \ - -Wextra \ - -Wno-unused-parameter - -common_c_includes := \ - $(LOCAL_PATH)/../remote-processor/ - -common_shared_libraries := libremote-processor -common_static_libraries := libpfw_utility - -############################# -# Target build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_MODULE := $(common_module) -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_CFLAGS := $(common_cflags) - -LOCAL_C_INCLUDES := $(common_c_includes) - -LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) -LOCAL_STATIC_LIBRARIES := $(common_static_libraries) - -ifeq ($(INCLUDE_STLPORT), true) -include external/stlport/libstlport.mk -endif - -include $(BUILD_EXECUTABLE) - -############################## -# Host build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_MODULE := $(common_module)_host -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_CFLAGS := $(common_cflags) - -LOCAL_C_INCLUDES += \ - $(common_c_includes) - -LOCAL_SHARED_LIBRARIES := $(foreach shared_library, $(common_shared_libraries), \ - $(shared_library)_host) -LOCAL_STATIC_LIBRARIES := $(foreach static_library, $(common_static_libraries), \ - $(static_library)_host) - -include $(BUILD_HOST_EXECUTABLE) diff --git a/remote-process/CMakeLists.txt b/remote-process/CMakeLists.txt index f71e562..e27a101 100644 --- a/remote-process/CMakeLists.txt +++ b/remote-process/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,14 +26,14 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_executable(remote-process main.cpp) +if(NETWORKING) + add_executable(remote-process main.cpp) -# TODO: separate remote-processor's includes in half (public/private) -# And use only public headers here -include_directories( - "${PROJECT_SOURCE_DIR}/remote-processor" - "${PROJECT_SOURCE_DIR}/utility") + set(CMAKE_THREAD_PREFER_PTHREAD 1) + find_package(Threads REQUIRED) -target_link_libraries(remote-process remote-processor pfw_utility) + target_link_libraries(remote-process + PRIVATE remote-processor pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) -install(TARGETS remote-process RUNTIME DESTINATION bin) + install(TARGETS remote-process RUNTIME DESTINATION bin) +endif() diff --git a/remote-process/main.cpp b/remote-process/main.cpp index 97881dc..3ebaa86 100644 --- a/remote-process/main.cpp +++ b/remote-process/main.cpp @@ -27,81 +27,24 @@ * (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 <asio.hpp> + #include <iostream> #include <string> #include <cstring> #include <stdlib.h> #include "RequestMessage.h" #include "AnswerMessage.h" -#include "ConnectionSocket.h" -#include "NaiveTokenizer.h" +#include "Socket.h" using namespace std; -class CRequestMessageGenerator -{ -private: - istream& _input; // File to read the commands from - -public: - CRequestMessageGenerator(istream& input) : _input(input) {} - - enum EStatus { - OK, - STOP, - EMPTY_LINE, - ERROR - }; - - EStatus next(CRequestMessage& requestMessage) - { - string sLine; - char* pcLine; - char* pcLine_backup; // pcLine will be modified by NaiveTokenizer - // so we need to keep track of its original value - char* pcToken; - - // Read a single line from the input file - getline(_input, sLine); - if (_input.eof() && (_input.gcount() == 0)) { - return STOP; // No more commands - } - if (_input.fail()) { - return ERROR; // Error while reading file - } - - pcLine = strdup(sLine.c_str()); - pcLine_backup = pcLine; - if (!pcLine) { - return ERROR; - } - - // Set the first word as the command - pcToken = NaiveTokenizer::getNextToken(&pcLine); - if (!pcToken) { - free(pcLine_backup); - return EMPTY_LINE; - } - requestMessage.setCommand(pcToken); - - while ((pcToken = NaiveTokenizer::getNextToken(&pcLine)) != NULL) { - - // Add each word as arguments to the command - requestMessage.addArgument(pcToken); - } - - free(pcLine_backup); - - return OK; - } -}; - -bool sendAndDisplayCommand(CConnectionSocket &connectionSocket, CRequestMessage &requestMessage) +bool sendAndDisplayCommand(asio::ip::tcp::socket &socket, CRequestMessage &requestMessage) { string strError; - if (requestMessage.serialize(&connectionSocket, true, strError) - != CRequestMessage::success) { + if (requestMessage.serialize(Socket(socket), true, strError) != CRequestMessage::success) { cerr << "Unable to send command to target: " << strError << endl; return false; @@ -109,8 +52,7 @@ bool sendAndDisplayCommand(CConnectionSocket &connectionSocket, CRequestMessage ///// Get answer CAnswerMessage answerMessage; - if (answerMessage.serialize(&connectionSocket, false, strError) - != CRequestMessage::success) { + if (answerMessage.serialize(Socket(socket), false, strError) != CRequestMessage::success) { cerr << "Unable to received answer from target: " << strError << endl; return false; @@ -135,75 +77,42 @@ bool sendAndDisplayCommand(CConnectionSocket &connectionSocket, CRequestMessage // hostname port < commands int main(int argc, char *argv[]) { - bool bFromStdin = false; // Read commands from stdin instead of arguments - // Enough args? - if (argc < 3) { + if (argc < 4) { cerr << "Missing arguments" << endl; cerr << "Usage: " << endl; cerr << "Send a single command:" << endl; cerr << "\t" << argv[0] << " hostname port command [argument[s]]" << endl; - cerr << "Send several commands, read from stdin:" << endl; - cerr << "\t" << argv[0] << " hostname port" << endl; return 1; - } else if (argc < 4) { - bFromStdin = true; } - // Get port number - uint16_t uiPort = (uint16_t)strtoul(argv[2], NULL, 0); - - // Connect to target - CConnectionSocket connectionSocket; + using asio::ip::tcp; + asio::io_service io_service; + tcp::resolver resolver(io_service); + + tcp::socket connectionSocket(io_service); + + string host{argv[1]}; + string port{argv[2]}; + try { + asio::connect(connectionSocket, resolver.resolve(tcp::resolver::query(host, port))); + } catch (const asio::system_error &e) { + cerr << "Connection to '" << host << ":" << port << "' failed: " << e.what() << endl; + return 1; + } - string strError; - // Connect - if (!connectionSocket.connect(argv[1], uiPort, strError)) { + // Create command message + CRequestMessage requestMessage(argv[3]); - cerr << strError << endl; + // Add arguments + for (int arg = 4; arg < argc; arg++) { - return 1; + requestMessage.addArgument(argv[arg]); } - if (bFromStdin) { - - CRequestMessageGenerator generator(cin); - CRequestMessage requestMessage; - CRequestMessageGenerator::EStatus status; - - while (true) { - status = generator.next(requestMessage); - - switch (status) { - case CRequestMessageGenerator::OK: - if (!sendAndDisplayCommand(connectionSocket, requestMessage)) { - return 1; - } - break; - case CRequestMessageGenerator::STOP: - return 0; - case CRequestMessageGenerator::ERROR: - cerr << "Error while reading the input" << endl; - return 1; - case CRequestMessageGenerator::EMPTY_LINE: - continue; - } - } - } else { - // Create command message - CRequestMessage requestMessage(argv[3]); - - // Add arguments - uint32_t uiArg; - for (uiArg = 4; uiArg < (uint32_t)argc; uiArg++) { - - requestMessage.addArgument(argv[uiArg]); - } - - if (!sendAndDisplayCommand(connectionSocket, requestMessage)) { - return 1; - } + if (!sendAndDisplayCommand(connectionSocket, requestMessage)) { + return 1; } // Program status diff --git a/remote-processor/AnswerMessage.cpp b/remote-processor/AnswerMessage.cpp index 8cfe8d3..7ae948f 100644 --- a/remote-processor/AnswerMessage.cpp +++ b/remote-processor/AnswerMessage.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -28,14 +28,14 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AnswerMessage.h" -#include "RemoteProcessorProtocol.h" #include <assert.h> #define base CMessage using std::string; -CAnswerMessage::CAnswerMessage(const string& strAnswer, bool bSuccess) : base(bSuccess ? ESuccessAnswer : EFailureAnswer), _strAnswer(strAnswer) +CAnswerMessage::CAnswerMessage(const string &strAnswer, bool bSuccess) + : base(bSuccess ? MsgType::ESuccessAnswer : MsgType::EFailureAnswer), _strAnswer(strAnswer) { } @@ -44,12 +44,12 @@ CAnswerMessage::CAnswerMessage() } // Answer -void CAnswerMessage::setAnswer(const string& strAnswer) +void CAnswerMessage::setAnswer(const string &strAnswer) { _strAnswer = strAnswer; } -const string& CAnswerMessage::getAnswer() const +const string &CAnswerMessage::getAnswer() const { return _strAnswer; } @@ -57,7 +57,11 @@ const string& CAnswerMessage::getAnswer() const // Status bool CAnswerMessage::success() const { - return getMsgId() == ESuccessAnswer; + /* FIXME this test is buggy because MsgType mixes up two different information: message type + * (answer or request), and content of the message (answer is success or failure). Getting a + * message id 'ECommandRequest' would deserve an assert, when here it is just misinterpreted as + * a failure... */ + return getMsgId() == MsgType::ESuccessAnswer; } // Size diff --git a/remote-processor/AnswerMessage.h b/remote-processor/AnswerMessage.h index 9dbcdc8..8275d5d 100644 --- a/remote-processor/AnswerMessage.h +++ b/remote-processor/AnswerMessage.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -29,19 +29,22 @@ */ #pragma once +#include "remote_processor_export.h" + #include "Message.h" -class CAnswerMessage : public CMessage +class REMOTE_PROCESSOR_EXPORT CAnswerMessage : public CMessage { public: - CAnswerMessage(const std::string& strAnswer, bool bSuccess); + CAnswerMessage(const std::string &strAnswer, bool bSuccess); CAnswerMessage(); // Answer - const std::string& getAnswer() const; + const std::string &getAnswer() const; // Status bool success() const; + private: // Fill data to send virtual void fillDataToSend(); @@ -52,9 +55,8 @@ private: */ virtual size_t getDataSize() const; // Answer - void setAnswer(const std::string& strAnswer); + void setAnswer(const std::string &strAnswer); // Answer std::string _strAnswer; }; - diff --git a/remote-processor/ConnectionSocket.cpp b/remote-processor/BackgroundRemoteProcessorServer.cpp index 5b5de45..0820786 100644 --- a/remote-processor/ConnectionSocket.cpp +++ b/remote-processor/BackgroundRemoteProcessorServer.cpp @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2014, Intel Corporation +/* + * Copyright (c) 2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,51 +27,38 @@ * (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 "ConnectionSocket.h" -#include <unistd.h> -#include <netdb.h> -#include <netinet/in.h> -#include <stdio.h> -#include <errno.h> -#include <sstream> +#include "BackgroundRemoteProcessorServer.h" +#include "RemoteProcessorServer.h" -#define base CSocket - -using std::string; - -CConnectionSocket::CConnectionSocket() +BackgroundRemoteProcessorServer::BackgroundRemoteProcessorServer( + uint16_t uiPort, std::unique_ptr<IRemoteCommandHandler> &&commandHandler) + : _server(new CRemoteProcessorServer(uiPort)), mCommandHandler(std::move(commandHandler)) { } -// Connection -bool CConnectionSocket::connect(const string& strRemote, uint16_t uiPort, string& strError) +bool BackgroundRemoteProcessorServer::start(std::string &error) { - struct sockaddr_in server_addr; - - // Host entry - struct hostent* host = gethostbyname(strRemote.c_str()); - - // Check host - if (!host) { - - strError = "Target not found :-("; - + if (!_server->start(error)) { return false; } - - // Fill server address - initSockAddrIn(&server_addr, *((uint32_t*)host->h_addr), uiPort); - - // Connect - if (::connect(getFd(), (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) { - - std::ostringstream oss; - oss << "CConnectionSocket::connect::connect on port: " << uiPort; - perror(oss.str().c_str()); - - strError = "Unable to connnect to target :-("; - + try { + mServerSuccess = std::async(std::launch::async, &CRemoteProcessorServer::process, + _server.get(), std::ref(*mCommandHandler)); + } catch (std::exception &e) { + error = "Could not create a remote processor thread: " + std::string(e.what()); return false; } + return true; } + +bool BackgroundRemoteProcessorServer::stop() +{ + _server->stop(); + return mServerSuccess.get(); +} + +BackgroundRemoteProcessorServer::~BackgroundRemoteProcessorServer() +{ + stop(); +} diff --git a/remote-processor/BackgroundRemoteProcessorServer.h b/remote-processor/BackgroundRemoteProcessorServer.h new file mode 100644 index 0000000..1c17fca --- /dev/null +++ b/remote-processor/BackgroundRemoteProcessorServer.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011-2014, 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 "RemoteProcessorServerInterface.h" +#include "RemoteCommandHandler.h" +#include <memory> +#include <future> + +#include "remote_processor_export.h" + +class CRemoteProcessorServer; + +class REMOTE_PROCESSOR_EXPORT BackgroundRemoteProcessorServer final + : public IRemoteProcessorServerInterface +{ +public: + BackgroundRemoteProcessorServer(uint16_t uiPort, + std::unique_ptr<IRemoteCommandHandler> &&commandHandler); + + ~BackgroundRemoteProcessorServer(); + + bool start(std::string &error) override; + + bool stop() override; + +private: + std::unique_ptr<CRemoteProcessorServer> _server; + std::unique_ptr<IRemoteCommandHandler> mCommandHandler; + std::future<bool> mServerSuccess; +}; diff --git a/remote-processor/CMakeLists.txt b/remote-processor/CMakeLists.txt index 27a41f9..ee21f55 100644 --- a/remote-processor/CMakeLists.txt +++ b/remote-processor/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -27,20 +27,25 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. add_library(remote-processor SHARED - Socket.cpp - ListeningSocket.cpp - ConnectionSocket.cpp Message.cpp RequestMessage.cpp AnswerMessage.cpp RemoteProcessorServer.cpp - RemoteProcessorServerBuilder.cpp) + BackgroundRemoteProcessorServer.cpp) + +include(GenerateExportHeader) +generate_export_header(remote-processor + BASE_NAME remote_processor) set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads REQUIRED) -include_directories("${PROJECT_SOURCE_DIR}/utility") +target_include_directories(remote-processor + # Symbol export macro header + PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" + # TODO: separate remote-processor's includes in half (public/private) + PUBLIC .) -target_link_libraries(remote-processor pfw_utility ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(remote-processor PRIVATE pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) -install(TARGETS remote-processor LIBRARY DESTINATION lib) +install(TARGETS remote-processor LIBRARY DESTINATION lib RUNTIME DESTINATION bin) diff --git a/remote-processor/ListeningSocket.cpp b/remote-processor/ListeningSocket.cpp deleted file mode 100644 index 191d412..0000000 --- a/remote-processor/ListeningSocket.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2011-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 "ListeningSocket.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <unistd.h> -#include <assert.h> -#include <netdb.h> -#include <strings.h> -#include <sstream> - -#include <stdio.h> -#include <errno.h> -#include <cstring> - -#define base CSocket - -using std::string; - -CListeningSocket::CListeningSocket() -{ - int iOption = true; - // Reuse option - setsockopt(getFd(), SOL_SOCKET, SO_REUSEADDR, &iOption, sizeof(iOption)); -} - -// Listen -bool CListeningSocket::listen(uint16_t uiPort, string &strError) -{ - struct sockaddr_in server_addr; - - // Fill server address - initSockAddrIn(&server_addr, INADDR_ANY, uiPort); - - // Bind - if (bind(getFd(), (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) == -1) { - - std::ostringstream oss; - oss << uiPort; - strError = "Could not bind socket to port " + oss.str() + ": " + strerror(errno); - return false; - } - - if (::listen(getFd(), 5) == -1) { - - std::ostringstream oss; - oss << uiPort; - strError = "Could not listen to port " + oss.str() + ": " + strerror(errno); - return false; - } - return true; -} - -// Accept -CSocket* CListeningSocket::accept() -{ - struct sockaddr_in client_addr; - socklen_t ulClientAddrLen = sizeof(client_addr); - - int iSockId = ::accept(getFd(), (struct sockaddr*)&client_addr, &ulClientAddrLen); - - if (iSockId == -1) { - - perror("CListeningSocket::accept::accept"); - - return NULL; - } - return new CSocket(iSockId); -} diff --git a/remote-processor/Message.cpp b/remote-processor/Message.cpp index 2662e3d..66154ec 100644 --- a/remote-processor/Message.cpp +++ b/remote-processor/Message.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -28,69 +28,73 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Message.h" -#include <assert.h> #include "Socket.h" -#include "RemoteProcessorProtocol.h" -#include <string.h> -#include <assert.h> -#include <errno.h> +#include "Iterator.hpp" +#include <asio.hpp> +#include <vector> +#include <numeric> +#include <cassert> using std::string; -CMessage::CMessage(uint8_t ucMsgId) : _ucMsgId(ucMsgId), _pucData(NULL), _uiDataSize(0), _uiIndex(0) +CMessage::CMessage(MsgType ucMsgId) : _ucMsgId(ucMsgId), _uiIndex(0) { } -CMessage::CMessage() : _ucMsgId((uint8_t)-1), _pucData(NULL), _uiDataSize(0), _uiIndex(0) +CMessage::CMessage() : _ucMsgId(MsgType::EInvalid), _uiIndex(0) { } -CMessage::~CMessage() +// Msg Id +CMessage::MsgType CMessage::getMsgId() const { - delete [] _pucData; + return _ucMsgId; } -// Msg Id -uint8_t CMessage::getMsgId() const +bool CMessage::isValidAccess(size_t offset, size_t size) const { - return _ucMsgId; + return offset + size <= getMessageDataSize(); } // Data -void CMessage::writeData(const void* pvData, size_t uiSize) +void CMessage::writeData(const void *pvData, size_t size) { - assert(_uiIndex + uiSize <= _uiDataSize); + assert(isValidAccess(_uiIndex, size)); + + auto first = MAKE_ARRAY_ITERATOR(static_cast<const uint8_t *>(pvData), size); + auto last = first + size; + auto destFirst = begin(mData) + _uiIndex; - // Copy - memcpy(&_pucData[_uiIndex], pvData, uiSize); + std::copy(first, last, destFirst); - // Index - _uiIndex += uiSize; + _uiIndex += size; } -void CMessage::readData(void* pvData, size_t uiSize) +void CMessage::readData(void *pvData, size_t size) { - assert(_uiIndex + uiSize <= _uiDataSize); + assert(isValidAccess(_uiIndex, size)); - // Copy - memcpy(pvData, &_pucData[_uiIndex], uiSize); + auto first = begin(mData) + _uiIndex; + auto last = first + size; + auto destFirst = MAKE_ARRAY_ITERATOR(static_cast<uint8_t *>(pvData), size); - // Index - _uiIndex += uiSize; + std::copy(first, last, destFirst); + + _uiIndex += size; } -void CMessage::writeString(const string& strData) +void CMessage::writeString(const string &strData) { // Size - uint32_t uiSize = strData.length(); + uint32_t size = static_cast<uint32_t>(strData.length()); - writeData(&uiSize, sizeof(uiSize)); + writeData(&size, sizeof(size)); // Content - writeData(strData.c_str(), uiSize); + writeData(strData.c_str(), size); } -void CMessage::readString(string& strData) +void CMessage::readString(string &strData) { // Size uint32_t uiSize; @@ -98,19 +102,19 @@ void CMessage::readString(string& strData) readData(&uiSize, sizeof(uiSize)); // Data - char pcData[uiSize + 1]; + std::vector<char> string(uiSize + 1); // Content - readData(pcData, uiSize); + readData(string.data(), uiSize); // NULL-terminate string - pcData[uiSize] = '\0'; + string.back() = '\0'; // Output - strData = pcData; + strData = string.data(); } -size_t CMessage::getStringSize(const string& strData) const +size_t CMessage::getStringSize(const string &strData) const { // Return string length plus room to store its length return strData.length() + sizeof(uint32_t); @@ -119,13 +123,16 @@ size_t CMessage::getStringSize(const string& strData) const // Remaining data size size_t CMessage::getRemainingDataSize() const { - return _uiDataSize - _uiIndex; + return getMessageDataSize() - _uiIndex; } // Send/Receive -CMessage::Result CMessage::serialize(CSocket* pSocket, bool bOut, string& strError) +CMessage::Result CMessage::serialize(Socket &&socket, bool bOut, string &strError) { + asio::ip::tcp::socket &asioSocket = socket.get(); + if (bOut) { + asio::error_code ec; // Make room for data to send allocateData(getDataSize()); @@ -134,59 +141,59 @@ CMessage::Result CMessage::serialize(CSocket* pSocket, bool bOut, string& strErr fillDataToSend(); // Finished providing data? - assert(_uiIndex == _uiDataSize); + assert(_uiIndex == getMessageDataSize()); // First send sync word uint16_t uiSyncWord = SYNC_WORD; - if (!pSocket->write(&uiSyncWord, sizeof(uiSyncWord))) { + if (!asio::write(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { - if (pSocket->hasPeerDisconnected()) { + if (ec == asio::error::eof) { return peerDisconnected; } return error; } // Size - uint32_t uiSize = (uint32_t)(sizeof(_ucMsgId) + _uiDataSize); + uint32_t uiSize = (uint32_t)(sizeof(_ucMsgId) + getMessageDataSize()); - if (!pSocket->write(&uiSize, sizeof(uiSize))) { + if (!asio::write(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { - strError += string("Size write failed: ") + strerror(errno); + strError += string("Size write failed: ") + ec.message(); return error; } // Msg Id - if (!pSocket->write(&_ucMsgId, sizeof(_ucMsgId))) { + if (!asio::write(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { - strError += string("Msg write failed: ") + strerror(errno); + strError += string("Msg write failed: ") + ec.message(); return error; } // Data - if (!pSocket->write(_pucData, _uiDataSize)) { + if (!asio::write(asioSocket, asio::buffer(mData), ec)) { - strError = string("Data write failed: ") + strerror(errno); + strError = string("Data write failed: ") + ec.message(); return error; } // Checksum uint8_t ucChecksum = computeChecksum(); - if (!pSocket->write(&ucChecksum, sizeof(ucChecksum))) { + if (!asio::write(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { - strError = string("Checksum write failed: ") + strerror(errno); + strError = string("Checksum write failed: ") + ec.message(); return error; } } else { // First read sync word - uint16_t uiSyncWord; - - if (!pSocket->read(&uiSyncWord, sizeof(uiSyncWord))) { + uint16_t uiSyncWord = 0; + asio::error_code ec; - strError = string("Sync read failed: ") + strerror(errno); - if (pSocket->hasPeerDisconnected()) { + if (!asio::read(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { + strError = string("Sync read failed: ") + ec.message(); + if (ec == asio::error::eof) { return peerDisconnected; } return error; @@ -200,18 +207,16 @@ CMessage::Result CMessage::serialize(CSocket* pSocket, bool bOut, string& strErr } // Size - uint32_t uiSize; + uint32_t uiSize = 0; - if (!pSocket->read(&uiSize, sizeof(uiSize))) { - - strError = string("Size read failed: ") + strerror(errno); + if (!asio::read(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { + strError = string("Size read failed: ") + ec.message(); return error; } // Msg Id - if (!pSocket->read(&_ucMsgId, sizeof(_ucMsgId))) { - - strError = string("Msg id read failed: ") + strerror(errno); + if (!asio::read(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { + strError = string("Msg id read failed: ") + ec.message(); return error; } @@ -221,18 +226,16 @@ CMessage::Result CMessage::serialize(CSocket* pSocket, bool bOut, string& strErr allocateData(uiSize - sizeof(_ucMsgId)); // Data receive - if (!pSocket->read(_pucData, _uiDataSize)) { - - strError = string("Data read failed: ") + strerror(errno); + if (!asio::read(asioSocket, asio::buffer(mData), ec)) { + strError = string("Data read failed: ") + ec.message(); return error; } // Checksum - uint8_t ucChecksum; - - if (!pSocket->read(&ucChecksum, sizeof(ucChecksum))) { + uint8_t ucChecksum = 0; - strError = string("Checksum read failed: ") + strerror(errno); + if (!asio::read(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { + strError = string("Checksum read failed: ") + ec.message(); return error; } // Compare @@ -252,31 +255,17 @@ CMessage::Result CMessage::serialize(CSocket* pSocket, bool bOut, string& strErr // Checksum uint8_t CMessage::computeChecksum() const { - uint8_t uiChecksum = _ucMsgId; - - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) { - - uiChecksum += _pucData[uiIndex]; - } - - return uiChecksum; + return accumulate(begin(mData), end(mData), static_cast<uint8_t>(_ucMsgId)); } // Allocation of room to store the message -void CMessage::allocateData(size_t uiSize) +void CMessage::allocateData(size_t size) { // Remove previous one - if (_pucData) { + mData.clear(); - delete [] _pucData; - } // Do allocate - _pucData = new uint8_t[uiSize]; - - // Record size - _uiDataSize = uiSize; + mData.resize(size); // Reset Index _uiIndex = 0; diff --git a/remote-processor/Message.h b/remote-processor/Message.h index 3f5e847..2a596f1 100644 --- a/remote-processor/Message.h +++ b/remote-processor/Message.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,19 +29,31 @@ */ #pragma once -#include <stdint.h> +#include "NonCopyable.hpp" +#include <vector> #include <string> +#include <cstdint> -class CSocket; +#include <remote_processor_export.h> -class CMessage +class Socket; + +class REMOTE_PROCESSOR_EXPORT CMessage : private utility::NonCopyable { public: - CMessage(uint8_t ucMsgId); + enum class MsgType : std::uint8_t + { + ECommandRequest, + ESuccessAnswer, + EFailureAnswer, + EInvalid = static_cast<uint8_t>(-1), + }; + CMessage(MsgType ucMsgId); CMessage(); - virtual ~CMessage(); + virtual ~CMessage() = default; - enum Result { + enum Result + { success, peerDisconnected, error @@ -49,7 +61,7 @@ public: /** Write or read the message on pSocket. * - * @param[in,out] pSocket is the socket on wich IO operation will be made. + * @param[in,out] socket is the socket on wich IO operation will be made. * @param[in] bOut if true message should be read, * if false it should be written. * @param[out] strError on failure, a string explaining the error, @@ -59,51 +71,51 @@ public: * peerDisconnected if the peer disconnected before the first socket access. * error if the message could not be read/write for any other reason */ - Result serialize(CSocket* pSocket, bool bOut, std::string &strError); + Result serialize(Socket &&socket, bool bOut, std::string &strError); protected: // Msg Id - uint8_t getMsgId() const; + MsgType getMsgId() const; /** Write raw data to the message * * @param[in] pvData pointer to the data array * @param[in] uiSize array size in bytes */ - void writeData(const void* pvData, size_t uiSize); + void writeData(const void *pvData, size_t uiSize); /** Read raw data from the message * * @param[out] pvData pointer to the data array * @param[in] uiSize array size in bytes */ - void readData(void* pvData, size_t uiSize); + void readData(void *pvData, size_t uiSize); /** Write string to the message * * @param[in] strData the string to write */ - void writeString(const std::string& strData); + void writeString(const std::string &strData); /** Write string to the message * * @param[out] strData the string to read to */ - void readString(std::string& strData); + void readString(std::string &strData); /** @return string length plus room to store its length * * @param[in] strData the string to get the size from */ - size_t getStringSize(const std::string& strData) const; + size_t getStringSize(const std::string &strData) const; /** @return remaining data size to read or to write depending on the context * (request: write, answer: read) */ size_t getRemainingDataSize() const; + private: - CMessage(const CMessage&); - CMessage& operator=(const CMessage&); + bool isValidAccess(size_t offset, size_t size) const; /** Allocate room to store the message * @@ -123,11 +135,14 @@ private: uint8_t computeChecksum() const; // MsgId - uint8_t _ucMsgId; - // Data - uint8_t* _pucData; - /** Size of the allocated memory to store the message */ - size_t _uiDataSize; + MsgType _ucMsgId; + + size_t getMessageDataSize() const { return mData.size(); } + + using Data = std::vector<uint8_t>; + Data mData; /** Read/Write Index used to iterate across the message data */ size_t _uiIndex; + + static const uint16_t SYNC_WORD = 0xBABE; }; diff --git a/remote-processor/RemoteCommand.h b/remote-processor/RemoteCommand.h index fbc4fc6..025a133 100644 --- a/remote-processor/RemoteCommand.h +++ b/remote-processor/RemoteCommand.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -30,19 +30,25 @@ #pragma once #include <stdint.h> +#include <vector> #include <string> class IRemoteCommand { public: // Command Name - virtual const std::string& getCommand() const = 0; + virtual const std::string &getCommand() const = 0; // Arguments - virtual void addArgument(const std::string& strArgument) = 0; - virtual uint32_t getArgumentCount() const = 0; - virtual const std::string& getArgument(uint32_t uiArgument) const = 0; - virtual const std::string packArguments(uint32_t uiStartArgument, uint32_t uiNbArguments) const = 0; + virtual void addArgument(const std::string &strArgument) = 0; + virtual size_t getArgumentCount() const = 0; + virtual const std::string &getArgument(size_t argument) const = 0; + /** Get all the arguments in a vector + * + * @returns a reference to a vector containing all the arguments. + */ + virtual const std::vector<std::string> &getArguments() const = 0; + virtual const std::string packArguments(size_t startArgument, size_t nbArguments) const = 0; protected: virtual ~IRemoteCommand() {} diff --git a/remote-processor/RemoteCommandHandler.h b/remote-processor/RemoteCommandHandler.h index 170e424..29a9588 100644 --- a/remote-processor/RemoteCommandHandler.h +++ b/remote-processor/RemoteCommandHandler.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -36,8 +36,8 @@ class IRemoteCommandHandler { public: // Return true on success, fill result in any cases - virtual bool remoteCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult) = 0; + virtual bool remoteCommandProcess(const IRemoteCommand &remoteCommand, + std::string &strResult) = 0; -protected: virtual ~IRemoteCommandHandler() {} }; diff --git a/remote-processor/RemoteCommandHandlerTemplate.h b/remote-processor/RemoteCommandHandlerTemplate.h index 0b7428d..db59a5b 100644 --- a/remote-processor/RemoteCommandHandlerTemplate.h +++ b/remote-processor/RemoteCommandHandlerTemplate.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -37,11 +37,12 @@ class TRemoteCommandHandlerTemplate : public IRemoteCommandHandler { public: /** Remote command parser execution return status */ - enum CommandStatus { - EDone, /**< Command succeded, return "Done" */ + enum CommandStatus + { + EDone, /**< Command succeded, return "Done" */ ESucceeded, /**< Command succeeded */ - EFailed, /**< Command failed */ - EShowUsage /**< Command failed, show usage */ + EFailed, /**< Command failed */ + EShowUsage /**< Command failed, show usage */ }; /** Type of the remote command callbacks @@ -51,44 +52,35 @@ public: * * @return the command execution status, @see CommandStatus */ - typedef CommandStatus (CCommandParser::*RemoteCommandParser)(const IRemoteCommand& remoteCommand, std::string& strResult); + typedef CommandStatus (CCommandParser::*RemoteCommandParser)( + const IRemoteCommand &remoteCommand, std::string &strResult); private: // Parser descriptions class CRemoteCommandParserItem { public: - CRemoteCommandParserItem(const std::string& strCommandName, - RemoteCommandParser pfnParser, - uint32_t uiMinArgumentCount, - const std::string& strHelp, - const std::string& strDescription) - : _strCommandName(strCommandName), - _pfnParser(pfnParser), - _uiMinArgumentCount(uiMinArgumentCount), - _strHelp(strHelp), - _strDescription(strDescription) {} - - const std::string& getCommandName() const + CRemoteCommandParserItem(const std::string &strCommandName, RemoteCommandParser pfnParser, + size_t minArgumentCount, const std::string &strHelp, + const std::string &strDescription) + : _strCommandName(strCommandName), _pfnParser(pfnParser), + _minArgumentCount(minArgumentCount), _strHelp(strHelp), + _strDescription(strDescription) { - return _strCommandName; } - const std::string& getDescription() const - { - return _strDescription; - } + const std::string &getCommandName() const { return _strCommandName; } + + const std::string &getDescription() const { return _strDescription; } // Usage - std::string usage() const - { - return _strCommandName + " " + _strHelp; - } + std::string usage() const { return _strCommandName + " " + _strHelp; } - bool parse(CCommandParser* pCommandParser, const IRemoteCommand& remoteCommand, std::string& strResult) const + bool parse(CCommandParser *pCommandParser, const IRemoteCommand &remoteCommand, + std::string &strResult) const { // Check enough arguments supplied - if (remoteCommand.getArgumentCount() < _uiMinArgumentCount) { + if (remoteCommand.getArgumentCount() < _minArgumentCount) { strResult = std::string("Not enough arguments supplied\nUsage:\n") + usage(); @@ -98,12 +90,12 @@ private: switch ((pCommandParser->*_pfnParser)(remoteCommand, strResult)) { case EDone: strResult = "Done"; - // Fall through intentionally + // Fall through intentionally case ESucceeded: return true; case EShowUsage: strResult = usage(); - // Fall through intentionally + // Fall through intentionally case EFailed: return false; } @@ -114,33 +106,31 @@ private: private: std::string _strCommandName; RemoteCommandParser _pfnParser; - uint32_t _uiMinArgumentCount; + size_t _minArgumentCount; std::string _strHelp; std::string _strDescription; }; public: - TRemoteCommandHandlerTemplate(CCommandParser* pCommandParser) : _pCommandParser(pCommandParser), _uiMaxCommandUsageLength(0) + TRemoteCommandHandlerTemplate(CCommandParser *pCommandParser) + : _pCommandParser(pCommandParser), _maxCommandUsageLength(0) { // Help Command addCommandParser("help", NULL, 0, "", "Show commands description and usage"); } ~TRemoteCommandHandlerTemplate() { - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { + // FIXME use unique_ptr + for (auto *parser : _remoteCommandParserVector) { - delete _remoteCommandParserVector[uiIndex]; + delete parser; } } // Parsers - bool addCommandParser(const std::string& strCommandName, - RemoteCommandParser pfnParser, - uint32_t uiMinArgumentCount, - const std::string& strHelp, - const std::string& strDescription) + bool addCommandParser(const std::string &strCommandName, RemoteCommandParser pfnParser, + size_t minArgumentCount, const std::string &strHelp, + const std::string &strDescription) { if (findCommandParserItem(strCommandName)) { @@ -149,17 +139,19 @@ public: } // Add command - _remoteCommandParserVector.push_back(new CRemoteCommandParserItem(strCommandName, pfnParser, uiMinArgumentCount, strHelp, strDescription)); + _remoteCommandParserVector.push_back(new CRemoteCommandParserItem( + strCommandName, pfnParser, minArgumentCount, strHelp, strDescription)); return true; } private: // Command processing - bool remoteCommandProcess(const IRemoteCommand& remoteCommand, std::string& strResult) + bool remoteCommandProcess(const IRemoteCommand &remoteCommand, std::string &strResult) { // Dispatch - const CRemoteCommandParserItem* pRemoteCommandParserItem = findCommandParserItem(remoteCommand.getCommand()); + const CRemoteCommandParserItem *pRemoteCommandParserItem = + findCommandParserItem(remoteCommand.getCommand()); if (!pRemoteCommandParserItem) { @@ -182,19 +174,15 @@ private: // Max command usage length, use for formatting void initMaxCommandUsageLength() { - if (!_uiMaxCommandUsageLength) { + if (!_maxCommandUsageLength) { // Show usages - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { + for (const auto *pRemoteCommandParserItem : _remoteCommandParserVector) { - const CRemoteCommandParserItem* pRemoteCommandParserItem = _remoteCommandParserVector[uiIndex]; + size_t remoteCommandUsageLength = pRemoteCommandParserItem->usage().length(); - uint32_t uiRemoteCommandUsageLength = (uint32_t)pRemoteCommandParserItem->usage().length(); + if (remoteCommandUsageLength > _maxCommandUsageLength) { - if (uiRemoteCommandUsageLength > _uiMaxCommandUsageLength) { - - _uiMaxCommandUsageLength = uiRemoteCommandUsageLength; + _maxCommandUsageLength = remoteCommandUsageLength; } } } @@ -202,42 +190,26 @@ private: /////////////////// Remote command parsers /// Help - void helpCommandProcess(std::string& strResult) + void helpCommandProcess(std::string &strResult) { initMaxCommandUsageLength(); - strResult = "\n"; - // Show usages - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { - - const CRemoteCommandParserItem* pRemoteCommandParserItem = _remoteCommandParserVector[uiIndex]; + for (const auto *pRemoteCommandParserItem : _remoteCommandParserVector) { std::string strUsage = pRemoteCommandParserItem->usage(); - strResult += strUsage; - // Align - uint32_t uiToSpacesAdd = _uiMaxCommandUsageLength + 5 - (uint32_t)strUsage.length(); + size_t spacesToAdd = _maxCommandUsageLength + 5 - strUsage.length(); - while (uiToSpacesAdd--) { - - strResult += " "; - } - - strResult += std::string("=> ") + std::string(pRemoteCommandParserItem->getDescription()) + "\n"; + strResult += strUsage + std::string(spacesToAdd, ' ') + "=> " + + pRemoteCommandParserItem->getDescription() + '\n'; } } - const CRemoteCommandParserItem* findCommandParserItem(const std::string& strCommandName) const + const CRemoteCommandParserItem *findCommandParserItem(const std::string &strCommandName) const { - uint32_t uiIndex; - - for (uiIndex = 0; uiIndex < _remoteCommandParserVector.size(); uiIndex++) { - - const CRemoteCommandParserItem* pRemoteCommandParserItem = _remoteCommandParserVector[uiIndex]; + for (const auto *pRemoteCommandParserItem : _remoteCommandParserVector) { if (pRemoteCommandParserItem->getCommandName() == strCommandName) { @@ -248,8 +220,7 @@ private: } private: - CCommandParser* _pCommandParser; - std::vector<CRemoteCommandParserItem*> _remoteCommandParserVector; - uint32_t _uiMaxCommandUsageLength; + CCommandParser *_pCommandParser; + std::vector<CRemoteCommandParserItem *> _remoteCommandParserVector; + size_t _maxCommandUsageLength; }; - diff --git a/remote-processor/RemoteProcessorServer.cpp b/remote-processor/RemoteProcessorServer.cpp index e289d4e..d3fefdd 100644 --- a/remote-processor/RemoteProcessorServer.cpp +++ b/remote-processor/RemoteProcessorServer.cpp @@ -28,23 +28,19 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "RemoteProcessorServer.h" -#include "ListeningSocket.h" -#include "FullIo.hpp" #include <iostream> #include <memory> #include <assert.h> -#include <poll.h> -#include <unistd.h> #include <string.h> -#include <errno.h> #include "RequestMessage.h" #include "AnswerMessage.h" #include "RemoteCommandHandler.h" +#include "Socket.h" using std::string; -CRemoteProcessorServer::CRemoteProcessorServer(uint16_t uiPort, IRemoteCommandHandler* pCommandHandler) : - _uiPort(uiPort), _pCommandHandler(pCommandHandler), _bIsStarted(false), _pListeningSocket(NULL), _ulThreadId(0) +CRemoteProcessorServer::CRemoteProcessorServer(uint16_t uiPort) + : _uiPort(uiPort), _io_service(), _acceptor(_io_service), _socket(_io_service) { } @@ -56,132 +52,71 @@ CRemoteProcessorServer::~CRemoteProcessorServer() // State bool CRemoteProcessorServer::start(string &error) { - assert(!_bIsStarted); + using namespace asio; - if (pipe(_aiInbandPipe) == -1) { - error = "Could not create a pipe for remote processor communication: "; - error += strerror(errno); - return false; - } - - // Create server socket - std::auto_ptr<CListeningSocket> pListeningSocket(new CListeningSocket); + try { + ip::tcp::endpoint endpoint(ip::tcp::v6(), _uiPort); - if (!pListeningSocket->listen(_uiPort, error)) { - - return false; - } + _acceptor.open(endpoint.protocol()); - // Thread needs to access to the listning socket. - _pListeningSocket = pListeningSocket.get(); - // Create thread - errno = pthread_create(&_ulThreadId, NULL, thread_func, this); - if (errno != 0) { + _acceptor.set_option(ip::tcp::acceptor::reuse_address(true)); + _acceptor.set_option(asio::socket_base::linger(true, 0)); + _acceptor.set_option(socket_base::enable_connection_aborted(true)); - error = "Could not create a remote processor thread: "; - error += strerror(errno); + _acceptor.bind(endpoint); + _acceptor.listen(); + } catch (std::exception &e) { + error = "Unable to listen on port " + std::to_string(_uiPort) + ": " + e.what(); return false; } - // State - _bIsStarted = true; - pListeningSocket.release(); - return true; } -void CRemoteProcessorServer::stop() -{ - // Check state - if (!_bIsStarted) { - - return; - } - - // Cause exiting of the thread - uint8_t ucData = 0; - if (not utility::fullWrite(_aiInbandPipe[1], &ucData, sizeof(ucData))) { - std::cerr << "Could not query command processor thread to terminate: " - "fail to write on inband pipe: " - << strerror(errno) << std::endl; - assert(false); - } - - // Join thread - errno = pthread_join(_ulThreadId, NULL); - if (errno != 0) { - std::cout << "Could not join with remote processor thread: " - << strerror(errno) << std::endl; - assert(false); - } - - _bIsStarted = false; - - // Remove listening socket - delete _pListeningSocket; - _pListeningSocket = NULL; -} - -bool CRemoteProcessorServer::isStarted() const -{ - return _bIsStarted; -} - -// Thread -void* CRemoteProcessorServer::thread_func(void* pData) +bool CRemoteProcessorServer::stop() { - reinterpret_cast<CRemoteProcessorServer*>(pData)->run(); + _io_service.stop(); - return NULL; + return true; } -void CRemoteProcessorServer::run() +void CRemoteProcessorServer::acceptRegister(IRemoteCommandHandler &commandHandler) { - struct pollfd _aPollFds[2]; + auto peerHandler = [this, &commandHandler](asio::error_code ec) { + if (ec) { + std::cerr << "Accept failed: " << ec.message() << std::endl; + return; + } - bzero(_aPollFds, sizeof(_aPollFds)); + _socket.set_option(asio::ip::tcp::no_delay(true)); + handleNewConnection(commandHandler); - // Build poll elements - _aPollFds[0].fd = _pListeningSocket->getFd(); - _aPollFds[1].fd = _aiInbandPipe[0]; - _aPollFds[0].events = POLLIN; - _aPollFds[1].events = POLLIN; + _socket.close(); - while (true) { + acceptRegister(commandHandler); + }; - poll(_aPollFds, 2, -1); + _acceptor.async_accept(_socket, peerHandler); +} - if (_aPollFds[0].revents & POLLIN) { +bool CRemoteProcessorServer::process(IRemoteCommandHandler &commandHandler) +{ + acceptRegister(commandHandler); - // New incoming connection - handleNewConnection(); - } - if (_aPollFds[1].revents & POLLIN) { + asio::error_code ec; - // Consume exit request - uint8_t ucData; - if (not utility::fullRead(_aiInbandPipe[0], &ucData, sizeof(ucData))) { - std::cerr << "Remote processor could not receive exit request" - << strerror(errno) << std::endl; - assert(false); - } + _io_service.run(ec); - // Exit - return; - } + if (ec) { + std::cerr << "Server failed: " << ec.message() << std::endl; } + + return ec.value() == 0; } // New connection -void CRemoteProcessorServer::handleNewConnection() +void CRemoteProcessorServer::handleNewConnection(IRemoteCommandHandler &commandHandler) { - const std::auto_ptr<CSocket> clientSocket(_pListeningSocket->accept()); - - if (clientSocket.get() == NULL) { - - return; - } - // Process all incoming requests from the client while (true) { @@ -192,12 +127,12 @@ void CRemoteProcessorServer::handleNewConnection() string strError; ///// Receive command CRequestMessage::Result res; - res = requestMessage.serialize(clientSocket.get(), false, strError); + res = requestMessage.serialize(Socket(_socket), false, strError); switch (res) { case CRequestMessage::error: std::cout << "Error while receiving message: " << strError << std::endl; - // fall through + // fall through case CRequestMessage::peerDisconnected: // Consider peer disconnection as normal, no log return; // Bail out @@ -210,28 +145,19 @@ void CRemoteProcessorServer::handleNewConnection() string strResult; - if (_pCommandHandler) { - - bSuccess = _pCommandHandler->remoteCommandProcess(requestMessage, strResult); - - } else { - - strResult = "No handler!"; - - bSuccess = false; - } + bSuccess = commandHandler.remoteCommandProcess(requestMessage, strResult); // Send back answer // Create answer message CAnswerMessage answerMessage(strResult, bSuccess); ///// Send answer - res = answerMessage.serialize(clientSocket.get(), true, strError); + res = answerMessage.serialize(_socket, true, strError); switch (res) { case CRequestMessage::peerDisconnected: - // Peer should not disconnect while waiting for an answer - // Fall through to log the error and bail out + // Peer should not disconnect while waiting for an answer + // Fall through to log the error and bail out case CRequestMessage::error: std::cout << "Error while receiving message: " << strError << std::endl; return; // Bail out diff --git a/remote-processor/RemoteProcessorServer.h b/remote-processor/RemoteProcessorServer.h index 08f93e4..2da0113 100644 --- a/remote-processor/RemoteProcessorServer.h +++ b/remote-processor/RemoteProcessorServer.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * @@ -29,43 +29,35 @@ */ #pragma once +#include "remote_processor_export.h" + #include <stdint.h> -#include <pthread.h> #include "RemoteProcessorServerInterface.h" +#include <asio.hpp> -class CListeningSocket; class IRemoteCommandHandler; -class CRemoteProcessorServer : public IRemoteProcessorServerInterface +class REMOTE_PROCESSOR_EXPORT CRemoteProcessorServer : public IRemoteProcessorServerInterface { public: - CRemoteProcessorServer(uint16_t uiPort, IRemoteCommandHandler* pCommandHandler); + CRemoteProcessorServer(uint16_t uiPort); virtual ~CRemoteProcessorServer(); // State virtual bool start(std::string &error); - virtual void stop(); - virtual bool isStarted() const; + virtual bool stop(); + bool process(IRemoteCommandHandler &commandHandler); private: - // Thread - static void* thread_func(void* pData); - void run(); + void acceptRegister(IRemoteCommandHandler &commandHandler); // New connection - void handleNewConnection(); + void handleNewConnection(IRemoteCommandHandler &commandHandler); // Port number uint16_t _uiPort; - // Command handler - IRemoteCommandHandler* _pCommandHandler; - // State - bool _bIsStarted; - // Listening socket - CListeningSocket* _pListeningSocket; - // Inband pipe - int _aiInbandPipe[2]; - // Thread - pthread_t _ulThreadId; -}; + asio::io_service _io_service; + asio::ip::tcp::acceptor _acceptor; + asio::ip::tcp::socket _socket; +}; diff --git a/remote-processor/RemoteProcessorServerInterface.h b/remote-processor/RemoteProcessorServerInterface.h index 3ca3b76..889ff83 100644 --- a/remote-processor/RemoteProcessorServerInterface.h +++ b/remote-processor/RemoteProcessorServerInterface.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * @@ -36,8 +36,7 @@ class IRemoteProcessorServerInterface { public: virtual bool start(std::string &strError) = 0; - virtual void stop() = 0; - virtual bool isStarted() const = 0; + virtual bool stop() = 0; /* FIXME this was missing but is explicitly called */ virtual ~IRemoteProcessorServerInterface() {} diff --git a/remote-processor/RequestMessage.cpp b/remote-processor/RequestMessage.cpp index 3f1cdcc..0eb1e85 100644 --- a/remote-processor/RequestMessage.cpp +++ b/remote-processor/RequestMessage.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -28,7 +28,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "RequestMessage.h" -#include "RemoteProcessorProtocol.h" #include <assert.h> #include <algorithm> #include <ctype.h> @@ -37,9 +36,10 @@ using std::string; -const char* const CRequestMessage::gacDelimiters = " \t\n\v\f\r"; +const char *const CRequestMessage::gacDelimiters = " \t\n\v\f\r"; -CRequestMessage::CRequestMessage(const string& strCommand) : base(ECommandRequest), _strCommand(strCommand) +CRequestMessage::CRequestMessage(const string &strCommand) + : base(MsgType::ECommandRequest), _strCommand(strCommand) { } @@ -48,46 +48,50 @@ CRequestMessage::CRequestMessage() } // Command Name -void CRequestMessage::setCommand(const string& strCommand) +void CRequestMessage::setCommand(const string &strCommand) { _strCommand = trim(strCommand); } -const string& CRequestMessage::getCommand() const +const string &CRequestMessage::getCommand() const { return _strCommand; } // Arguments -void CRequestMessage::addArgument(const string& strArgument) +void CRequestMessage::addArgument(const string &strArgument) { _argumentVector.push_back(trim(strArgument)); } -uint32_t CRequestMessage::getArgumentCount() const +size_t CRequestMessage::getArgumentCount() const { return _argumentVector.size(); } -const string& CRequestMessage::getArgument(uint32_t uiArgument) const +const std::vector<string> &CRequestMessage::getArguments() const { - assert(uiArgument < _argumentVector.size()); + return _argumentVector; +} + +const string &CRequestMessage::getArgument(size_t argument) const +{ + assert(argument < _argumentVector.size()); - return _argumentVector[uiArgument]; + return _argumentVector[argument]; } -const string CRequestMessage::packArguments(uint32_t uiStartArgument, uint32_t uiNbArguments) const +const string CRequestMessage::packArguments(size_t uiStartArgument, size_t uiNbArguments) const { string strPackedArguments; assert(uiStartArgument + uiNbArguments <= _argumentVector.size()); // Pack arguments, separating them with a space - uint32_t uiArgument; - bool bFirst = true; - for (uiArgument = uiStartArgument; uiArgument < uiStartArgument + uiNbArguments; uiArgument++) { + for (size_t argument = uiStartArgument; argument < uiStartArgument + uiNbArguments; + argument++) { if (!bFirst) { @@ -97,7 +101,7 @@ const string CRequestMessage::packArguments(uint32_t uiStartArgument, uint32_t u bFirst = false; } - strPackedArguments += _argumentVector[uiArgument]; + strPackedArguments += _argumentVector[argument]; } return strPackedArguments; @@ -110,11 +114,9 @@ void CRequestMessage::fillDataToSend() writeString(getCommand()); // Arguments - uint32_t uiArgument; - - for (uiArgument = 0; uiArgument < getArgumentCount(); uiArgument++) { + for (size_t argument = 0; argument < getArgumentCount(); argument++) { - writeString(getArgument(uiArgument)); + writeString(getArgument(argument)); } } @@ -146,9 +148,7 @@ size_t CRequestMessage::getDataSize() const size_t uiSize = getStringSize(getCommand()); // Arguments - uint32_t uiArgument; - - for (uiArgument = 0; uiArgument < getArgumentCount(); uiArgument++) { + for (size_t uiArgument = 0; uiArgument < getArgumentCount(); uiArgument++) { uiSize += getStringSize(getArgument(uiArgument)); } @@ -156,12 +156,12 @@ size_t CRequestMessage::getDataSize() const } // Trim input string -string CRequestMessage::trim(const string& strToTrim) +string CRequestMessage::trim(const string &strToTrim) { // Trim string string strTrimmed = strToTrim; - strTrimmed.erase(strTrimmed.find_last_not_of(gacDelimiters) + 1 ); + strTrimmed.erase(strTrimmed.find_last_not_of(gacDelimiters) + 1); strTrimmed.erase(0, strTrimmed.find_first_not_of(gacDelimiters)); diff --git a/remote-processor/RequestMessage.h b/remote-processor/RequestMessage.h index 7a30aaa..7c78db6 100644 --- a/remote-processor/RequestMessage.h +++ b/remote-processor/RequestMessage.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -29,35 +29,37 @@ */ #pragma once +#include "remote_processor_export.h" + #include "Message.h" #include "RemoteCommand.h" #include <vector> #include <string> -class CRequestMessage : public CMessage, public IRemoteCommand +class REMOTE_PROCESSOR_EXPORT CRequestMessage : public CMessage, public IRemoteCommand { public: - CRequestMessage(const std::string& strCommand); + CRequestMessage(const std::string &strCommand); CRequestMessage(); // Command Name - void setCommand(const std::string& strCommand); - virtual const std::string& getCommand() const; + void setCommand(const std::string &strCommand); + virtual const std::string &getCommand() const; // Arguments - virtual void addArgument(const std::string& strArgument); - virtual uint32_t getArgumentCount() const; - virtual const std::string& getArgument(uint32_t uiArgument) const; - virtual const std::string packArguments(uint32_t uiStartArgument, uint32_t uiNbArguments) const; + virtual void addArgument(const std::string &strArgument); + virtual size_t getArgumentCount() const; + virtual const std::string &getArgument(size_t argument) const; + virtual const std::vector<std::string> &getArguments() const; + virtual const std::string packArguments(size_t startArgument, size_t nbArguments) const; private: - /** * Constant character array. * This value defines the delimiters used to separate the arguments * in the request command. */ - static const char* const gacDelimiters; + static const char *const gacDelimiters; // Fill data to send virtual void fillDataToSend(); @@ -69,11 +71,10 @@ private: */ virtual size_t getDataSize() const; // Trim input std::string - static std::string trim(const std::string& strToTrim); + static std::string trim(const std::string &strToTrim); // Command std::string _strCommand; // Arguments std::vector<std::string> _argumentVector; }; - diff --git a/remote-processor/Socket.cpp b/remote-processor/Socket.cpp deleted file mode 100644 index 0aec7a2..0000000 --- a/remote-processor/Socket.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2011-2014, 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 "Socket.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <unistd.h> -#include <assert.h> -#include <netdb.h> -#include <strings.h> -#include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <sys/time.h> -#include <signal.h> - -CSocket::CSocket() : _iSockFd(socket(AF_INET, SOCK_STREAM, 0)), mSendFlag(0) -{ - assert(_iSockFd != -1); - - int iNoDelay = 1; - // (see man 7 tcp) - // Setting TCP_NODELAY allows us sending commands and responses as soon as - // they are ready to be sent, instead of waiting for more data on the - // socket. - setsockopt(_iSockFd, IPPROTO_TCP, TCP_NODELAY, (char *)&iNoDelay, sizeof(iNoDelay)); - - // Disable sigpipe reception on send -# if not defined(SIGPIPE) - // Pipe signal does not exist, there no sigpipe to ignore on send -# elif defined(SO_NOSIGPIPE) - const int set = 1; - setsockopt(_iSockFd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set)); -# elif defined(MSG_NOSIGNAL) - // Use flag NOSIGNAL on send call - mSendFlag = MSG_NOSIGNAL; -# else -# error Can not disable SIGPIPE -# endif -} - -CSocket::CSocket(int iSockId) : _iSockFd(iSockId) -{ - assert(_iSockFd != -1); -} - -CSocket::~CSocket() -{ - // fd might be invalide if send had an error. - // valgrind displays a warning if closing an invalid fd. - if (_iSockFd != -1) { - close(_iSockFd); - } -} - -// Socket address init -void CSocket::initSockAddrIn(struct sockaddr_in* pSockAddrIn, uint32_t uiInAddr, uint16_t uiPort) const -{ - // Fill server address - pSockAddrIn->sin_family = AF_INET; - pSockAddrIn->sin_port = htons(uiPort); - pSockAddrIn->sin_addr.s_addr = uiInAddr; - bzero(&pSockAddrIn->sin_zero, sizeof(pSockAddrIn->sin_zero)); -} - -// Non blocking state -void CSocket::setNonBlocking(bool bNonBlocking) -{ - int iFlags = fcntl(_iSockFd, F_GETFL, 0); - - assert(iFlags != -1); - - if (bNonBlocking) { - - iFlags |= O_NONBLOCK; - } else { - - iFlags &= ~O_NONBLOCK; - } - fcntl(_iSockFd, F_SETFL, iFlags); -} - -// Communication timeout -void CSocket::setTimeout(uint32_t uiMilliseconds) -{ - struct timeval tv; - tv.tv_sec = uiMilliseconds / 1000; - tv.tv_usec = (uiMilliseconds % 1000) * 1000; - - setsockopt(_iSockFd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - setsockopt(_iSockFd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); -} - -// Read -bool CSocket::read(void* pvData, uint32_t uiSize) -{ - uint32_t uiOffset = 0; - uint8_t* pucData = (uint8_t*)pvData; - - while (uiSize) { - - int32_t iAccessedSize = ::recv(_iSockFd, &pucData[uiOffset], uiSize, 0); - - switch (iAccessedSize) { - case 0: - // recv return value is 0 when the peer has performed an orderly shutdown. - _disconnected = true; - errno = ECONNRESET; // Warn the client that the client disconnected. - return false; - - case -1: - // errno == EINTR => The recv system call was interrupted, try again - if (errno != EINTR) { - return false; - } - break; - - default: - uiSize -= iAccessedSize; - uiOffset += iAccessedSize; - } - } - return true; -} - -// Write -bool CSocket::write(const void* pvData, uint32_t uiSize) -{ - uint32_t uiOffset = 0; - const uint8_t* pucData = (const uint8_t*)pvData; - - while (uiSize) { - - int32_t iAccessedSize = ::send(_iSockFd, &pucData[uiOffset], uiSize, mSendFlag); - - if (iAccessedSize == -1) { - if (errno == EINTR) { - // The send system call was interrupted, try again - continue; - } - - // An error occured, forget this socket - _disconnected = true; - close(_iSockFd); - _iSockFd = -1; // Avoid writing again on the same socket - return false; - } else { - uiSize -= iAccessedSize; - uiOffset += iAccessedSize; - } - } - return true; -} - -// Fd -int CSocket::getFd() const -{ - return _iSockFd; -} - -bool CSocket::hasPeerDisconnected() { - return _disconnected; -} diff --git a/remote-processor/Socket.h b/remote-processor/Socket.h index 8c3fb9f..020750b 100644 --- a/remote-processor/Socket.h +++ b/remote-processor/Socket.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,86 +27,21 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma once +#include <asio.hpp> -#include <string> -#include <stdint.h> - -struct sockaddr_in; -struct in_addr; - -/** Readable and writable socket. +/** Wraps and hides asio::ip::tcp::socket * - * The class does not encapsulate completely it's internal file descriptor as - * it can be retrieve by the getFd method. - * - * This "feature" means that it's state consistency can not - * be enforced by the class but rather by clients. + * asio::ip::tcp::socket cannot be forward-declared because it is an + * inner-class. This class wraps the asio class in order for it to be + * forward-declared and avoid it to leak in client interfaces. */ -class CSocket +class Socket { public: - CSocket(); - CSocket(int iSockId); - virtual ~CSocket(); - - // Non blocking state - void setNonBlocking(bool bNonBlocking); - - // Communication timeout - void setTimeout(uint32_t uiMilliseconds); - - /* Read data - * - * On failure errno will be set appropriately (see send). - * If the client disconnects, false will be returned and - * - hasPeerDisconnected will return true - * - errno is set to ECONNRESET. - * @param[in] pvData - on success: will contain the sent data - * - on failure: undefined - * @param[in] uiSize size of the data to receive. - * - * @return true if all data could be read, false otherwise. - */ - bool read(void* pvData, uint32_t uiSize); - - /* Write data - * - * On failure errno will be set (see recv) - * @param[in] pvData data to send. - * @param[in] uiSize is the size of the data to send. - * - * @return true if all data could be read, false otherwise. - */ - bool write(const void* pvData, uint32_t uiSize); - - /** @return the managed file descriptor. - * - * The client can then bind/connect/accept/listen/... the socket. - */ - int getFd() const; + Socket(asio::ip::tcp::socket &socket) : mSocket(socket) {} - /** @return true if the peer has disconnected. - * - * The internal fd is returned by getFd and clients can use it for - * bind/connect/read/write/... as a result it's state can not be tracked. - * - * Thus hasPeerDisconnected returns true only if the disconnection - * was notified during a call to CSocket::write or CSocket::read. - */ - bool hasPeerDisconnected(); + asio::ip::tcp::socket &get() { return mSocket; } -protected: - // Socket address init - void initSockAddrIn(struct sockaddr_in* pSockAddrIn, uint32_t uiInAddr, uint16_t uiPort) const; private: - int _iSockFd; - /** If the peer disconnected. - * - * This is not the state of _iSockFd (connected/disconnected) - * - * See hasPeerDisconnected for more details. - */ - bool _disconnected; - int mSendFlag; + asio::ip::tcp::socket &mSocket; }; diff --git a/schemas/CMakeLists.txt b/schemas/CMakeLists.txt new file mode 100644 index 0000000..ba876fe --- /dev/null +++ b/schemas/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) 2014, 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. + +install(FILES ComponentLibrary.xsd + ComponentTypeSet.xsd + ConfigurableDomains.xsd + ConfigurableDomain.xsd + FileIncluder.xsd + ParameterFrameworkConfiguration.xsd + ParameterSettings.xsd + Parameter.xsd + Subsystem.xsd + SystemClass.xsd + W3cXmlAttributes.xsd + DESTINATION share/${PROJECT_NAME}/schemas) diff --git a/Schemas/ComponentLibrary.xsd b/schemas/ComponentLibrary.xsd index fbd70af..fbd70af 100644 --- a/Schemas/ComponentLibrary.xsd +++ b/schemas/ComponentLibrary.xsd diff --git a/Schemas/ComponentTypeSet.xsd b/schemas/ComponentTypeSet.xsd index ec58eba..ec58eba 100644 --- a/Schemas/ComponentTypeSet.xsd +++ b/schemas/ComponentTypeSet.xsd diff --git a/Schemas/ConfigurableDomain.xsd b/schemas/ConfigurableDomain.xsd index 8683192..8683192 100644 --- a/Schemas/ConfigurableDomain.xsd +++ b/schemas/ConfigurableDomain.xsd diff --git a/Schemas/ConfigurableDomains.xsd b/schemas/ConfigurableDomains.xsd index 67e6b0f..67e6b0f 100644 --- a/Schemas/ConfigurableDomains.xsd +++ b/schemas/ConfigurableDomains.xsd diff --git a/Schemas/FileIncluder.xsd b/schemas/FileIncluder.xsd index 62593b2..62593b2 100644 --- a/Schemas/FileIncluder.xsd +++ b/schemas/FileIncluder.xsd diff --git a/Schemas/Parameter.xsd b/schemas/Parameter.xsd index 14f7629..6ec78b4 100644 --- a/Schemas/Parameter.xsd +++ b/schemas/Parameter.xsd @@ -10,6 +10,7 @@ </xs:attributeGroup> <xs:complexType name="ComponentInstance"> <xs:attributeGroup ref="TypedNameable"/> + <xs:attributeGroup ref="ArrayLengthAttribute"/> <xs:attribute name="Mapping" use="optional"/> </xs:complexType> <xs:simpleType name="SizeType"> @@ -112,17 +113,38 @@ <xs:field xpath="@Numerical"/> </xs:unique> </xs:element> - <xs:complexType name="FixedPointParameterType"> + <xs:simpleType name="PointBound"> + <xs:restriction base="xs:string"> + <xs:pattern value="(0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="PointParameterType"> <xs:complexContent> <xs:extension base="Parameter"> + <xs:attribute name="Unit" type="xs:token" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:complexType name="FixedPointParameterType"> + <xs:complexContent> + <xs:extension base="PointParameterType"> <xs:attribute name="Size" type="SizeType" use="required"/> <xs:attribute name="Integral" type="xs:nonNegativeInteger" use="required"/> <xs:attribute name="Fractional" type="xs:nonNegativeInteger" use="required"/> - <xs:attribute name="Unit" type="xs:token" use="optional"/> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="FixedPointParameter" type="FixedPointParameterType"/> + <xs:complexType name="FloatingPointParameterType"> + <xs:complexContent> + <xs:extension base="PointParameterType"> + <xs:attribute name="Size" fixed="32"/> + <xs:attribute name="Min" type="PointBound" use="optional"/> + <xs:attribute name="Max" type="PointBound" use="optional"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <xs:element name="FloatingPointParameter" type="FloatingPointParameterType"/> <xs:complexType name="BitParameterType"> <xs:attributeGroup ref="Nameable"/> <xs:attribute name="Size" use="required"> @@ -168,6 +190,7 @@ <xs:element ref="IntegerParameter"/> <xs:element ref="EnumParameter"/> <xs:element ref="FixedPointParameter"/> + <xs:element ref="FloatingPointParameter"/> <xs:element ref="BitParameterBlock"/> <xs:element ref="StringParameter"/> <xs:element name="Component" type="ComponentInstance"/> diff --git a/Schemas/ParameterFrameworkConfiguration.xsd b/schemas/ParameterFrameworkConfiguration.xsd index 8ece70d..522b806 100644 --- a/Schemas/ParameterFrameworkConfiguration.xsd +++ b/schemas/ParameterFrameworkConfiguration.xsd @@ -23,7 +23,6 @@ <xs:complexType name="SettingsConfigurationType"> <xs:sequence> <xs:element name="ConfigurableDomainsFileLocation" type="ConfigurationFilePath"/> - <xs:element name="BinarySettingsFileLocation" type="ConfigurationFilePath" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:element name="ParameterFrameworkConfiguration"> diff --git a/Schemas/ParameterSettings.xsd b/schemas/ParameterSettings.xsd index 5ebe495..d95a17d 100644 --- a/Schemas/ParameterSettings.xsd +++ b/schemas/ParameterSettings.xsd @@ -40,10 +40,10 @@ </xs:restriction> </xs:simpleContent> </xs:complexType> - <xs:complexType name="FixedPointParameterType"> + <xs:complexType name="PointParameterType"> <xs:simpleContent> <xs:restriction base="ParameterType"> - <xs:pattern value="((0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))(e[+-]?[0-9]+)?)(\s+(0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))(e[+-]?[0-9]+)?)*"/> + <xs:pattern value="((0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?)(\s+(0|[+-]?0\.[0-9]+|(([+-]?[1-9][0-9]*)(\.[0-9]+)?))([Ee][+-]?[0-9]+)?)*"/> <xs:pattern value="(0x[0-9a-fA-F]+)(\s+(0x[0-9a-fA-F]+))*"/> </xs:restriction> </xs:simpleContent> @@ -66,7 +66,8 @@ <xs:element name="BooleanParameter" type="BooleanParameterType"/> <xs:element name="IntegerParameter" type="IntegerParameterType"/> <xs:element name="EnumParameter" type="EnumParameterType"/> - <xs:element name="FixedPointParameter" type="FixedPointParameterType"/> + <xs:element name="FixedPointParameter" type="PointParameterType"/> + <xs:element name="FloatingPointParameter" type="PointParameterType"/> <xs:element name="BitParameterBlock" type="BitParameterBlockType"> <xs:unique name="BitParameterBlockSubElementsUniqueness"> <xs:selector xpath="*"/> diff --git a/Schemas/README.md b/schemas/README.md index 5d04fad..f634d8c 100644 --- a/Schemas/README.md +++ b/schemas/README.md @@ -66,7 +66,6 @@ A Subsystem has the following attribute: which case, no plugin will be used and the parameters won't be synchronized. This is useful for debugging but may also be used for the parameter-framework to act as a configurable settings database; -- `Endianness`: `Little` or `Big`; - `Mapping` (optional), defines a Mapping to be inherited by all Components in the Subsystem. diff --git a/Schemas/Subsystem.xsd b/schemas/Subsystem.xsd index d418af7..2ba898e 100644 --- a/Schemas/Subsystem.xsd +++ b/schemas/Subsystem.xsd @@ -20,14 +20,6 @@ </xs:element> </xs:sequence> <xs:attributeGroup ref="Nameable"/> - <xs:attribute name="Endianness" use="required"> - <xs:simpleType> - <xs:restriction base="xs:NMTOKEN"> - <xs:enumeration value="Little"/> - <xs:enumeration value="Big"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> <xs:attribute name="Type" use="required"/> <xs:attribute name="Mapping" use="optional"/> </xs:complexType> diff --git a/Schemas/SystemClass.xsd b/schemas/SystemClass.xsd index 5aa32db..5aa32db 100644 --- a/Schemas/SystemClass.xsd +++ b/schemas/SystemClass.xsd diff --git a/Schemas/W3cXmlAttributes.xsd b/schemas/W3cXmlAttributes.xsd index 4b2500c..4b2500c 100644 --- a/Schemas/W3cXmlAttributes.xsd +++ b/schemas/W3cXmlAttributes.xsd diff --git a/skeleton-subsystem/CMakeLists.txt b/skeleton-subsystem/CMakeLists.txt index 6a83223..1ec822d 100644 --- a/skeleton-subsystem/CMakeLists.txt +++ b/skeleton-subsystem/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,34 +26,52 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# has been tested on 2.8 only - might work on older versions -cmake_minimum_required(VERSION 2.8) +# working on 2.8.12 - broken on older versions +cmake_minimum_required(VERSION 2.8.12) project(parameter-framework-plugins-skeleton) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra") +if(WIN32) + # Force include iso646.h to support alternative operator form (and, or, not...) + # Such support is require by the standard and can be enabled with /Za + # but doing so breaks compilation of windows headers... + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /FIiso646.h") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Werror -Wall -Wextra -Wconversion") +endif() + +# Hide symbols by default, then exposed symbols are the same in linux and windows +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN true) + +# Force libs and executable to all be at a known place - simplifies a lot of +# things, expecially setting the test environment +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) # # Find PFW libraries and include directories # -find_path(PFW_CORE_ROOT_DIR NAMES include/parameter/plugin/Subsystem.h) +find_path(PFW_INCLUDE_ROOT NAMES parameter/plugin/Plugin.h) -find_library(PFW_CORE_LIBRARY NAMES parameter - HINTS ${PFW_CORE_ROOT_DIR}/lib) +find_library(PFW_CORE_LIBRARY NAMES parameter) -find_path(PFW_CORE_INCLUDE_DIR NAMES Subsystem.h - HINTS ${PFW_CORE_ROOT_DIR}/include/parameter/plugin) -find_path(PFW_XMLSERIALIZER_INCLUDE_DIR NAMES XmlSink.h - HINTS ${PFW_CORE_ROOT_DIR}/include/xmlserializer) +set(PFW_INCLUDE_DIRS + ${PFW_INCLUDE_ROOT}/parameter/plugin + ${PFW_INCLUDE_ROOT}/xmlserializer + ${PFW_INCLUDE_ROOT}/utility) -set(PFW_INCLUDE_DIRS ${PFW_CORE_INCLUDE_DIR} ${PFW_XMLSERIALIZER_INCLUDE_DIR}) -set(PFW_LIBRARIES ${PFW_CORE_LIBRARY}) - -add_library(skeleton-subsystem SHARED +add_library(skeleton-subsystem MODULE SkeletonSubsystemBuilder.cpp SkeletonSubsystem.cpp SkeletonSubsystemObject.cpp) -include_directories(${PFW_INCLUDE_DIRS}) +target_include_directories(skeleton-subsystem PRIVATE ${PFW_INCLUDE_DIRS}) +target_link_libraries(skeleton-subsystem ${PFW_CORE_LIBRARY}) + +install(TARGETS skeleton-subsystem + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) -install(TARGETS skeleton-subsystem LIBRARY DESTINATION lib) +include(../ctest/CMakeLists.txt) +add_subdirectory(test) diff --git a/skeleton-subsystem/SkeletonMappingKeys.h b/skeleton-subsystem/SkeletonMappingKeys.h index 19caa4c..f1b0962 100644 --- a/skeleton-subsystem/SkeletonMappingKeys.h +++ b/skeleton-subsystem/SkeletonMappingKeys.h @@ -30,7 +30,8 @@ #pragma once // Mapping item types -enum SkeletonItemType { +enum SkeletonItemType +{ ESkeletonOwner, EAmend1, EAmend2, diff --git a/skeleton-subsystem/SkeletonSubsystem.cpp b/skeleton-subsystem/SkeletonSubsystem.cpp index e3cbcba..227d71a 100644 --- a/skeleton-subsystem/SkeletonSubsystem.cpp +++ b/skeleton-subsystem/SkeletonSubsystem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -35,7 +35,8 @@ #define base CSubsystem // Implementation -CSkeletonSubsystem::CSkeletonSubsystem(const std::string& strName) : base(strName) +CSkeletonSubsystem::CSkeletonSubsystem(const std::string &strName, core::log::Logger &logger) + : base(strName, logger) { // Provide mapping keys to upper layer addContextMappingKey("Owner"); @@ -43,5 +44,6 @@ CSkeletonSubsystem::CSkeletonSubsystem(const std::string& strName) : base(strNam addContextMappingKey("Amend2"); // Provide creators to upper layer - addSubsystemObjectFactory(new TSubsystemObjectFactory<CSkeletonSubsystemObject>("Message", 1 << ESkeletonOwner)); + addSubsystemObjectFactory( + new TSubsystemObjectFactory<CSkeletonSubsystemObject>("Message", 1 << ESkeletonOwner)); } diff --git a/skeleton-subsystem/SkeletonSubsystem.h b/skeleton-subsystem/SkeletonSubsystem.h index 26cd659..276562e 100644 --- a/skeleton-subsystem/SkeletonSubsystem.h +++ b/skeleton-subsystem/SkeletonSubsystem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -34,7 +34,5 @@ class CSkeletonSubsystem : public CSubsystem { public: - CSkeletonSubsystem(const std::string& strName); - + CSkeletonSubsystem(const std::string &strName, core::log::Logger &logger); }; - diff --git a/skeleton-subsystem/SkeletonSubsystemBuilder.cpp b/skeleton-subsystem/SkeletonSubsystemBuilder.cpp index a6aae2d..5a8647e 100644 --- a/skeleton-subsystem/SkeletonSubsystemBuilder.cpp +++ b/skeleton-subsystem/SkeletonSubsystemBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,24 +27,13 @@ * (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 "SubsystemLibrary.h" -#include "NamedElementBuilderTemplate.h" +#include "Plugin.h" +#include "LoggingElementBuilderTemplate.h" #include "SkeletonSubsystem.h" - -extern "C" +void PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1(CSubsystemLibrary *pSubsystemLibrary, + core::log::Logger &logger) { -/** - * CARE: the naming convention used in the parameter framework: - * - * A plugin file name is of the form: - * lib<type>-subsystem.so or lib<type>-subsystem._host.so - * - * The plugin symbol is of the form: - * get<TYPE>SubsystemBuilder -*/ -void getSKELETONSubsystemBuilder(CSubsystemLibrary* pSubsystemLibrary) -{ - pSubsystemLibrary->addElementBuilder("Skeleton", new TNamedElementBuilderTemplate<CSkeletonSubsystem>()); -} + pSubsystemLibrary->addElementBuilder( + "Skeleton", new TLoggingElementBuilderTemplate<CSkeletonSubsystem>(logger)); } diff --git a/skeleton-subsystem/SkeletonSubsystemObject.cpp b/skeleton-subsystem/SkeletonSubsystemObject.cpp index 5ecded9..8f696a0 100644 --- a/skeleton-subsystem/SkeletonSubsystemObject.cpp +++ b/skeleton-subsystem/SkeletonSubsystemObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -46,41 +46,36 @@ using std::string; CSkeletonSubsystemObject::CSkeletonSubsystemObject( - const string& strMappingValue, - CInstanceConfigurableElement* pInstanceConfigurableElement, - const CMappingContext& context - ) : - base(pInstanceConfigurableElement, - strMappingValue, - EAmend1, - EAmendEnd - EAmend1 + 1, - context), - _bWrongElementTypeError(false) + const string &strMappingValue, CInstanceConfigurableElement *pInstanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger) + : base(pInstanceConfigurableElement, logger, strMappingValue, EAmend1, EAmendEnd - EAmend1 + 1, + context), + _bWrongElementTypeError(false) { // Get actual element type - const CParameterType* pParameterType = static_cast<const CParameterType*>(pInstanceConfigurableElement->getTypeElement()); + const CParameterType *pParameterType = + static_cast<const CParameterType *>(pInstanceConfigurableElement->getTypeElement()); // Retrieve sizes - _uiScalarSize = pParameterType->getSize(); - _uiArraySize = pInstanceConfigurableElement->getFootPrint() / _uiScalarSize; + _scalarSize = pParameterType->getSize(); + _arraySize = pInstanceConfigurableElement->getFootPrint() / _scalarSize; // Construct message - _strMessage = context.getItem(ESkeletonOwner) + ":" + strMappingValue ; + _strMessage = context.getItem(ESkeletonOwner) + ":" + strMappingValue; // Handle types // Check we are able to handle elements (no exception support, defer the error) - switch(pInstanceConfigurableElement->getType()) { + switch (pInstanceConfigurableElement->getType()) { - case CInstanceConfigurableElement::EParameter: - break; - default: - _bWrongElementTypeError = true; - break; + case CInstanceConfigurableElement::EParameter: + break; + default: + _bWrongElementTypeError = true; + break; } - } // Sync to/from HW -bool CSkeletonSubsystemObject::accessHW(bool bReceive, string& strError) +bool CSkeletonSubsystemObject::accessHW(bool bReceive, string &strError) { // Check parameter type is ok (deferred error, no exceptions available :-() if (_bWrongElementTypeError) { @@ -93,18 +88,14 @@ bool CSkeletonSubsystemObject::accessHW(bool bReceive, string& strError) return base::accessHW(bReceive, strError); } -bool CSkeletonSubsystemObject::sendToHW(string& strError) +bool CSkeletonSubsystemObject::sendToHW(string & /*strError*/) { - (void) strError; - - uint32_t uiIndex; - - void* pvValue = alloca(_uiScalarSize); + void *pvValue = alloca(_scalarSize); - for (uiIndex = 0 ; uiIndex < _uiArraySize ; uiIndex++) { + for (size_t index = 0; index < _arraySize; index++) { // Read Value in BlackBoard - blackboardRead(pvValue, _uiScalarSize); + blackboardRead(pvValue, _scalarSize); // Send here the value std::cout << "Sending to HW: " << _strMessage << std::endl; @@ -113,21 +104,17 @@ bool CSkeletonSubsystemObject::sendToHW(string& strError) return true; } -bool CSkeletonSubsystemObject::receiveFromHW(string& strError) +bool CSkeletonSubsystemObject::receiveFromHW(string & /*strError*/) { - (void) strError; - - uint32_t uiIndex; - - void* pvValue = alloca(_uiScalarSize); + void *pvValue = alloca(_scalarSize); - for (uiIndex = 0 ; uiIndex < _uiArraySize ; uiIndex++) { + for (size_t index = 0; index < _arraySize; index++) { // Retreive here the value std::cout << "Retreive from HW: " << _strMessage << std::endl; // Write Value in Blackboard - blackboardWrite(pvValue, _uiScalarSize); + blackboardWrite(pvValue, _scalarSize); } return true; diff --git a/skeleton-subsystem/SkeletonSubsystemObject.h b/skeleton-subsystem/SkeletonSubsystemObject.h index f292774..f4c09c9 100644 --- a/skeleton-subsystem/SkeletonSubsystemObject.h +++ b/skeleton-subsystem/SkeletonSubsystemObject.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -36,22 +36,24 @@ class CMappingContext; class CSkeletonSubsystemObject : public CFormattedSubsystemObject { public: - CSkeletonSubsystemObject(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context); + CSkeletonSubsystemObject(const std::string &strMappingValue, + CInstanceConfigurableElement *pInstanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger); protected: // from CSubsystemObject // Sync to/from HW - virtual bool sendToHW(std::string& strError); - virtual bool receiveFromHW(std::string& strError); + virtual bool sendToHW(std::string &strError); + virtual bool receiveFromHW(std::string &strError); private: // Sync to/from HW - virtual bool accessHW(bool bReceive, std::string& strError); + virtual bool accessHW(bool bReceive, std::string &strError); protected: // Scalar parameter size for elementary access - uint32_t _uiScalarSize; - uint32_t _uiArraySize; + size_t _scalarSize; + size_t _arraySize; std::string _strMessage; // Delayed error about supported parameter types (always false in this example) bool _bWrongElementTypeError; diff --git a/skeleton-subsystem/test/CMakeLists.txt b/skeleton-subsystem/test/CMakeLists.txt new file mode 100644 index 0000000..46cb669 --- /dev/null +++ b/skeleton-subsystem/test/CMakeLists.txt @@ -0,0 +1,39 @@ +# 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. + +configure_file(structure.xml "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) +configure_file(toplevel.xml "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) + +add_executable(skeleton-test main.cpp) +target_include_directories(skeleton-test PRIVATE "${PFW_INCLUDE_ROOT}/parameter/client") +target_link_libraries(skeleton-test "${PFW_CORE_LIBRARY}") + +add_test(NAME skeleton-test + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + COMMAND skeleton-test) +set_test_env(skeleton-test) diff --git a/skeleton-subsystem/test/main.cpp b/skeleton-subsystem/test/main.cpp new file mode 100644 index 0000000..43a9d6f --- /dev/null +++ b/skeleton-subsystem/test/main.cpp @@ -0,0 +1,55 @@ +/* + * 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 <ParameterMgrFullConnector.h> + +#include <iostream> + +class MyLogger final : public CParameterMgrFullConnector::ILogger +{ +public: + void info(const std::string &log) override { std::cout << "Info: " << log << std::endl; } + + void warning(const std::string &log) override { std::cerr << "Warning: " << log << std::endl; } +}; + +int main(void) +{ + MyLogger logger; + CParameterMgrFullConnector instance("toplevel.xml"); + instance.setLogger(&logger); + + std::string errorMsg; + if (not instance.start(errorMsg)) { + std::cout << "Failed to start: " << errorMsg << std::endl; + return 1; + } + + return 0; +} diff --git a/skeleton-subsystem/test/structure.xml b/skeleton-subsystem/test/structure.xml new file mode 100644 index 0000000..58e15c3 --- /dev/null +++ b/skeleton-subsystem/test/structure.xml @@ -0,0 +1,9 @@ +<SystemClass Name="class"> + <Subsystem Name="subsystem" Type="Skeleton"> + <ComponentLibrary> + </ComponentLibrary> + <InstanceDefinition> + <BooleanParameter Name="parameter"/> + </InstanceDefinition> + </Subsystem> +</SystemClass> diff --git a/skeleton-subsystem/test/toplevel.xml b/skeleton-subsystem/test/toplevel.xml new file mode 100644 index 0000000..b15d4b0 --- /dev/null +++ b/skeleton-subsystem/test/toplevel.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ParameterFrameworkConfiguration SystemClassName="class" ServerPort="1" TuningAllowed="false"> + <SubsystemPlugins> + <Location Folder=""> + <Plugin Name="skeleton-subsystem"/> + </Location> + </SubsystemPlugins> + <StructureDescriptionFileLocation Path="structure.xml"/> +</ParameterFrameworkConfiguration> diff --git a/support/android/build_pfw_settings.mk b/support/android/build_pfw_settings.mk deleted file mode 100644 index e51adfd..0000000 --- a/support/android/build_pfw_settings.mk +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2014-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. - -LOCAL_MODULE_CLASS := ETC -LOCAL_MODULE_TAGS := optional - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): MY_TOOL := $(HOST_OUT)/bin/domainGenerator.py -# As of Android K, python is available as prebuilt. We can't reliably use the -# host's default python because the low-level python binding has been compiled -# against Android's Python headers. -# BTW, python is only available in 32bits for now, thus arch is forced to 32bits -$(LOCAL_BUILT_MODULE): MY_PYTHON := prebuilts/python/$(HOST_OS)-x86/2.7.5/bin/python -# The parameter-framework binding module is installed on these locations on -# Android (On 64bit machines, PyPfw.py is installed in the 'lib64' directory -# and _PyPfw.so is installed in the 'lib' directory, hence the need for these -# two directories in the PYTHONPATH) -$(LOCAL_BUILT_MODULE): MY_ENV := PYTHONPATH=$(HOST_OUT_SHARED_LIBRARIES):$(2ND_HOST_OUT_SHARED_LIBRARIES) - -$(LOCAL_BUILT_MODULE): MY_TOPLEVEL_FILE := $(PFW_TOPLEVEL_FILE) -$(LOCAL_BUILT_MODULE): MY_CRITERIA_FILE := $(PFW_CRITERIA_FILE) -$(LOCAL_BUILT_MODULE): MY_TUNING_FILE := $(PFW_TUNING_FILE) -$(LOCAL_BUILT_MODULE): MY_EDD_FILES := $(PFW_EDD_FILES) -$(LOCAL_BUILT_MODULE): MY_DOMAIN_FILES := $(PFW_DOMAIN_FILES) -$(LOCAL_BUILT_MODULE): MY_SCHEMAS_DIR := $(PFW_SCHEMAS_DIR) - -$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES) $(HOST_OUT)/bin/domainGenerator.py - $(hide) mkdir -p "$(dir $@)" - - $(MY_ENV) $(MY_PYTHON) "$(MY_TOOL)" --validate \ - --toplevel-config "$(MY_TOPLEVEL_FILE)" \ - --criteria "$(MY_CRITERIA_FILE)" \ - --initial-settings $(MY_TUNING_FILE) \ - --add-edds $(MY_EDD_FILES) \ - --add-domains $(MY_DOMAIN_FILES) \ - --schemas-dir $(MY_SCHEMAS_DIR) > "$@" - -# Clear variables for further use -PFW_TOPLEVEL_FILE := -PFW_CRITERIA_FILE := -PFW_TUNING_FILE := -PFW_EDD_FILES := -PFW_DOMAIN_FILES := -PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR) diff --git a/parameter/BinarySerializableElement.cpp b/support/windows/Resource.rc.in index 744d140..9ed0078 100644 --- a/parameter/BinarySerializableElement.cpp +++ b/support/windows/Resource.rc.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2016, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,46 +27,49 @@ * (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 "BinarySerializableElement.h" +#include "winres.h" -#define base CElement - -using std::string; - -CBinarySerializableElement::CBinarySerializableElement(const string& strName) : base(strName) -{ -} - -// Binary Serialization -void CBinarySerializableElement::binarySerialize(CBinaryStream& binaryStream) -{ - // Propagate - size_t uiNbChildren = getNbChildren(); - size_t uiChild; - - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - - CBinarySerializableElement* pChild = static_cast<CBinarySerializableElement*>(getChild(uiChild)); - - pChild->binarySerialize(binaryStream); - } -} - -// Data size -size_t CBinarySerializableElement::getDataSize() const -{ - // Propagate - size_t uiDataSize = 0; - size_t uiNbChildren = getNbChildren(); - size_t uiChild; - - for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { - - const CBinarySerializableElement* pChild = static_cast<const CBinarySerializableElement*>(getChild(uiChild)); - - uiDataSize += pChild->getDataSize(); - } - - return uiDataSize; -} +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058%28v=vs.85%29.aspx +VS_VERSION_INFO VERSIONINFO + FILEVERSION @WINRC_MAJOR@,@WINRC_MINOR@,@WINRC_PATCH@,@WINRC_TWEAK@ + PRODUCTVERSION @WINRC_MAJOR@,@WINRC_MINOR@,@WINRC_PATCH@,@WINRC_TWEAK@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 +#ifdef WINRC_EXE + FILETYPE VFT_APP +#else +# ifdef WINRC_DLL + FILETYPE VFT_DLL +# else + FILETYPE WFT_UNKNOWN +# endif +#endif + FILESUBTYPE 0x0L +BEGIN + // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa381049%28v=vs.85%29.aspx + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" // US english, unicode + BEGIN + VALUE "CompanyName", "Intel Corporation" + VALUE "FileDescription", "@WINRC_FILE_DESCRIPTION@" + VALUE "FileVersion", "@NICE_PF_VERSION@" + VALUE "InternalName", WINRC_FILENAME + VALUE "LegalCopyright", "Copyright (c) 2011-2016 Intel Corporation" + VALUE "OriginalFilename", WINRC_FILENAME + VALUE "ProductName", "Parameter Framework" + VALUE "ProductVersion", "@NICE_PF_VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END +END diff --git a/test/Android.mk b/test/Android.mk deleted file mode 100644 index 56ffec5..0000000 --- a/test/Android.mk +++ /dev/null @@ -1,7 +0,0 @@ -# include virtual HAL test-platform - - -LOCAL_PATH := $(call my-dir) - -include $(LOCAL_PATH)/test-platform/Android.mk - diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8efd0d7..48a40e5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,8 +26,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_subdirectory(test-platform) -add_subdirectory(test-fixed-point-parameter) -add_subdirectory(tokenizer) +add_subdirectory(catch) +add_subdirectory(tmpfile) add_subdirectory(functional-tests) +add_subdirectory(functional-tests-legacy) +add_subdirectory(test-fixed-point-parameter) +add_subdirectory(test-platform) add_subdirectory(test-subsystem) +add_subdirectory(introspection-subsystem) +add_subdirectory(tokenizer) +add_subdirectory(xml-generator) diff --git a/test/catch/CMakeLists.txt b/test/catch/CMakeLists.txt new file mode 100644 index 0000000..14b9afa --- /dev/null +++ b/test/catch/CMakeLists.txt @@ -0,0 +1,51 @@ +# 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. + +if(BUILD_TESTING) + # TODO Use gtest as it is the team recommendation + # Unfortunately gtest is very hard to setup as not binary distributed + # catch is only one header so it is very easy + find_path(CATCH_HEADER catch.hpp) + set_property(CACHE CATCH_HEADER PROPERTY ADVANCED TRUE) + if(NOT CATCH_HEADER) + message(SEND_ERROR +" Catch header `catch.hpp' could not be found. + Catch is a single header unit test framework required to build some tests. + How to install: + If it is not available on your package manager, Catch can be downloaded from: + https://raw.github.com/philsquared/Catch/master/single_include/catch.hpp + Then either: + - append the download folder to the `CMAKE_INCLUDE_PATH' or `CMAKE_PREFIX_PATH' variable + - copy it in a standard location (/usr/include on most linux distribution). + To remove test dependancies all together, set `BUILD_TESTING' to false. + It will disable test targets, thus the framework they depend on.") + endif() + + add_library(catch STATIC catch.cpp) + target_include_directories(catch PUBLIC "${CATCH_HEADER}") +endif() diff --git a/test/catch/catch.cpp b/test/catch/catch.cpp new file mode 100644 index 0000000..a46649c --- /dev/null +++ b/test/catch/catch.cpp @@ -0,0 +1,35 @@ +/* + * 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. + */ + +/** Accelerate test build by not recompiling catch when a test change. + * See: https://github.com/philsquared/Catch/blob/master/docs/slow-compiles.md + */ +#define CATCH_CONFIG_MAIN +#include "catch.hpp" diff --git a/test/functional-tests/ACTCampaignEngine.py b/test/functional-tests-legacy/ACTCampaignEngine.py index d4aeaf9..d4aeaf9 100755 --- a/test/functional-tests/ACTCampaignEngine.py +++ b/test/functional-tests-legacy/ACTCampaignEngine.py diff --git a/test/functional-tests-legacy/CMakeLists.txt b/test/functional-tests-legacy/CMakeLists.txt new file mode 100644 index 0000000..2eb1724 --- /dev/null +++ b/test/functional-tests-legacy/CMakeLists.txt @@ -0,0 +1,67 @@ +# Copyright (c) 2014-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. + +# This test suite relies on remote-process - which isn't available when +# networking is disabled +if(BUILD_TESTING AND NETWORKING) + find_package(PythonInterp 2 REQUIRED) + + set(PFW_ROOT ${PROJECT_BINARY_DIR}/tmp/test-parameters) + set(PFW_RESULT ${PFW_ROOT}/result) + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/Structure/Test/TestSubsystem.xml.in + ${PFW_ROOT}/xml/configuration/Structure/Test/TestSubsystem.xml @ONLY) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/Structure/Test/TestClass.xml + ${PFW_ROOT}/xml/configuration/Structure/Test/TestClass.xml + COPYONLY) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/ParameterFrameworkConfiguration.xml + ${PFW_ROOT}/xml/configuration/ParameterFrameworkConfiguration.xml + COPYONLY) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/Settings/Test/TestConfigurableDomains.xml + ${PFW_ROOT}/xml/configuration/Settings/Test/TestConfigurableDomains.xml + COPYONLY) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/ACTCampaignEngine.py DESTINATION ${PFW_ROOT}/) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/PfwTestCase DESTINATION ${PFW_ROOT}/) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Util DESTINATION ${PFW_ROOT}/) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xml/XML_Test DESTINATION ${PFW_ROOT}/xml/) + + add_test(NAME functional-test-legacy + WORKING_DIRECTORY ${PFW_ROOT} + COMMAND ${PYTHON_EXECUTABLE} ${PFW_ROOT}/ACTCampaignEngine.py) + + # Custom function defined in the top-level CMakeLists + set_test_env(functional-test-legacy) + set_property(TEST functional-test-legacy APPEND PROPERTY ENVIRONMENT + PFW_ROOT=${PFW_ROOT} + PFW_RESULT=${PFW_RESULT} + PFW_SCHEMAS=${PROJECT_SOURCE_DIR}/schemas) +endif() diff --git a/test/functional-tests/PfwTestCase/Domains/__init__.py b/test/functional-tests-legacy/PfwTestCase/Domains/__init__.py index e49f417..e49f417 100644 --- a/test/functional-tests/PfwTestCase/Domains/__init__.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/__init__.py diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Configuration.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Configuration.py index e5fcfed..8c5e641 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Configuration.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Configuration.py @@ -122,19 +122,19 @@ class TestCases(PfwTestCase): new_conf_name = "".join([self.conf_test, "_", str(iteration)]) log.I("Trying to create already existent %s configuration for domain %s" % (new_conf_name,self.domain_name)) log.I("command [createConfiguration]") - out, err = self.pfw.sendCmd("createConfiguration",self.domain_name,new_conf_name) + out, err = self.pfw.sendCmd("createConfiguration",self.domain_name,new_conf_name, expectSuccess=False) assert out != "Done", "ERROR : command [createConfiguration] - Error not detected while creating already existent configuration %s" % (new_conf_name) assert err == None, "ERROR : command [createConfiguration] - Error while creating configuration %s" % (new_conf_name) log.I("command [createConfiguration] correctly executed") log.I("error correctly detected, no configuration created") log.I("Creating a configuration without specifying a name") - out, err = self.pfw.sendCmd("createConfiguration",self.domain_name) + out, err = self.pfw.sendCmd("createConfiguration",self.domain_name, expectSuccess=False) assert out != "Done", "ERROR : command [createConfiguration] - Error not detected while creating a configuration without specifying a name" assert err == None, "ERROR : command [createConfiguration] - Error while creating configuration" log.I("error correctly detected") log.I("Creating a configuration on a wrong domain name") new_conf_name = "new_conf" - out, err = self.pfw.sendCmd("createConfiguration","wrong_domain_name",new_conf_name) + out, err = self.pfw.sendCmd("createConfiguration","wrong_domain_name",new_conf_name, expectSuccess=False) assert out != "Done", "ERROR : command [createConfiguration] - Error not detected while creating a configuration on a wrong domain name" assert err == None, "ERROR : command [createConfiguration] - Error while creating configuration" log.I("error correctly detected") @@ -154,10 +154,9 @@ class TestCases(PfwTestCase): log.I("Configurations listing conformity check") f_configurations = open("f_configurations", "r") f_configurations_backup = open("f_configurations_backup", "r") - for iteration in range(self.new_conf_number): - listed_conf_backup = f_configurations_backup.readline().strip('\n') - listed_conf = f_configurations.readline().strip('\n') - assert listed_conf==listed_conf_backup, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf_backup, listed_conf) + listed_conf_backup = f_configurations_backup.read().splitlines() + listed_conf = f_configurations.read().splitlines() + assert listed_conf==listed_conf_backup, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf_backup, listed_conf) log.I("No change detected, listed configurations names conform to expected values") # New domain deletion @@ -236,19 +235,19 @@ class TestCases(PfwTestCase): new_conf_name = "".join([self.conf_test, "_", str(iteration+1)]) log.I("Trying to rename %s on domain %s with an already used name : %s" % (conf_name,self.domain_name,new_conf_name)) log.I("command [renameConfiguration]" ) - out, err = self.pfw.sendCmd("renameConfiguration",self.domain_name,conf_name,new_conf_name) + out, err = self.pfw.sendCmd("renameConfiguration",self.domain_name,conf_name,new_conf_name, expectSuccess=False) assert out != "Done", "ERROR : command [renameConfiguration] - Error not detected while renaming configuration %s with an already used name" % (new_conf_name) assert err == None, "ERROR : command [renameConfiguration] - Error while renaming configuration %s" % (new_conf_name) log.I("command [renameConfiguration] correctly executed") log.I("error correctly detected, no configuration renamed") log.I("renaming a configuration without specifying a new name") - out, err = self.pfw.sendCmd("renameConfiguration",self.domain_name,new_conf_name) + out, err = self.pfw.sendCmd("renameConfiguration",self.domain_name,new_conf_name, expectSuccess=False) assert out != "Done", "ERROR : command [renameConfiguration] - Error not detected while renaming a configuration without specifying a new name" assert err == None, "ERROR : command [renameConfiguration] - Error while renaming configuration" log.I("error correctly detected, no configuration renamed") log.I("renaming a configuration on a wrong domain name") new_conf_name = "new_conf" - out, err = self.pfw.sendCmd("renameConfiguration","wrong_domain_name",new_conf_name,"Configuration") + out, err = self.pfw.sendCmd("renameConfiguration","wrong_domain_name",new_conf_name,"Configuration", expectSuccess=False) assert out != "Done", "ERROR : command [renameConfiguration] - Error not detected while renaming a configuration on a wrong domain name" assert err == None, "ERROR : command [renameConfiguration] - Error while renaming configuration" log.I("error correctly detected, no configuration renamed") @@ -268,10 +267,9 @@ class TestCases(PfwTestCase): log.I("Configurations listing conformity check") f_configurations = open("f_configurations", "r") f_configurations_backup = open("f_configurations_backup", "r") - for iteration in range(self.new_conf_number): - listed_conf_backup = f_configurations_backup.readline().strip('\n') - listed_conf = f_configurations.readline().strip('\n') - assert listed_conf==listed_conf_backup, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf_backup, listed_conf) + listed_conf_backup = f_configurations_backup.read().splitlines() + listed_conf = f_configurations.read().splitlines() + assert listed_conf==listed_conf_backup, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf_backup, listed_conf) log.I("No change detected, listed configurations names conform to expected values") # Testing domain deletion @@ -346,18 +344,18 @@ class TestCases(PfwTestCase): log.I("Trying various deletions error test cases") log.I("Trying to delete a wrong configuration name on domain %s" % (self.domain_name)) log.I("command [deleteConfiguration]") - out, err = self.pfw.sendCmd("deleteConfiguration",self.domain_name,"wrong_configuration_name") + out, err = self.pfw.sendCmd("deleteConfiguration",self.domain_name,"wrong_configuration_name", expectSuccess=False) assert out != "Done", "ERROR : command [deleteConfiguration] - Error not detected while deleting non existent configuration name" assert err == None, "ERROR : command [deleteConfiguration] - Error while deleting configuration" log.I("command [deleteConfiguration] correctly executed") log.I("error correctly detected, no configuration deleted") log.I("deleting a configuration with no name specified") - out, err = self.pfw.sendCmd("deleteConfiguration",self.domain_name) + out, err = self.pfw.sendCmd("deleteConfiguration",self.domain_name, expectSuccess=False) assert out != "Done", "ERROR : command [deleteConfiguration] - Error not detected while deleting a configuration without specifying a name" assert err == None, "ERROR : command [deleteConfiguration] - Error while deleting configuration" log.I("error correctly detected, no configuration deleted") log.I("deleting a configuration on a wrong domain name") - out, err = self.pfw.sendCmd("deleteConfiguration","wrong_domain_name",new_conf_name) + out, err = self.pfw.sendCmd("deleteConfiguration","wrong_domain_name",new_conf_name, expectSuccess=False) assert out != "Done", "ERROR : command [deleteConfiguration] - Error not detected while deleting a configuration on a wrong domain name" assert err == None, "ERROR : command [deleteConfiguration] - Error while deleting configuration" log.I("error correctly detected, no configuration deleted") @@ -377,10 +375,9 @@ class TestCases(PfwTestCase): log.I("Configurations listing conformity check") f_configurations = open("f_configurations", "r") f_configurations_backup = open("f_configurations_backup", "r") - for iteration in range(self.new_conf_number): - listed_conf_backup = f_configurations_backup.readline().strip('\n') - listed_conf = f_configurations.readline().strip('\n') - assert listed_conf==listed_conf_backup, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf_backup, listed_conf) + listed_conf_backup = f_configurations_backup.read().splitlines() + listed_conf = f_configurations.read().splitlines() + assert listed_conf==listed_conf_backup, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf_backup, listed_conf) log.I("No change detected, listed configurations names conform to expected values") # Testing domain deletion @@ -453,10 +450,9 @@ class TestCases(PfwTestCase): # Checking configurations names integrity log.I("Configurations listing conformity check") f_configurations = open("f_configurations", "r") - for iteration in range(self.new_conf_number): - new_conf_name = "".join([self.conf_test, "_", str(iteration)]) - listed_conf = f_configurations.readline().strip('\n') - assert listed_conf==new_conf_name, "ERROR : Error while listing configuration %s (found %s)" % (listed_conf, new_conf_name) + new_conf_names = [self.conf_test + "_" + str(iteration) for iteration in range(self.new_conf_number)] + listed_conf = f_configurations.read().strip('\r\n').splitlines() + assert listed_conf == new_conf_names, "ERROR : Error while listing configuration, expected '%s', found '%s'" % (new_conf_names, listed_conf) log.I("Listed configurations names conform to expected values") # Configuration renaming @@ -478,16 +474,12 @@ class TestCases(PfwTestCase): assert err == None, "ERROR : command [listConfigurations] - Error while listing configurations for domain %s" % (self.domain_name) log.I("command [listConfigurations] correctly executed") # Saving configurations names - f_configurations_renamed = open("f_configurations_renamed", "w") - f_configurations_renamed.write(out) - f_configurations_renamed.close() + configurations_renamed = out # Checking configurations names integrity log.I("Configurations listing conformity check") - f_configurations_renamed = open("f_configurations_renamed", "r") - for iteration in range(self.new_conf_number): - new_conf_name = "".join([self.conf_test_renamed, "_", str(iteration)]) - listed_conf = f_configurations_renamed.readline().strip('\n') - assert listed_conf==new_conf_name, "ERROR : Error while renaming configuration %s (found %s)" % (new_conf_name,listed_conf) + new_conf_names = [self.conf_test_renamed + "_" + str(iteration) for iteration in range(self.new_conf_number)] + listed_conf = configurations_renamed.strip('\r\n').splitlines() + assert listed_conf == new_conf_names, "ERROR : Error while renaming configuration, expected '%s', found '%s'" % (new_conf_names, listed_conf) log.I("Listed configurations names conform to expected values, renaming successfull") # New domain deletion @@ -501,5 +493,3 @@ class TestCases(PfwTestCase): # Closing and deleting temp file f_configurations.close() os.remove("f_configurations") - f_configurations_renamed.close() - os.remove("f_configurations_renamed") diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Configuration_Backup.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Configuration_Backup.py index 51d3d2b..26dd03a 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Configuration_Backup.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Configuration_Backup.py @@ -155,15 +155,15 @@ class TestCases(PfwTestCase): # Configuration saving errors log.I("saving configuration error test cases :") log.I("saving configuration with a missing argument") - out, err = self.pfw.sendCmd("saveConfiguration", self.domain_name) + out, err = self.pfw.sendCmd("saveConfiguration", self.domain_name, expectSuccess=False) assert err == None, "ERROR : Error when saving configuration with a missing argument" assert out != "Done", "ERROR : Error not detected when saving configuration with a missing argument" log.I("saving configuration with a wrong domain name") - out, err = self.pfw.sendCmd("saveConfiguration", "Wrong_Domain_Name", self.conf_1) + out, err = self.pfw.sendCmd("saveConfiguration", "Wrong_Domain_Name", self.conf_1, expectSuccess=False) assert err == None, "ERROR : Error when saving configuration with a wrong domain name" assert out != "Done", "ERROR : Error not detected when saving configuration with a wrong domain name" log.I("saving configuration with a wrong configuration name") - out, err = self.pfw.sendCmd("saveConfiguration", self.domain_name, "Wrong_Configuration_Name") + out, err = self.pfw.sendCmd("saveConfiguration", self.domain_name, "Wrong_Configuration_Name", expectSuccess=False) assert err == None, "ERROR : Error when saving configuration with a wrong configuration name" assert out != "Done", "ERROR : Error not detected when saving configuration with a wrong configuration name" log.I("saving configuration error test cases : errors correctly detected") @@ -218,15 +218,15 @@ class TestCases(PfwTestCase): # Configuration restore errors log.I("restoring configuration error test cases :") log.I("restoring configuration with a missing argument") - out, err = self.pfw.sendCmd("restoreConfiguration", self.domain_name) + out, err = self.pfw.sendCmd("restoreConfiguration", self.domain_name, expectSuccess=False) assert err == None, "ERROR : Error when restoring configuration with a missing argument" assert out != "Done", "ERROR : Error not detected when restoring configuration with a missing argument" log.I("restoring configuration with a wrong domain name") - out, err = self.pfw.sendCmd("restoreConfiguration", "Wrong_Domain_Name", self.conf_1) + out, err = self.pfw.sendCmd("restoreConfiguration", "Wrong_Domain_Name", self.conf_1, expectSuccess=False) assert err == None, "ERROR : Error when restoring configuration with a wrong domain name" assert out != "Done", "ERROR : Error not detected when restoring configuration with a wrong domain name" log.I("restoring configuration with a wrong configuration name") - out, err = self.pfw.sendCmd("restoreConfiguration", self.domain_name, "Wrong_Configuration_Name") + out, err = self.pfw.sendCmd("restoreConfiguration", self.domain_name, "Wrong_Configuration_Name", expectSuccess=False) assert err == None, "ERROR : Error when restoring configuration with a wrong configuration name" assert out != "Done", "ERROR : Error not detected when restoring configuration with a wrong configuration name" log.I("restoring configuration error test cases : errors correctly detected") diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Configuration_Selection.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Configuration_Selection.py index 86739ac..eaaa17d 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Configuration_Selection.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Configuration_Selection.py @@ -49,8 +49,7 @@ class TestCases(PfwTestCase): def setUp(self): self.pfw.sendCmd("setTuningMode", "on") - self.reference_xml = "$PFW_TEST_TOOLS/xml/XML_Test/Reference_Criteria.xml" - self.temp_domain="f_Domains_Backup" + self.reference_xml = os.environ["PFW_TEST_TOOLS"] + "/xml/XML_Test/Reference_Criteria.xml" self.temp_status="f_Config_Status" # Expected results are defined by Reference_Criteria.xml configuration settings self.expected_result = [["Conf_1_1", "<none>", "Conf_3_0"] , @@ -71,7 +70,7 @@ class TestCases(PfwTestCase): self.crit_change_iteration = 6 def tearDown(self): - self.pfw.sendCmd("setTuningMode", "off") + self.pfw.sendCmd("setTuningMode", "off", expectSuccess=False) def test_Combinatorial_Criteria(self): """ @@ -111,18 +110,6 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [listDomains] : %s"%(err)) log.I("Command [listDomains] : correctly executed") - # Domains listing backup - f_Domains_Backup = open(self.temp_domain, "w") - f_Domains_Backup.write(out) - f_Domains_Backup.close() - f_Domains_Backup = open(self.temp_domain, "r") - domains_nbr = 0 - line=f_Domains_Backup.readline() - while line!="": - line=f_Domains_Backup.readline() - domains_nbr+=1 - f_Domains_Backup.close() - # Applying default configurations out, err = self.pfw.sendCmd("setTuningMode", "off") assert err == None, log.E("Command [setTuningMode]") @@ -167,7 +154,7 @@ class TestCases(PfwTestCase): f_Config_Status.close() # Configurations checking - for domain in range (domains_nbr): + for domain in range (len(self.expected_result[0])): domain_name = "".join([self.new_domain_name, "_", str(domain+1), "[<none>]"]) config = str(self.expected_result[iteration][domain]) log.I("Checking that domain %s is set to configuration : %s" % (domain_name,config)) @@ -181,5 +168,4 @@ class TestCases(PfwTestCase): log.I("Domain %s - configuration correctly set to %s" % (domain_name,line)) # Temporary files deletion - os.remove(self.temp_domain) os.remove(self.temp_status) diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Elements.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Elements.py index 8651968..cd8a0be 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Elements.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Elements.py @@ -136,12 +136,12 @@ class TestCases(PfwTestCase): for line in range(element_nbr): # initial domain elements shall not have been impacted by current test if (line < element_nbr_init): - element_name = f_DomainElements.readline().strip('\n') - element_name_backup = f_DomainElements_Backup.readline().strip('\n') + element_name = f_DomainElements.readline().strip('\r\n') + element_name_backup = f_DomainElements_Backup.readline().strip('\r\n') assert element_name==element_name_backup, "ERROR : Error while modifying domain elements on domain %s" % (self.domain_name) # last listed element shall be equal to the only one element added previously else: - element_name = f_DomainElements.readline().strip('\n') + element_name = f_DomainElements.readline().strip('\r\n') assert element_name==str(self.elem_2_path), "ERROR : Error while modifying domain elements on domain %s" % (self.domain_name) log.I("Actual domain %s elements names conform to expected values" % (self.domain_name)) # Temporary files deletion @@ -192,11 +192,11 @@ class TestCases(PfwTestCase): # Adding a new domain element errors log.I("Adding an already existing domain element to domain %s" % (self.domain_name)) - out, err = self.pfw.sendCmd("addElement", str(self.domain_name), str(self.elem_0_path)) + out, err = self.pfw.sendCmd("addElement", str(self.domain_name), str(self.elem_0_path), expectSuccess=False) assert err == None, "ERROR : command [addElement] - Error while adding new domain element %s" % (self.elem_0_path) assert out != "Done", "ERROR : command [addElement] - Error not detected while adding an already existing domain element to domain %s" % (self.domain_name) log.I("Adding a non defined domain element to domain %s" % (self.domain_name)) - out, err = self.pfw.sendCmd("addElement", str(self.domain_name), "Non_Defined_Element") + out, err = self.pfw.sendCmd("addElement", str(self.domain_name), "Non_Defined_Element", expectSuccess=False) assert err == None, "ERROR : command [addElement] - Error while adding new domain element %s" % (self.elem_2_path) assert out != "Done", "ERROR : command [addElement] - Error not detected while adding a non defined domain element to domain %s" % (self.domain_name) log.I("Error when adding elements correctly detected") @@ -222,8 +222,8 @@ class TestCases(PfwTestCase): f_DomainElements_Backup = open("f_DomainElements_Backup", "r") for line in range(element_nbr): # initial domain elements shall not have been impacted by current test - element_name = f_DomainElements.readline().strip('\n') - element_name_backup = f_DomainElements_Backup.readline().strip('\n') + element_name = f_DomainElements.readline().strip('\r\n') + element_name_backup = f_DomainElements_Backup.readline().strip('\r\n') assert element_name==element_name_backup, "ERROR : domain %s elements affected by addElement errors" % (self.domain_name) log.I("Actual domain %s elements names conform to expected values" % (self.domain_name)) # Temporary files deletion @@ -270,11 +270,11 @@ class TestCases(PfwTestCase): # Error when removing domain elements log.I("Removing a domain element from a non defined domain") - out, err = self.pfw.sendCmd("removeElement", "Wrong_Domain_Name", str(self.elem_0_path)) + out, err = self.pfw.sendCmd("removeElement", "Wrong_Domain_Name", str(self.elem_0_path), expectSuccess=False) assert err == None, "ERROR : command [removeElement] - Error when removing domain element %s" % (self.elem_0_path) assert out != "Done", "ERROR : command [removeElement] - Error not detected when removing domain element %s from an undefined domain"% (self.elem_0_path) log.I("Removing a non existent domain element from domain %s" % (self.domain_name)) - out, err = self.pfw.sendCmd("removeElement", str(self.domain_name), "Wrong_Element_Name") + out, err = self.pfw.sendCmd("removeElement", str(self.domain_name), "Wrong_Element_Name", expectSuccess=False) assert err == None, "ERROR : command [removeElement] - Error when removing domain element %s" % (self.elem_0_path) assert out != "Done", "ERROR : command [removeElement] - Error not detected when removing a non existent domain element from domain %s" % (self.domain_name) log.I("Error when removing elements correctly detected") @@ -300,8 +300,8 @@ class TestCases(PfwTestCase): f_DomainElements_Backup = open("f_DomainElements_Backup", "r") for line in range(element_nbr): # initial domain elements shall not have been impacted by current test - element_name = f_DomainElements.readline().strip('\n') - element_name_backup = f_DomainElements_Backup.readline().strip('\n') + element_name = f_DomainElements.readline().strip('\r\n') + element_name_backup = f_DomainElements_Backup.readline().strip('\r\n') assert element_name==element_name_backup, "ERROR : domain %s elements affected by addElement errors" % (self.domain_name) log.I("Actual domain %s elements names conform to expected values" % (self.domain_name)) # Temporary files deletion diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Elements_Sequences.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Elements_Sequences.py index 1544cae..8baad70 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Elements_Sequences.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Elements_Sequences.py @@ -107,20 +107,11 @@ class TestCases(PfwTestCase): # Checking new elements sequence order conformity for selected configuration log.I("Checking new elements sequence order for configuration") - f_ConfigElementsOrder = open("f_ConfigElementsOrder", "w") - f_ConfigElementsOrder.write(out) - f_ConfigElementsOrder.close() - f_ConfigElementsOrder = open("f_ConfigElementsOrder", "r") - element_name = f_ConfigElementsOrder.readline().strip('\n') - assert element_name==self.elem_2_path, "ERROR : Error while modifying configuration %s elements order on domain %s" % (self.configuration) - element_name = f_ConfigElementsOrder.readline().strip('\n') - assert element_name==self.elem_0_path, "ERROR : Error while modifying configuration %s elements order on domain %s" % (self.configuration) - element_name = f_ConfigElementsOrder.readline().strip('\n') - assert element_name==self.elem_1_path, "ERROR : Error while modifying configuration %s elements order on domain %s" % (self.configuration) + expected = [self.elem_2_path, self.elem_0_path, self.elem_1_path] + # Only check the element reordered + configElementOrder = out.strip('\r\n').splitlines()[:len(expected)] + assert configElementOrder == expected, "ERROR : Error while modifying configuration %s elements order on domain %s, expected %s, found %s" % (self.configuration, self.domain_name, expected, configElementOrder) log.I("New elements sequence order conform to expected order for configuration %s" % (self.configuration)) - # Closing and removing temp file - f_ConfigElementsOrder.close() - os.remove("f_ConfigElementsOrder") # Removing created domain element out, err = self.pfw.sendCmd("removeElement", str(self.domain_name), str(self.elem_1_path)) assert err == None, "ERROR : command [removeElement] - Error while removing domain element %s" % (self.elem_1_path) @@ -168,13 +159,13 @@ class TestCases(PfwTestCase): # Setting an element not belonging to configuration in sequence order log.I("Setting an element not belonging to configuration %s in sequence order" % (self.configuration)) - out, err = self.pfw.sendCmd("setElementSequence", self.domain_name, self.configuration, self.elem_2_path, self.elem_0_path, self.elem_1_path) + out, err = self.pfw.sendCmd("setElementSequence", self.domain_name, self.configuration, self.elem_2_path, self.elem_0_path, self.elem_1_path, expectSuccess=False) assert err == None, "ERROR : command [setElementSequence] - Error while setting elements sequence for configuration %s" % (self.configuration) assert out != "Done", "ERROR : command [setElementSequence] - Error not detected when setting an element not belonging to configuration" # Setting undefined element in sequence order for selected configuration log.I("Setting undefined element in sequence order for configuration %s" % (self.configuration)) - out, err = self.pfw.sendCmd("setElementSequence", self.domain_name, self.configuration, "Wrong_Element_Name", self.elem_0_path, self.elem_1_path) + out, err = self.pfw.sendCmd("setElementSequence", self.domain_name, self.configuration, "Wrong_Element_Name", self.elem_0_path, self.elem_1_path, expectSuccess=False) assert err == None, "ERROR : command [setElementSequence] - Error while setting elements sequence for configuration %s" % (self.configuration) assert out != "Done", "ERROR : command [getElementSequence] - Error not detected when setting an undefined element to configuration" @@ -190,11 +181,8 @@ class TestCases(PfwTestCase): log.I("Checking new elements sequence order for configuration") f_ConfigElementsOrder = open("f_ConfigElementsOrder", "r") f_ConfigElementsOrder_Backup = open("f_ConfigElementsOrder_Backup", "r") - new_element_name = f_ConfigElementsOrder.readline().strip('\n') - element_name = f_ConfigElementsOrder_Backup.readline().strip('\n') - assert element_name==new_element_name, "ERROR : setElementSequence errors have affected elements order on domain %s" % (self.configuration) - new_element_name = f_ConfigElementsOrder.readline().strip('\n') - element_name = f_ConfigElementsOrder_Backup.readline().strip('\n') + new_element_name = f_ConfigElementsOrder.read().splitlines() + element_name = f_ConfigElementsOrder_Backup.read().splitlines() assert element_name==new_element_name, "ERROR : setElementSequence errors have affected elements order on domain %s" % (self.configuration) log.I("Elements sequence order not affected by setElementSequence errors") @@ -230,11 +218,11 @@ class TestCases(PfwTestCase): log.I("Adding a new domain element to domain %s" % (self.domain_name)) out, err = self.pfw.sendCmd("addElement", str(self.domain_name), str(self.elem_1_path)) assert err == None, "ERROR : command [addElement] - Error while adding new domain element %s" % (self.elem_1_path) - assert out == "Done", "ERROR : command [addElement] - Error while adding new domain element %s" % (self.elem_1_path) + assert out == "Done", "ERROR : command [addElement] - Error while adding new domain element %s: %s" % (self.elem_1_path, out) log.I("Adding a new domain element to domain %s" % (self.domain_name)) out, err = self.pfw.sendCmd("addElement", str(self.domain_name), str(self.elem_2_path)) assert err == None, "ERROR : command [addElement] - Error while adding new domain element %s" % (self.elem_2_path) - assert out == "Done", "ERROR : command [addElement] - Error while adding new domain element %s" % (self.elem_2_path) + assert out == "Done", "ERROR : command [addElement] - Error while adding new domain element %s: %s" % (self.elem_2_path, out) log.I("New domain elements %s and %s added to domain %s" % (self.elem_1_path, self.elem_2_path, self.domain_name)) # Getting elements sequence from selected configuration @@ -250,13 +238,13 @@ class TestCases(PfwTestCase): # Getting an element sequence on a wrong domain name log.I("Getting an element sequence on a wrong domain name") - out, err = self.pfw.sendCmd("getElementSequence", "Wrong_Domain_Name", self.configuration) + out, err = self.pfw.sendCmd("getElementSequence", "Wrong_Domain_Name", self.configuration, expectSuccess=False) assert err == None, "ERROR : command [getElementSequence] - Error when getting elements sequence for configuration %s" % (self.configuration) assert out != "Done", "ERROR : command [getElementSequence] - Error not detected when getting elements sequence for a wrong domain name" # Getting an element sequence on a wrong configuration name log.I("Getting an element sequence on a wrong configuration name") - out, err = self.pfw.sendCmd("getElementSequence", self.domain_name, "Wrong_Configuration_Name") + out, err = self.pfw.sendCmd("getElementSequence", self.domain_name, "Wrong_Configuration_Name", expectSuccess=False) assert err == None, "ERROR : command [getElementSequence] - Error when getting elements sequence on a wrong configuration name" assert out != "Done", "ERROR : command [getElementSequence] - Error not detected when getting elements sequence on a wrong configuration name" @@ -272,12 +260,9 @@ class TestCases(PfwTestCase): log.I("Checking new elements sequence order for configuration") f_ConfigElementsOrder = open("f_ConfigElementsOrder", "r") f_ConfigElementsOrder_Backup = open("f_ConfigElementsOrder_Backup", "r") - new_element_name = f_ConfigElementsOrder.readline().strip('\n') - element_name = f_ConfigElementsOrder_Backup.readline().strip('\n') - assert element_name==new_element_name, "ERROR : getElementSequence errors have affected elements order on domain %s" % (self.configuration) - new_element_name = f_ConfigElementsOrder.readline().strip('\n') - element_name = f_ConfigElementsOrder_Backup.readline().strip('\n') - assert element_name==new_element_name, "ERROR : getElementSequence errors have affected elements order on domain %s" % (self.configuration) + new_element_names = f_ConfigElementsOrder.read().splitlines() + element_name = f_ConfigElementsOrder_Backup.read().splitlines() + assert element_name==new_element_names, "ERROR : getElementSequence errors have affected elements order on domain %s" % (self.configuration) log.I("Elements sequence order not affected by getElementSequence errors") # Closing and removing temp file diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Rules.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Rules.py index 0084e22..407047f 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Rules.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Rules.py @@ -132,19 +132,19 @@ class TestCases(PfwTestCase): # Clearing rule errors log.I("Clearing a rule on domain %s to a non-existent configuration" % (self.domain_name)) log.I("command [clearRule]") - out, err = self.pfw.sendCmd("clearRule",self.domain_name,"Wrong_Config_Name") + out, err = self.pfw.sendCmd("clearRule",self.domain_name,"Wrong_Config_Name", expectSuccess=False) assert err == None, "ERROR : command [clearRule] - Error while clearing rule on domain %s to a non-existent configuration" % (self.domain_name) assert out != "Done", "ERROR : command [clearRule] - Error not detected while clearing rule on domain %s to a non-existent configuration" % (self.domain_name) log.I("error correctly detected when clearing a rule to a non-existent configuration") log.I("Clearing a rule on a non-existent domain") log.I("command [clearRule]") - out, err = self.pfw.sendCmd("clearRule","Wrong_Domain_Name",self.conf_2) + out, err = self.pfw.sendCmd("clearRule","Wrong_Domain_Name",self.conf_2, expectSuccess=False) assert err == None, "ERROR : command [clearRule] - Error while clearing rule on a non-existent domain" assert out != "Done", "ERROR : command [clearRule] - Error not detected while clearing rule on a non-existent domain" log.I("error correctly detected while clearing rule on a non-existent domain") log.I("Clearing a rule with wrong parameters order") log.I("command [clearRule]") - out, err = self.pfw.sendCmd("clearRule",self.conf_1,self.domain_name) + out, err = self.pfw.sendCmd("clearRule",self.conf_1,self.domain_name, expectSuccess=False) assert err == None, "ERROR : command [clearRule] - Error when clearing a rule with incorrect paramaters order" assert out != "Done", "ERROR : command [clearRule] - Error not detected when clearing a rule with incorrect paramaters order" log.I("error correctly detected when clearing a rule with incorrect paramaters order on domain %s and configuration %s" % (self.domain_name,self.conf_1)) @@ -209,19 +209,19 @@ class TestCases(PfwTestCase): # setRule :basic error cases log.I("Applying a new rule on domain %s to a non-existent configuration" % (self.domain_name)) log.I("command [setRule]") - out, err = self.pfw.sendCmd("setRule",self.domain_name,"Wrong_Config_Name",self.rule_1) + out, err = self.pfw.sendCmd("setRule",self.domain_name,"Wrong_Config_Name",self.rule_1, expectSuccess=False) assert err == None, "ERROR : command [setRule] - Error while setting rule on domain %s to a non-existent configuration" % (self.domain_name) assert out != "Done", "ERROR : command [setRule] - Error not detected while setting rule on domain %s to a non-existent configuration" % (self.domain_name) log.I("error correctly detected when creating a rule to a non-existent configuration") log.I("Applying a new rule on a non-existent domain") log.I("command [setRule]") - out, err = self.pfw.sendCmd("setRule","Wrong_Domain_Name",self.conf_1,self.rule_1) + out, err = self.pfw.sendCmd("setRule","Wrong_Domain_Name",self.conf_1,self.rule_1, expectSuccess=False) assert err == None, "ERROR : command [setRule] - Error while setting rule on a non-existent domain" assert out != "Done", "ERROR : command [setRule] - Error not detected while setting rule on a non-existent domain" log.I("error correctly detected while setting rule on a non-existent domain") log.I("Applying a new rule with incorrect format") log.I("command [setRule]") - out, err = self.pfw.sendCmd("setRule",self.domain_name,self.conf_1,"Wrong_Rule_Format") + out, err = self.pfw.sendCmd("setRule",self.domain_name,self.conf_1,"Wrong_Rule_Format", expectSuccess=False) assert err == None, "ERROR : command [setRule] - Error when setting incorrect format rule" assert out != "Done", "ERROR : command [setRule] - Error not detected when setting incorrect format rule" log.I("error correctly detected when setting incorrect format rule on domain %s and configuration %s" % (self.domain_name,self.conf_1)) @@ -231,7 +231,7 @@ class TestCases(PfwTestCase): for index in range (self.rule_error_nbr): log.I("Rule error number %s" % (str(index))) rule_name = "".join(["self.rule_error_", "_", str(index)]) - out, err = self.pfw.sendCmd("setRule",self.domain_name,self.conf_1, rule_name) + out, err = self.pfw.sendCmd("setRule",self.domain_name,self.conf_1, rule_name, expectSuccess=False) assert err == None, "ERROR : command [setRule] - Error when setting incorrect format rule %s" % (str(rule_name)) assert out != "Done", "ERROR : command [setRule] - Error not detected when setting incorrect format rule %s" % (str(rule_name)) log.I("error correctly detected when setting incorrect format rule on domain %s and configuration %s" % (self.domain_name,self.conf_1)) @@ -315,19 +315,19 @@ class TestCases(PfwTestCase): # Getting rule errors log.I("Getting a rule on domain %s from a non-existent configuration" % (self.domain_name)) log.I("command [getRule]") - out, err = self.pfw.sendCmd("getRule",self.domain_name,"Wrong_Config_Name") + out, err = self.pfw.sendCmd("getRule",self.domain_name,"Wrong_Config_Name", expectSuccess=False) assert err == None, "ERROR : command [getRule] - Error when getting rule on domain %s from a non-existent configuration" % (self.domain_name) assert out != "Done", "ERROR : command [getRule] - Error not detected while getting rule on domain %s from a non-existent configuration" % (self.domain_name) log.I("error correctly detected when getting a rule from a non-existent configuration") log.I("getting a rule from a non-existent domain") log.I("command [getRule]") - out, err = self.pfw.sendCmd("getRule","Wrong_Domain_Name",self.conf_2) + out, err = self.pfw.sendCmd("getRule","Wrong_Domain_Name",self.conf_2, expectSuccess=False) assert err == None, "ERROR : command [getRule] - Error when getting rule from a non-existent domain" assert out != "Done", "ERROR : command [getRule] - Error not detected while getting rule from a non-existent domain" log.I("error correctly detected when getting rule from a non-existent domain") log.I("getting a rule with wrong parameters order") log.I("command [getRule]") - out, err = self.pfw.sendCmd("getRule",self.conf_1,self.domain_name) + out, err = self.pfw.sendCmd("getRule",self.conf_1,self.domain_name, expectSuccess=False) assert err == None, "ERROR : command [getRule] - Error when getting a rule with incorrect paramaters order" assert out != "Done", "ERROR : command [getRule] - Error not detected when getting a rule with incorrect paramaters order" log.I("error correctly detected when getting a rule with incorrect paramaters order on domain %s and configuration %s" % (self.domain_name,self.conf_1)) diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_Split.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Split.py index 9d2990e..c714224 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_Split.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_Split.py @@ -43,7 +43,7 @@ Test cases : ------------ - Testing nominal case """ -import os.path +import os from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging log=ACTLogging.Logger() @@ -52,7 +52,7 @@ class TestCases(PfwTestCase): def setUp(self): self.pfw.sendCmd("setTuningMode", "on") - self.reference_xml = "$PFW_TEST_TOOLS/xml/XML_Test/Reference_Split_Domain.xml" + self.reference_xml = os.environ["PFW_TEST_TOOLS"] + "/xml/XML_Test/Reference_Split_Domain.xml" self.temp_domain="f_Domains_Backup" self.temp_status="f_Config_Status" diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_creation_deletion.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_creation_deletion.py index 039830d..c5d43f3 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_creation_deletion.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_creation_deletion.py @@ -107,7 +107,7 @@ class TestCases(PfwTestCase): log.I("Adding an already existent domain name") log.I("command [createDomain]") domain_name = 'Test_Domain' - out, err = self.pfw.sendCmd("createDomain",domain_name, "") + out, err = self.pfw.sendCmd("createDomain",domain_name, "", expectSuccess=False) assert out != "Done", "ERROR : command [createDomain] - Error not detected when creating an already existent domain" assert err == None, err log.I("command [createDomain] - error correctly detected") @@ -133,8 +133,8 @@ class TestCases(PfwTestCase): f_Domains = open("f_Domains", "r") f_Domains_Backup = open("f_Domains_Backup", "r") for line in range(domains_nbr): - domain_backup_name = f_Domains_Backup.readline().strip('\n'), - domain_name = f_Domains.readline().strip('\n'), + domain_backup_name = f_Domains_Backup.readline().strip('\r\n'), + domain_name = f_Domains.readline().strip('\r\n'), assert domain_backup_name==domain_name, "ERROR : Error while reading domain %s" % (domain_backup_name) log.I("Test OK - Domains listing not affected by domain creation error") @@ -185,7 +185,7 @@ class TestCases(PfwTestCase): log.I("Deleting a non-existent domain name") log.I("command [deleteDomain]") domain_name = 'Wrong_Domain_Name' - out, err = self.pfw.sendCmd("deleteDomain",domain_name, "") + out, err = self.pfw.sendCmd("deleteDomain",domain_name, "", expectSuccess=False) assert out != "Done", "ERROR : command [deleteDomain] - Error not detected when deleting a non-existent domain" assert err == None, err log.I("command [deleteDomain] - error correctly detected") @@ -211,8 +211,8 @@ class TestCases(PfwTestCase): f_Domains = open("f_Domains", "r") f_Domains_Backup = open("f_Domains_Backup", "r") for line in range(domains_nbr): - domain_backup_name = f_Domains_Backup.readline().strip('\n'), - domain_name = f_Domains.readline().strip('\n'), + domain_backup_name = f_Domains_Backup.readline().strip('\r\n'), + domain_name = f_Domains.readline().strip('\r\n'), assert domain_backup_name==domain_name, "Error while reading domain %s" % (domain_backup_name) log.I("Test OK - Domains listing not affected by domain deletion error") @@ -296,7 +296,7 @@ class TestCases(PfwTestCase): for line in range(domains_nbr): if (line >= (domains_nbr - self.new_domains_number)): domain_name = "".join([self.new_domain_name,"_",str(line)]), - domain_created = tempfile.readline().strip('\n'), + domain_created = tempfile.readline().strip('\n\r'), assert domain_name==domain_created, "ERROR : Error while creating domain %s %s" % (domain_created, domain_name) else: domain_created = tempfile.readline() diff --git a/test/functional-tests/PfwTestCase/Domains/tDomain_rename.py b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_rename.py index 81d4539..2ee5414 100644 --- a/test/functional-tests/PfwTestCase/Domains/tDomain_rename.py +++ b/test/functional-tests-legacy/PfwTestCase/Domains/tDomain_rename.py @@ -198,7 +198,7 @@ class TestCases(PfwTestCase): log.I("Renaming a non existent domain") log.I("Renaming domain FAKE to NEW_NAME") log.I("command [renameDomain]") - out, err = self.pfw.sendCmd("renameDomain",'FAKE','NEW_NAME') + out, err = self.pfw.sendCmd("renameDomain",'FAKE','NEW_NAME', expectSuccess=False) assert out != "Done", out assert err == None, "ERROR : command [renameDomain] - Error while renaming domain" log.I("command [renameDomain] - renaming error correctly detected") @@ -230,7 +230,7 @@ class TestCases(PfwTestCase): log.I("renaming a domain with an already existent domain name") log.I("Renaming domain %s to %s" % (self.domain_name,self.new_domain_name) ) log.I("command [renameDomain]") - out, err = self.pfw.sendCmd("renameDomain",self.domain_name,self.new_domain_name) + out, err = self.pfw.sendCmd("renameDomain",self.domain_name,self.new_domain_name, expectSuccess=False) assert out != "Done", out assert err == None, "INFO : command [renameDomain] - Error while renaming domain" log.I("command [renameDomain] - renaming error correctly detected") diff --git a/test/functional-tests/PfwTestCase/Functions/__init__.py b/test/functional-tests-legacy/PfwTestCase/Functions/__init__.py index 7b72df8..7b72df8 100644 --- a/test/functional-tests/PfwTestCase/Functions/__init__.py +++ b/test/functional-tests-legacy/PfwTestCase/Functions/__init__.py diff --git a/test/functional-tests/PfwTestCase/Functions/tFunction_Export_Import_Domains.py b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_Export_Import_Domains.py index 3af1395..2bfc50a 100644 --- a/test/functional-tests/PfwTestCase/Functions/tFunction_Export_Import_Domains.py +++ b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_Export_Import_Domains.py @@ -37,15 +37,12 @@ List of tested functions : - [importDomainsWithSettingsXML] function - [exportDomainsXML] function - [importDomainsXML] function - - [importSettings] function - - [exportSettings] function Test cases : ------------ - Testing importDomainsWithSettingsXML nominal case - Testing exportDomainsWithSettingsXML nominal case - Testing exportDomainsXML/importDomainsXML nominal case - - Testing importSettings/exportSettings nominal case - Testing import errors - Testing export errors """ @@ -61,33 +58,30 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setTuningMode", "on") self.param_name_01 = "/Test/Test/TEST_DIR/UINT16" - self.filesystem_01 = "$PFW_RESULT/UINT16" + self.filesystem_01 = os.environ["PFW_RESULT"] + "/UINT16" self.param_name_02 = "/Test/Test/TEST_DOMAIN_0/Param_00" - self.filesystem_02 = "$PFW_RESULT/Param_00" + self.filesystem_02 = os.environ["PFW_RESULT"] + "/Param_00" self.param_name_03 = "/Test/Test/TEST_DOMAIN_1/Param_12" - self.filesystem_03 = "$PFW_RESULT/Param_12" + self.filesystem_03 = os.environ["PFW_RESULT"] + "/Param_12" - pfw_test_tools=os.getenv("PFW_TEST_TOOLS") + pfw_test_tools=os.environ["PFW_TEST_TOOLS"] self.reference_xml = pfw_test_tools+"/xml/XML_Test/Reference_Compliant.xml" self.initial_xml = pfw_test_tools+"/xml/TestConfigurableDomains.xml" self.temp_config="f_Config_Backup" self.temp_domain="f_Domains_Backup" self.temp_xml=pfw_test_tools+"/f_temp.xml" - self.temp_binary=pfw_test_tools+"/f_temp.binary" self.nb_domains_in_reference_xml=3 self.nb_conf_per_domains_in_reference_xml=[2,2,2] def tearDown(self): - self.pfw.sendCmd("setTuningMode", "off") + self.pfw.sendCmd("setTuningMode", "off", expectSuccess=None) if os.path.exists(self.temp_domain): os.remove(self.temp_domain) if os.path.exists(self.temp_config): os.remove(self.temp_config) if os.path.exists(self.temp_xml): os.remove(self.temp_xml) - if os.path.exists(self.temp_binary): - os.remove(self.temp_binary) def test_01_importDomainsWithSettingsXML_Nominal_Case(self): """ @@ -130,18 +124,9 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [listDomains] : %s"%(err)) log.I("Command [listDomains] - correctly executed") # Domains listing backup - f_Domains_Backup = open(self.temp_domain, "w") - f_Domains_Backup.write(out) - f_Domains_Backup.close() - f_Domains_Backup = open(self.temp_domain, "r") - domains_nbr = 0 - line=f_Domains_Backup.readline() - while line!="": - line=f_Domains_Backup.readline() - domains_nbr+=1 - f_Domains_Backup.close() - log.I("Actual domains number : %s" % domains_nbr) - assert domains_nbr==self.nb_domains_in_reference_xml, log.F("Number of listed domains is not compliant with the file %s - expected : %s - found : %s"%(self.reference_xml,self.nb_domains_in_reference_xml, domains_nbr)) + domainBackup = out.strip('\r\n').splitlines() + log.I("Actual domains: %s" % domainBackup) + assert len(domainBackup)==self.nb_domains_in_reference_xml, log.F("Number of listed domains is not compliant with the file %s - expected : %s domains, found domains %s"%(self.reference_xml,self.nb_domains_in_reference_xml, domainBackup)) #Check number of config per domain(2 config per domains are setup in the reference XML) # Config listing @@ -153,7 +138,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [listConfigurations %s] : %s"%(domain_name,err)) log.I("Command [listConfigurations %s] - correctly executed"%(domain_name)) f_Config_Backup = open(self.temp_config, "w") - f_Config_Backup.write(out) + f_Config_Backup.write(out.strip('\r\n')) f_Config_Backup.close() f_Config_Backup = open(self.temp_config, "r") config_nbr = 0 @@ -162,7 +147,7 @@ class TestCases(PfwTestCase): line=f_Config_Backup.readline() config_nbr+=1 f_Config_Backup.close() - assert config_nbr==self.nb_conf_per_domains_in_reference_xml[index], log.F("Number of listed config for %s is not compliant with the file %s - expected : %s - found : %s"%(domain_name, self.reference_xml,self.nb_conf_per_domains_in_reference_xml[index], domains_nbr)) + assert config_nbr==self.nb_conf_per_domains_in_reference_xml[index], log.F("Number of listed config for %s is not compliant with the file %s - expected : %s - found : %s"%(domain_name, self.reference_xml,self.nb_conf_per_domains_in_reference_xml[index], config_nbr)) log.I("Config checking : OK") #Check number of config per domain(2 config per domains are setup in the reference XML) @@ -202,7 +187,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 expected_value="4" hex_value="0x4" @@ -211,7 +196,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 expected_value="4" hex_value="0x4" @@ -220,7 +205,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) log.I("Parameters checking : OK") def test_02_exportDomainsWithSettingsXML_Nominal_Case(self): @@ -266,9 +251,9 @@ class TestCases(PfwTestCase): init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) + init_filesystem_01 = open(self.filesystem_01).read()[:-1] + init_filesystem_02 = open(self.filesystem_02).read()[:-1] + init_filesystem_03 = open(self.filesystem_03).read()[:-1] ### END OF INIT ### @@ -305,7 +290,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 expected_value=str(int(init_value_02)+1) log.I("Param_00 parameter= %s"%(expected_value)) @@ -313,7 +298,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 expected_value=str(int(init_value_03)+1) log.I("Param_12 parameter= %s"%(expected_value)) @@ -321,7 +306,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) #Import the temp XML file self.pfw.sendCmd("setTuningMode", "on","") @@ -339,7 +324,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) == init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] == init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 expected_value=init_value_02 log.I("Param_00 parameter= %s"%(expected_value)) @@ -347,7 +332,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) == init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] == init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 expected_value=init_value_03 log.I("Param_12 parameter= %s"%(expected_value)) @@ -355,7 +340,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) == init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] == init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) def test_03_exportImportXML_withoutSettings_Nominal_Case(self): """ @@ -402,9 +387,9 @@ class TestCases(PfwTestCase): init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) + init_filesystem_01 = open(self.filesystem_01).read()[:-1] + init_filesystem_02 = open(self.filesystem_02).read()[:-1] + init_filesystem_03 = open(self.filesystem_03).read()[:-1] ### END OF INIT ### @@ -441,7 +426,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 expected_value=str(int(init_value_02)+1) log.I("Param_00 parameter= %s"%(expected_value)) @@ -449,7 +434,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 expected_value=str(int(init_value_03)+1) log.I("Param_12 parameter= %s"%(expected_value)) @@ -457,7 +442,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) #Import the temp XML file without self.pfw.sendCmd("setTuningMode", "on","") @@ -475,7 +460,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_01, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 unexpected_value=init_value_02 log.I("Param_00 parameter= %s"%(unexpected_value)) @@ -483,7 +468,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_02, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 unexpected_value=init_value_03 log.I("Param_12 parameter= %s"%(unexpected_value)) @@ -491,7 +476,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s"% (self.param_name_03, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) #Import the reference_XML file without settings self.pfw.sendCmd("setTuningMode", "on","") @@ -509,7 +494,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_01, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 unexpected_value=init_value_02 log.I("Param_00 parameter= %s"%(unexpected_value)) @@ -517,7 +502,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_02, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 unexpected_value=init_value_03 log.I("Param_12 parameter= %s"%(unexpected_value)) @@ -525,185 +510,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_03, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) - - - - def test_04_exportImportSettings_Binary_Nominal_Case(self): - """ - Testing exportSettings/importSettings nominal case - -------------------------------------------------- - Test case description : - ~~~~~~~~~~~~~~~~~~~~~~~ - - export settings in temp binary files - - import a reference XML - - restore Configuration - - import the temp binary files - - restore Configuration - - check Domains - - check Configuration - - check Parameters - Tested commands : - ~~~~~~~~~~~~~~~~~ - - [exportSettings] function - - [importDomainsWithSettingsXML] function - - [importSettings] function - Used commands : - ~~~~~~~~~~~~~~~ - - [restoreConfiguration] function - - [listDomains] function - - [listConfiguration] function - - [getRules] function - - [getParameter] function - Expected result : - ~~~~~~~~~~~~~~~~~ - - all operations succeed - """ - log.D(self.test_04_exportImportSettings_Binary_Nominal_Case.__doc__) - ### INIT Domains Settings #### - - #Import a reference XML file - - log.I("Import Domains with initial settings from %s" - %(self.reference_xml)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",self.reference_xml, "") - assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(self.reference_xml,err)) - assert out == "Done", log.F("When using function importDomainsWithSettingsXML %s]"%(self.reference_xml)) - self.pfw.sendCmd("setTuningMode", "off","") - init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") - init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") - init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) - - ### END OF INIT ### - - #Export domains without settings in a temp XML file - log.I("Export Domains without initial settings in %s"%(self.temp_xml)) - out, err = self.pfw.sendCmd("exportDomainsXML",self.temp_xml, "") - assert err == None, log.E("Command [exportDomainsXML %s] : %s"%(self.temp_xml,err)) - assert out == "Done", log.F("When using function exportDomainsXML %s]"%(self.temp_xml)) - #Export settings in a binary temp file - log.I("Export settings in the binary files %s"%(self.temp_binary)) - out, err = self.pfw.sendCmd("exportSettings",self.temp_binary, "") - assert err == None, log.E("Command [exportSettings %s] : %s"%(self.temp_binary,err)) - assert out == "Done", log.F("When using function exportSettings %s]"%(self.temp_binary)) - - #Change the value of checked parameters - self.pfw.sendCmd("setTuningMode", "on","") - out, err = self.pfw.sendCmd("setParameter", self.param_name_01, str(int(init_value_01)+1)) - out, err = self.pfw.sendCmd("setParameter", self.param_name_02, str(int(init_value_02)+1)) - out, err = self.pfw.sendCmd("setParameter", self.param_name_03, str(int(init_value_03)+1)) - #save config - domain_basename="Domain_" - conf_basename="Conf_" - for index_domain in range(3): - for index_conf in range(2): - domain_name=domain_basename+str(index_domain+1) - conf_name=conf_basename+str(index_domain+1)+"_"+str(index_conf) - log.I("Save config %s for domain %s"%(conf_name,domain_name)) - out, err = self.pfw.sendCmd("saveConfiguration",domain_name,conf_name) - assert err == None, log.E("Command [saveConfiguration %s %s] : %s"%(domain_name,conf_name,err)) - assert out =="Done", log.F("When saving configuration %s for domain %s"%(conf_name,domain_name)) - log.I("Save configurations: OK") - self.pfw.sendCmd("setTuningMode", "off","") - - #Check parameter values - #UINT16 - expected_value=str(int(init_value_01)+1) - log.I("UINT16 parameter = %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) - #Param_00 - expected_value=str(int(init_value_02)+1) - log.I("Param_00 parameter= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) - #Param_12 - expected_value=str(int(init_value_03)+1) - log.I("Param_12 parameter= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) - - #Import the temp XML file without - self.pfw.sendCmd("setTuningMode", "on","") - log.I("Import Domains without settings from %s"%(self.temp_xml)) - out, err = self.pfw.sendCmd("importDomainsXML",self.temp_xml, "") - assert err == None, log.E("Command [importDomainsXML %s] : %s"%(self.temp_xml,err)) - assert out == "Done", log.F("When using function importDomainsXML %s]"%(self.temp_xml)) - self.pfw.sendCmd("setTuningMode", "off","") - - #Check parameter values - #UINT16 - unexpected_value=init_value_01 - log.I("UINT16 parameter = %s"%(unexpected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) - assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_01, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) - #Param_00 - unexpected_value=init_value_02 - log.I("Param_00 parameter= %s"%(unexpected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) - assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s" % (self.param_name_02, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) - #Param_12 - unexpected_value=init_value_03 - log.I("Param_12 parameter= %s"%(unexpected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) - assert out != unexpected_value, log.F("BLACKBOARD : Unexpected value found for %s: %s"% (self.param_name_03, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) - - #Import settings from the binary files - self.pfw.sendCmd("setTuningMode", "on","") - log.I("Import settings from %s"%(self.temp_binary)) - out, err = self.pfw.sendCmd("importSettings",self.temp_binary, "") - assert err == None, log.E("Command [importSettings %s] : %s"%(self.temp_binary,err)) - assert out == "Done", log.F("When using function importSettings %s]"%(self.temp_binary)) - self.pfw.sendCmd("setTuningMode", "off","") - - #Check parameter values - #UINT16 - expected_value=init_value_01 - log.I("UINT16 parameter = %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) == init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) - #Param_00 - expected_value=init_value_02 - log.I("Param_00 parameter= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) == init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) - #Param_12 - expected_value=init_value_03 - log.I("Param_12 parameter= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) == init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) - - + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) @unittest.expectedFailure def test_05_Import_XML_With_Settings_Error_Case(self): @@ -721,7 +528,6 @@ class TestCases(PfwTestCase): ~~~~~~~~~~~~~~~~~ - [importDomainsWithSettingsXML] function - [importDomainsXML] function - - [importSettings] function Used commands : ~~~~~~~~~~~~~~~ - [restoreConfiguration] function @@ -747,45 +553,45 @@ class TestCases(PfwTestCase): init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) - xml_path="$PFW_TEST_TOOLS/xml/XML_Test/" + init_filesystem_01 = open(self.filesystem_01).read()[:-1] + init_filesystem_02 = open(self.filesystem_02).read()[:-1] + init_filesystem_03 = open(self.filesystem_03).read()[:-1] + xml_path=os.environ["PFW_TEST_TOOLS"] + "/xml/XML_Test/" ### END OF INIT ### self.pfw.sendCmd("setTuningMode", "on","") #Import domains and settings from xml with outbound parameter value xml_name="Uncompliant_OutboundParameter.xml" log.I("Import %s with initial settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains and settings from xml using undeclared configurable element xml_name="Uncompliant_UndeclaredConfigurableElement.xml" log.I("Import %s with initial settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains and settings from xml using undeclared parameter xml_name="Uncompliant_UndeclaredParameter.xml" log.I("Import %s with initial settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains and settings from xml using wrong order of configurable element xml_name="Uncompliant_UnorderConfigurableElement.xml" log.I("Import %s with initial settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains and settings from unexistent xml xml_name="Unexistent.xml" log.I("Import %s with initial settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) @@ -802,7 +608,7 @@ class TestCases(PfwTestCase): log.I("Command [listDomains] - correctly executed") # Domains listing backup f_Domains_Backup = open(self.temp_domain, "w") - f_Domains_Backup.write(out) + f_Domains_Backup.write(out.strip('\r\n')) f_Domains_Backup.close() f_Domains_Backup = open(self.temp_domain, "r") domains_nbr = 0 @@ -823,7 +629,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [listConfigurations %s] : %s"%(domain_name,err)) log.I("Command [listConfigurations %s] - correctly executed"%(domain_name)) f_Config_Backup = open(self.temp_config, "w") - f_Config_Backup.write(out) + f_Config_Backup.write(out.strip('\r\n')) f_Config_Backup.close() f_Config_Backup = open(self.temp_config, "r") config_nbr = 0 @@ -843,7 +649,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #Param_00 expected_value=init_value_02 hex_value=init_filesystem_02 @@ -852,7 +658,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #Param_12 expected_value=init_value_03 hex_value=init_filesystem_03 @@ -861,7 +667,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) log.I("Parameters checking : OK") #### END check domains and settings #### @@ -884,7 +690,6 @@ class TestCases(PfwTestCase): ~~~~~~~~~~~~~~~~~ - [importDomainsWithSettingsXML] function - [importDomainsXML] function - - [importSettings] function Used commands : ~~~~~~~~~~~~~~~ - [restoreConfiguration] function @@ -907,42 +712,42 @@ class TestCases(PfwTestCase): assert out == "Done", log.F("When using function importDomainsWithSettingsXML %s]"%(self.reference_xml)) self.pfw.sendCmd("setTuningMode", "off","") - xml_path="$PFW_TEST_TOOLS/xml/XML_Test/" + xml_path=os.environ["PFW_TEST_TOOLS"] + "/xml/XML_Test/" ### END OF INIT ### self.pfw.sendCmd("setTuningMode", "on","") #Import domains from xml with outbound parameter value xml_name="Uncompliant_OutboundParameter.xml" log.I("Import %s without settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains from xml using undeclared configurable element xml_name="Uncompliant_UndeclaredConfigurableElement.xml" log.I("Import %s without settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains from xml using undeclared parameter #xml_name="Uncompliant_UndeclaredParameter.xml" #log.I("Import %s without settings"%(xml_name)) - #out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "") + #out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "", expectSuccess=False) #assert err == None, log.E("Command [importDomainsXML %s] : %s"%(xml_path+xml_name,err)) #assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) #log.I("Test OK : %s is not imported"%(xml_name)) #Import domains from xml using wrong order of configurable element xml_name="Uncompliant_UnorderConfigurableElement.xml" log.I("Import %s without settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) #Import domains from unexistent xml xml_name="Unexistent.xml" log.I("Import %s without settings"%(xml_name)) - out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "") + out, err = self.pfw.sendCmd("importDomainsXML",xml_path+xml_name, "", expectSuccess=False) assert err == None, log.E("Command [importDomainsXML %s] : %s"%(xml_path+xml_name,err)) assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+xml_name)) log.I("Test OK : %s is not imported"%(xml_name)) @@ -959,7 +764,7 @@ class TestCases(PfwTestCase): log.I("Command [listDomains] - correctly executed") # Domains listing backup f_Domains_Backup = open(self.temp_domain, "w") - f_Domains_Backup.write(out) + f_Domains_Backup.write(out.strip('\r\n')) f_Domains_Backup.close() f_Domains_Backup = open(self.temp_domain, "r") domains_nbr = 0 @@ -969,7 +774,7 @@ class TestCases(PfwTestCase): domains_nbr+=1 f_Domains_Backup.close() log.I("Actual domains number : %s" % domains_nbr) - assert domains_nbr==self.nb_domains_in_reference_xml, log.F("Number of listed domains is not compliant with the file %s - expected : %s - found : %s"%(self.reference_xml,self.nb_domains_in_reference_xml, domains_nbr)) + assert domains_nbr==self.nb_domains_in_reference_xml, log.F("Number of listed domains is not compliant with the file %s - expected %s domains, found domains: %s"%(self.reference_xml,self.nb_domains_in_reference_xml, domains_nbr)) #Check number of config per domain(2 config per domains are setup in the reference XML) # Config listing domain_basename="Domain_" @@ -980,7 +785,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [listConfigurations %s] : %s"%(domain_name,err)) log.I("Command [listConfigurations %s] - correctly executed"%(domain_name)) f_Config_Backup = open(self.temp_config, "w") - f_Config_Backup.write(out) + f_Config_Backup.write(out.strip('\r\n')) f_Config_Backup.close() f_Config_Backup = open(self.temp_config, "r") config_nbr = 0 @@ -993,151 +798,3 @@ class TestCases(PfwTestCase): log.I("Config checking : OK") #### END check domains and settings #### - - - @unittest.expectedFailure - def test_07_Import_Settings_From_Binary_Error_Case(self): - """ - Testing importDomainsWithSettingsXML error case - ---------------------------------------------- - Test case description : - ~~~~~~~~~~~~~~~~~~~~~~~ - - import settings from a non-compliant binary - - import settings from a non-existing file - - check Domains - - check Configuration - - check Parameters - Tested commands : - ~~~~~~~~~~~~~~~~~ - - [importDomainsWithSettingsXML] function - - [importDomainsXML] function - - [importSettings] function - Used commands : - ~~~~~~~~~~~~~~~ - - [restoreConfiguration] function - - [listDomains] function - - [listConfiguration] function - - [getRules] function - - [getParameter] function - Expected result : - ~~~~~~~~~~~~~~~~~ - - all errors are detected, initial domains keep settings - """ - log.D(self.test_07_Import_Settings_From_Binary_Error_Case.__doc__) - - ### INIT Domains Settings #### - #Import the initial XML file - log.I("Import Domains with initial settings from %s"%(self.initial_xml)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",self.initial_xml, "") - assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(self.initial_xml,err)) - assert out == "Done", log.F("When using function importDomainsWithSettingsXML %s]"%(self.initial_xml)) - #Export a binary files from the initial setting and config - log.I("Export settings in the binary files %s"%(self.temp_binary)) - out, err = self.pfw.sendCmd("exportSettings",self.temp_binary, "") - assert err == None, log.E("Command [exportSettings %s] : %s"%(self.temp_binary,err)) - assert out == "Done", log.F("When using function exportSettings %s]"%(self.temp_binary)) - #Import the reference XML file with another configuration - log.I("Import Domains with initial settings from %s"%(self.reference_xml)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",self.reference_xml, "") - assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(self.reference_xml,err)) - assert out == "Done", log.F("When using function importDomainsWithSettingsXML %s]"%(self.reference_xml)) - - self.pfw.sendCmd("setTuningMode", "off","") - init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") - init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") - init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) - xml_path="$PFW_TEST_TOOLS/xml/XML_Test/" - ### END OF INIT ### - - self.pfw.sendCmd("setTuningMode", "on","") - #Import the temporary binary file, normaly uncompatible with this config - self.pfw.sendCmd("setTuningMode", "on","") - log.I("Import settings from %s"%(self.temp_binary)) - out, err = self.pfw.sendCmd("importSettings",self.temp_binary, "") - assert err == None, log.E("Command [importSettings %s] : %s"%(self.temp_binary,err)) - assert out != "Done", log.F("Error not detected when imported %s]"%(self.temp_binary)) - log.I("Test OK : %s is not imported"%(self.temp_binary)) - #Import setings from a non-existing binary files - name="Unexistent" - log.I("Import settings from %s"%(name)) - out, err = self.pfw.sendCmd("importDomainsWithSettingsXML",xml_path+name, "") - assert err == None, log.E("Command [importDomainsWithSettingsXML %s] : %s"%(xml_path+name,err)) - assert out != "Done", log.F("Error not detected when imported %s]"%(xml_path+name)) - log.I("Test OK : %s is not imported"%(name)) - self.pfw.sendCmd("setTuningMode", "off","") - - #### check domains and settings #### - - #Check number of domain(3 domains are setup in the reference XML, initially only one domains is declared) - # Domains listing using "listDomains" command - log.I("Current domains listing") - log.I("Command [listDomains]") - out, err = self.pfw.sendCmd("listDomains","","") - assert err == None, log.E("Command [listDomains] : %s"%(err)) - log.I("Command [listDomains] - correctly executed") - # Domains listing backup - f_Domains_Backup = open(self.temp_domain, "w") - f_Domains_Backup.write(out) - f_Domains_Backup.close() - f_Domains_Backup = open(self.temp_domain, "r") - domains_nbr = 0 - line=f_Domains_Backup.readline() - while line!="": - line=f_Domains_Backup.readline() - domains_nbr+=1 - f_Domains_Backup.close() - log.I("Actual domains number : %s" % domains_nbr) - assert domains_nbr==self.nb_domains_in_reference_xml, log.F("Number of listed domains is not compliant with the file %s - expected : %s - found : %s"%(self.reference_xml,self.nb_domains_in_reference_xml, domains_nbr)) - #Check number of config per domain(2 config per domains are setup in the reference XML) - # Config listing - domain_basename="Domain_" - for index in range(self.nb_domains_in_reference_xml): - domain_name=domain_basename+str(index+1) - log.I("Listing config for domain %s"%(domain_name)) - out, err = self.pfw.sendCmd("listConfigurations",domain_name,"") - assert err == None, log.E("Command [listConfigurations %s] : %s"%(domain_name,err)) - log.I("Command [listConfigurations %s] - correctly executed"%(domain_name)) - f_Config_Backup = open(self.temp_config, "w") - f_Config_Backup.write(out) - f_Config_Backup.close() - f_Config_Backup = open(self.temp_config, "r") - config_nbr = 0 - line=f_Config_Backup.readline() - while line!="": - line=f_Config_Backup.readline() - config_nbr+=1 - f_Config_Backup.close() - assert config_nbr==self.nb_conf_per_domains_in_reference_xml[index], log.F("Number of listed config for %s is not compliant with the file %s - expected : %s - found : %s"%(domain_name, self.reference_xml,self.nb_conf_per_domains_in_reference_xml[index], domains_nbr)) - log.I("Config checking : OK") - #Check parameter values - #UINT16 - expected_value=init_value_01 - hex_value=init_filesystem_01 - log.I("UINT16 parameter in the conf Conf_1_1= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_01, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_01, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_01)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) - #Param_00 - expected_value=init_value_02 - hex_value=init_filesystem_02 - log.I("Param_00 parameter in the conf Conf_2_1= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_02, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_02, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_02)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) - #Param_12 - expected_value=init_value_03 - hex_value=init_filesystem_03 - log.I("Param_12 parameter in the conf Conf_3_1= %s"%(expected_value)) - out, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - assert err == None, log.E("When setting parameter %s : %s" % (self.param_name_03, err)) - assert out == expected_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name_03, expected_value, out)) - #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_03)) == hex_value, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) - log.I("Parameters checking : OK") diff --git a/test/functional-tests/PfwTestCase/Functions/tFunction_Sync.py b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_Sync.py index 993e8e1..d95318d 100644 --- a/test/functional-tests/PfwTestCase/Functions/tFunction_Sync.py +++ b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_Sync.py @@ -54,7 +54,7 @@ class TestCases(PfwTestCase): def setUp(self): - pfw_filesystem=os.getenv("PFW_RESULT") + pfw_filesystem=os.environ["PFW_RESULT"] self.pfw.sendCmd("setTuningMode", "on") self.param_name_01 = "/Test/Test/TEST_DIR/BOOL" @@ -133,9 +133,9 @@ class TestCases(PfwTestCase): init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) + init_filesystem_01 = open(self.filesystem_01).read()[:-1] + init_filesystem_02 = open(self.filesystem_02).read()[:-1] + init_filesystem_03 = open(self.filesystem_03).read()[:-1] #Implement a new value if int(init_value_01)==0 : new_value_01 = "1" @@ -155,11 +155,11 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setParameter", self.param_name_03, new_value_03) #Check the filesystem values #BOOL - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #INT16 - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #UINT32 - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) log.I("test setAutoSync %s : OK"%(value)) #Enable the autosync value = "off" @@ -173,11 +173,11 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setParameter", self.param_name_03, init_value_03) #Check the filesystem values #BOOL - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_01) #INT16 - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_02) #UINT32 - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_03) log.I("test setAutoSync %s : OK"%(value)) @@ -208,9 +208,9 @@ class TestCases(PfwTestCase): init_value_01, err = self.pfw.sendCmd("getParameter", self.param_name_01, "") init_value_02, err = self.pfw.sendCmd("getParameter", self.param_name_02, "") init_value_03, err = self.pfw.sendCmd("getParameter", self.param_name_03, "") - init_filesystem_01 = commands.getoutput("cat %s"%(self.filesystem_01)) - init_filesystem_02 = commands.getoutput("cat %s"%(self.filesystem_02)) - init_filesystem_03 = commands.getoutput("cat %s"%(self.filesystem_03)) + init_filesystem_01 = open(self.filesystem_01).read()[:-1] + init_filesystem_02 = open(self.filesystem_02).read()[:-1] + init_filesystem_03 = open(self.filesystem_03).read()[:-1] #Implement a new value if int(init_value_01)==0 : new_value_01 = "1" @@ -230,11 +230,11 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setParameter", self.param_name_03, new_value_03) #Check the filesystem values, must not changed #BOOL - assert commands.getoutput("cat %s"%(self.filesystem_01)) == init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] == init_filesystem_01, log.F("FILESYSTEM : parameter %s update error"%self.param_name_01) #INT16 - assert commands.getoutput("cat %s"%(self.filesystem_02)) == init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] == init_filesystem_02, log.F("FILESYSTEM : parameter %s update error"%self.param_name_02) #UINT32 - assert commands.getoutput("cat %s"%(self.filesystem_03)) == init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] == init_filesystem_03, log.F("FILESYSTEM : parameter %s update error"%self.param_name_03) log.I("test setAutoSync %s : OK"%(value)) log.I("Sync") out,err = self.pfw.sendCmd("sync", "") @@ -242,9 +242,9 @@ class TestCases(PfwTestCase): assert out == "Done", log.F("Sync - expected : Done , found : %s" % (out)) #Check the filesystem values #BOOL - assert commands.getoutput("cat %s"%(self.filesystem_01)) != init_filesystem_01, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_01) + assert open(self.filesystem_01).read()[:-1] != init_filesystem_01, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_01) #INT16 - assert commands.getoutput("cat %s"%(self.filesystem_02)) != init_filesystem_02, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_02) + assert open(self.filesystem_02).read()[:-1] != init_filesystem_02, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_02) #UINT32 - assert commands.getoutput("cat %s"%(self.filesystem_03)) != init_filesystem_03, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_03) + assert open(self.filesystem_03).read()[:-1] != init_filesystem_03, log.F("FILESYSTEM : parameter %s is updated, autosync is still enabled"%self.param_name_03) log.I("test setAutoSync %s : OK"%(value)) diff --git a/test/functional-tests/PfwTestCase/Functions/tFunction_getParameter.py b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_getParameter.py index 2e02713..e0c7fb9 100644 --- a/test/functional-tests/PfwTestCase/Functions/tFunction_getParameter.py +++ b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_getParameter.py @@ -70,7 +70,7 @@ class TestCases(PfwTestCase): log.D(self.test_Function_Commands_Errors.__doc__) #Get undefined parameter value log.I("Get undefined parameter value") - out, err = self.pfw.sendCmd("getParameter", "Undefined_parameter") + out, err = self.pfw.sendCmd("getParameter", "Undefined_parameter", expectSuccess=False) print str(out) assert err == None, "Error when getting parameter : %s" % (err) assert out != "Done", "Error not detected when getting an undefined parameter" diff --git a/test/functional-tests/PfwTestCase/Functions/tFunction_listingFunctions.py b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_listingFunctions.py index 5fa9fd0..327f2e4 100644 --- a/test/functional-tests/PfwTestCase/Functions/tFunction_listingFunctions.py +++ b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_listingFunctions.py @@ -53,7 +53,7 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setTuningMode", "on") - pfw_test_tools=os.getenv("PFW_TEST_TOOLS") + pfw_test_tools=os.environ["PFW_TEST_TOOLS"] self.reference_dumpDomains_xml = pfw_test_tools+"/xml/XML_Test/Reference_dumpDomains.xml" self.reference_dumpDomains_file = pfw_test_tools+"/xml/XML_Test/Reference_dumpDomains" self.initial_xml = pfw_test_tools+"/xml/TestConfigurableDomains.xml" @@ -102,7 +102,7 @@ class TestCases(PfwTestCase): log.I("Command [dumpDomains]") out, err = self.pfw.sendCmd("dumpDomains","","") assert err == None, log.E("Command [dumpDomains] : %s"%(err)) - assert out == commands.getoutput("cat %s"%(self.reference_dumpDomains_file)), log.F("A diff is found between dumpDomains output and %s"%(self.reference_dumpDomains_file)) + self.assertEqual(out.splitlines(), open(self.reference_dumpDomains_file).read().splitlines()) log.I("Command [dumpDomains] - correctly executed") def test_03_help_Case(self): @@ -166,9 +166,9 @@ class TestCases(PfwTestCase): """ log.D(self.test_05_listCriteria_Case.__doc__) log.I("Command [listCriteria]") - out, err = self.pfw.sendCmd("listCriteria","") + out, err = self.pfw.sendCmd("listCriteria", "XML") assert err == None, log.E("Command [listCriteria] : %s"%(err)) - assert out != "" + self.assertNotEqual(out, "") log.I("Command [listCriteria] - correctly executed") def test_06_listDomains_Case(self): @@ -256,7 +256,7 @@ class TestCases(PfwTestCase): """ log.D(self.test_08_listElements_Case.__doc__) log.I("Command [listElements]") - out, err = self.pfw.sendCmd("listElements") + out, err = self.pfw.sendCmd("listElements", expectSuccess=False) assert err == None, log.E("Command [listElements] : %s"%(err)) out, err = self.pfw.sendCmd("listElements","/Test/") assert err == None, log.E("Command [listElements /Test/] : %s"%(err)) @@ -280,7 +280,7 @@ class TestCases(PfwTestCase): """ log.D(self.test_09_listParameters_Case.__doc__) log.I("Command [listParameters]") - out, err = self.pfw.sendCmd("listParameters") + out, err = self.pfw.sendCmd("listParameters", expectSuccess=False) assert err == None, log.E("Command [listParameters] : %s"%(err)) out, err = self.pfw.sendCmd("listParameters","/Test/") assert err == None, log.E("Command [listParameters /Test/] : %s"%(err)) @@ -336,7 +336,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [getElementSize /Test/] : %s"%(err)) assert out != "" - out, err = self.pfw.sendCmd("getElementSize") + out, err = self.pfw.sendCmd("getElementSize", expectSuccess=False) assert err == None, log.E("Command [getElementSize /Test/] : %s"%(err)) def test_11_showProperties_Case(self): @@ -388,7 +388,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("Command [showProperties /Test/] : %s"%(err)) assert out != "" - out, err = self.pfw.sendCmd("showProperties") + out, err = self.pfw.sendCmd("showProperties", expectSuccess=False) assert err == None, log.E("Command [showProperties] : %s"%(err)) def test_12_listBelongingDomains_Case(self): @@ -438,7 +438,7 @@ class TestCases(PfwTestCase): out, err = self.pfw.sendCmd("listBelongingDomains","/Test/") assert err == None, log.E("Command [listBelongingDomains /Test/] : %s"%(err)) - out, err = self.pfw.sendCmd("listBelongingDomains") + out, err = self.pfw.sendCmd("listBelongingDomains", expectSuccess=False) assert err == None, log.E("Command [listBelongingDomains] : %s"%(err)) def test_13_listAssociatedDomains_Case(self): diff --git a/test/functional-tests/PfwTestCase/Functions/tFunction_setParameter.py b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_setParameter.py index b5605dd..62a7ca2 100644 --- a/test/functional-tests/PfwTestCase/Functions/tFunction_setParameter.py +++ b/test/functional-tests-legacy/PfwTestCase/Functions/tFunction_setParameter.py @@ -73,18 +73,18 @@ class TestCases(PfwTestCase): log.D(self.test_Function_Commands_Errors.__doc__) #Set undefined parameter value log.I("Set undefined parameter value") - out, err = self.pfw.sendCmd("setParameter", "Undefined_parameter", "0") + out, err = self.pfw.sendCmd("setParameter", "Undefined_parameter", "0", expectSuccess=False) assert err == None, "Error when setting parameter : %s" % (err) assert out != "Done", "Error not detected when setting an undefined parameter" #Set parameter with a forbiden character value log.I("Set parameter with a forbiden character value") - out, err = self.pfw.sendCmd("setParameter", self.param_name, "Wrong_Value") + out, err = self.pfw.sendCmd("setParameter", self.param_name, "Wrong_Value", expectSuccess=False) assert err == None, "Error when setting parameter : %s" % (err) assert out != "Done", "Error not detected when setting a parameter with a forbiden character value" log.I("Errors correctly detected") #Set parameter with a Float into an Integer parameter log.I("Set parameter with a Float into an Integer parameter") - out, err = self.pfw.sendCmd("setParameter", self.param_name, "1.2345") + out, err = self.pfw.sendCmd("setParameter", self.param_name, "1.2345", expectSuccess=False) assert err == None, "Error when setting parameter : %s" % (err) assert out != "Done", "Error not detected when setting a Float into an Integer parameter" log.I("Errors correctly detected") diff --git a/test/functional-tests/PfwTestCase/Types/__init__.py b/test/functional-tests-legacy/PfwTestCase/Types/__init__.py index 9fbd9f6..9fbd9f6 100644 --- a/test/functional-tests/PfwTestCase/Types/__init__.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/__init__.py diff --git a/test/functional-tests/PfwTestCase/Types/tBit_Block.py b/test/functional-tests-legacy/PfwTestCase/Types/tBit_Block.py index 512a1a7..f0161ad 100644 --- a/test/functional-tests/PfwTestCase/Types/tBit_Block.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tBit_Block.py @@ -54,6 +54,7 @@ Test cases : - Testing out of size TestCase : Bit define on a wrong position """ +import os import commands import unittest from Util.PfwUnitTestLib import PfwTestCase @@ -64,7 +65,7 @@ log=ACTLogging.Logger() class TestCases(PfwTestCase): def setUp(self): self.block_name = "/Test/Test/TEST_TYPES/BLOCK_8BIT" - self.filesystem_name="$PFW_RESULT/BLOCK_8BIT" + self.filesystem_name=os.environ["PFW_RESULT"] + "/BLOCK_8BIT" self.bit_name=[] @@ -123,7 +124,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.block_name, err)) assert out == value_bit[index_bit], log.F("getParameter %s - Expected : %s Found : %s" %(self.bit_name[index_bit],value_bit[index_bit], out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value[index_bit], log.F("FILESYSTEM : parameter update error for %s after setting bit %s "%(self.block_name, self.bit_name[index_bit])) + assert open(self.filesystem_name).read()[:-1] == filesystem_value[index_bit], log.F("FILESYSTEM : parameter update error for %s after setting bit %s "%(self.block_name, self.bit_name[index_bit])) def test_Set_Block_Directly_Case(self): @@ -156,18 +157,18 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s"%self.bit_name[index_bit]) init_value_bit.append(out) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("Try to set parameter %s to %s, failed expected"%(self.block_name,value)) - out,err = self.pfw.sendCmd("setParameter",self.block_name, value) + out,err = self.pfw.sendCmd("setParameter",self.block_name, value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.block_name, value, err)) assert out != "Done", log.F("Error not detected when setting directly the block %s" % (self.block_name)) log.I("Try to get parameter %s to %s, failed expected"%(self.block_name,value)) - out,err = self.pfw.sendCmd("getParameter",self.block_name, value) + out,err = self.pfw.sendCmd("getParameter",self.block_name, value, expectSuccess=False) assert err == None, log.E("getParameter %s : %s" % (self.block_name, err)) assert out != value, log.F("Error not detected when getting directly the block %s" % (self.block_name)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) log.I("Check Bit value") for index_bit in range(4): @@ -207,10 +208,10 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s"%self.bit_name[index_bit]) init_value_bit.append(out) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("set parameter %s to %s, failed expected"%(self.bit_name[1],bit_value)) - out,err = self.pfw.sendCmd("setParameter",self.bit_name[1],bit_value) + out,err = self.pfw.sendCmd("setParameter",self.bit_name[1],bit_value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.bit_name[1],bit_value, err)) assert out != "Done", log.F("Error not detected when setting the bit %s to out of bound value %s" % (self.bit_name[1],bit_value)) log.I("Check Bit value") @@ -218,7 +219,7 @@ class TestCases(PfwTestCase): out,err=self.pfw.sendCmd("getParameter",self.bit_name[index_bit]) assert out==init_value_bit[index_bit], log.F("BLACKBOARD: Forbidden change value for bit %s - Expected : %s Found : %s"%(self.bit_name[index_bit],init_value_bit[index_bit],out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) def test_Undefined_Bit_Case(self): """ @@ -251,10 +252,10 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s"%self.bit_name[index_bit]) init_value_bit.append(out) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("set parameter %s to %s, failed expected"%(bit_undefined_name,bit_value)) - out,err = self.pfw.sendCmd("setParameter",bit_undefined_name,bit_value) + out,err = self.pfw.sendCmd("setParameter",bit_undefined_name,bit_value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (bit_undefined_name,bit_value, err)) assert out != "Done", log.F("Error not detected when setting the bit %s to out of bound value %s" % (bit_undefined_name,bit_value)) log.I("Check Bit value") @@ -262,7 +263,7 @@ class TestCases(PfwTestCase): out,err=self.pfw.sendCmd("getParameter",self.bit_name[index_bit]) assert out==init_value_bit[index_bit], log.F("BLACKBOARD: Forbidden change value for bit %s - Expected : %s Found : %s"%(self.bit_name[index_bit],init_value_bit[index_bit],out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) @unittest.expectedFailure def test_Position_Conflicting_Case(self): @@ -305,7 +306,7 @@ class TestCases(PfwTestCase): out,err=self.pfw.sendCmd("getParameter",self.bit_name[index_bit]) init_value_bit.append(out) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("set parameter %s to %s, failed expected"%(self.bit_name[4],bit_value_7_1)) out,err = self.pfw.sendCmd("setParameter",self.bit_name[4],bit_value_7_1) @@ -316,4 +317,4 @@ class TestCases(PfwTestCase): out,err=self.pfw.sendCmd("getParameter",self.bit_name[index_bit]) assert out==init_value_bit[index_bit], log.F("BLACKBOARD: Forbidden change value for bit %s - Expected : %s Found : %s"%(self.bit_name[index_bit],init_value_bit[index_bit],out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.block_name)) diff --git a/test/functional-tests/PfwTestCase/Types/tBoolean.py b/test/functional-tests-legacy/PfwTestCase/Types/tBoolean.py index 0658964..9c95692 100644 --- a/test/functional-tests/PfwTestCase/Types/tBoolean.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tBoolean.py @@ -128,7 +128,7 @@ class TestCases(PfwTestCase): """ print self.testBooleanNegative.__doc__ value = "-1" - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("When setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("When setting parameter %s : %s" % (self.param_name, out)) out, err = self.pfw.sendCmd("getParameter", self.param_name, "") @@ -154,7 +154,7 @@ class TestCases(PfwTestCase): """ print self.testBooleanOverflow.__doc__ value = "2" - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("When setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("When setting parameter %s : %s" % (self.param_name, out)) out, err = self.pfw.sendCmd("getParameter", self.param_name, "") diff --git a/test/functional-tests/PfwTestCase/Types/tEnum.py b/test/functional-tests-legacy/PfwTestCase/Types/tEnum.py index 095b57d..524e763 100644 --- a/test/functional-tests/PfwTestCase/Types/tEnum.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tEnum.py @@ -50,6 +50,7 @@ Test cases : - Enum parameter out of size value = ENUM_OOS : 256 - Enum parameter undefined value = UNDEF """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -59,7 +60,7 @@ log=ACTLogging.Logger() class TestCases(PfwTestCase): def setUp(self): self.param_name = "/Test/Test/TEST_TYPES/ENUM" - self.filesystem_name="$PFW_RESULT/ENUM" + self.filesystem_name=os.environ["PFW_RESULT"] + "/ENUM" self.pfw.sendCmd("setTuningMode", "on") def tearDown(self): @@ -96,7 +97,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.param_name, err)) assert out == value, log.F("getParameter %s - expected : %s , found : %s" % (self.param_name,value,out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) def test_TypeMin(self): """ @@ -128,7 +129,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.param_name, err)) assert out == value, log.F("getParameter %s - expected : %s , found : %s" % (self.param_name,value,out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) def test_TypeMax(self): """ @@ -160,7 +161,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.param_name, err)) assert out == value, log.F("getParameter %s - expected : %s , found : %s" % (self.param_name,value,out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) def test_TypeUndefined(self): """ @@ -184,9 +185,9 @@ class TestCases(PfwTestCase): value = "UNDEF" log.I("Check parameter %s initial value"%(self.param_name)) init_parameter_value, err=self.pfw.sendCmd("getParameter",self.param_name) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("Set parameter %s to %s"%(self.param_name,value)) - out,err = self.pfw.sendCmd("setParameter",self.param_name, value) + out,err = self.pfw.sendCmd("setParameter",self.param_name, value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.param_name, value, err)) assert out != "Done", log.F("Error not detected when setParameter %s %s" % (self.param_name, value)) log.I("Check Enum parameter state") @@ -194,7 +195,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.param_name, err)) assert out == init_parameter_value, log.F("getParameter %s - expected : %s , found : %s" % (self.param_name,init_parameter_value,out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) def test_TypeOutOfBound(self): """ @@ -218,9 +219,9 @@ class TestCases(PfwTestCase): value = "ENUM_OOB" log.I("Check parameter %s initial value"%(self.param_name)) init_parameter_value, err=self.pfw.sendCmd("getParameter",self.param_name) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("Set parameter %s to %s"%(self.param_name,value)) - out,err = self.pfw.sendCmd("setParameter",self.param_name, value) + out,err = self.pfw.sendCmd("setParameter",self.param_name, value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.param_name, value, err)) assert out != "Done", log.F("Error not detected when setParameter %s %s" % (self.param_name, value)) log.I("Check Enum parameter state") @@ -228,7 +229,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.param_name, err)) assert out == init_parameter_value, log.F("getParameter %s - expected : %s , found : %s" % (self.param_name,init_parameter_value,out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) def test_TypeOutOfSize(self): """ @@ -252,9 +253,9 @@ class TestCases(PfwTestCase): value = "ENUM_OOS" log.I("Check parameter %s initial value"%(self.param_name)) init_parameter_value, err=self.pfw.sendCmd("getParameter",self.param_name) - init_filesystem_value=commands.getoutput("cat %s"%(self.filesystem_name)) + init_filesystem_value=open(self.filesystem_name).read()[:-1] log.I("Set parameter %s to %s"%(self.param_name,value)) - out,err = self.pfw.sendCmd("setParameter",self.param_name, value) + out,err = self.pfw.sendCmd("setParameter",self.param_name, value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.param_name, value, err)) assert out != "Done", log.F("Error not detected when setParameter %s %s" % (self.param_name, value)) log.I("Check Enum parameter state") @@ -262,4 +263,4 @@ class TestCases(PfwTestCase): assert err == None, log.E("getParameter %s : %s" % (self.param_name, err)) assert out == init_parameter_value, log.F("getParameter %s - expected : %s , found : %s" % (self.param_name,init_parameter_value,out)) log.I("Check filesystem value") - assert commands.getoutput("cat %s"%(self.filesystem_name)) == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) + assert open(self.filesystem_name).read()[:-1] == init_filesystem_value, log.F("FILESYSTEM : parameter update error for %s"%(self.param_name)) diff --git a/test/functional-tests/PfwTestCase/Types/tFP16_Q0_15.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP16_Q0_15.py index 11a7df3..0c9e273 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP16_Q0_15.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP16_Q0_15.py @@ -51,6 +51,7 @@ Test cases : - FP16_Q0.15 parameter max value out of bounds = 0.99997 - FP16_Q0.15 parameter in nominal case = 0.2453 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -97,7 +98,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert round(float(out),4) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -131,7 +132,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert round(float(out), 6) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s") % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" log.I("test OK") def test_TypeMin_Overflow(self): @@ -155,14 +156,14 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMin_Overflow.__doc__) value = "-1.00001" - param_check = commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') + param_check = open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -197,7 +198,7 @@ class TestCases(PfwTestCase): assert round(float(out), 6) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, round(float(out), 5))) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -221,12 +222,12 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMax_Overflow.__doc__) value = "0.99997" - param_check = commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') + param_check = open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q0.15') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q0.15").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP16_Q15_0.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP16_Q15_0.py index f833efa..11e237b 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP16_Q15_0.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP16_Q15_0.py @@ -51,6 +51,7 @@ Test cases : - FP16_Q15.0 parameter max value out of bounds = 32767.1 - FP16_Q15.0 parameter in nominal case = 2222 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -96,7 +97,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -130,7 +131,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("PFW : Error when setting parameter %s : %s" % (self.param_name, err)) assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -155,13 +156,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("FP16_Q15.0 parameter min value out of bounds = -32768.1") value = "-32768.1" - param_check = commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') + param_check = open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("Error when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -195,7 +196,7 @@ class TestCases(PfwTestCase): assert err == None, log.F("when setting parameter %s : %s" % (self.param_name, err)) assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -220,11 +221,11 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("FP16_Q15.0 parameter max value out of bounds = 32767.1") value = "32767.1" - param_check = commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') + param_check = open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q15.0') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q15.0").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP16_Q7_8.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP16_Q7_8.py index 7229a6b..2fb44d3 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP16_Q7_8.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP16_Q7_8.py @@ -51,6 +51,7 @@ Test cases : - FP16_Q7.8 parameter max value out of bounds = 127.997 - FP16_Q7.8 parameter in nominal case = 23.59 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -98,7 +99,7 @@ class TestCases(PfwTestCase): assert round(float(out),2) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -133,7 +134,7 @@ class TestCases(PfwTestCase): assert round(float(out), 3) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -158,14 +159,14 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("FP16_Q7.8 parameter min value out of bounds = -128.001") value = "-128.001" - param_check = commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') + param_check = open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -200,7 +201,7 @@ class TestCases(PfwTestCase): assert round(float(out), 3) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -225,11 +226,11 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("FP16_Q7.8 parameter max value out of bounds = 127.997") value = "127.997" - param_check = commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') + param_check = open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP16_Q7.8') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP16_Q7.8").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP32_Q0_31.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q0_31.py index 9267ff2..133d481 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP32_Q0_31.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q0_31.py @@ -51,6 +51,7 @@ Test cases : - FP16_Q0.31 parameter max value out of bounds = 1 - FP16_Q0.31 parameter in nominal case = 0.5000000000 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -97,7 +98,7 @@ class TestCases(PfwTestCase): assert round(float(out),10) == round(float(value),10), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -132,7 +133,7 @@ class TestCases(PfwTestCase): assert round(float(out),10) == round(float(value),10), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -157,14 +158,14 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("FP32_Q0.31 parameter min value out of bounds = -1.000000001") value = "-1.0000000001" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -199,7 +200,7 @@ class TestCases(PfwTestCase): assert round(float(out),10) == round(float(value),10), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -224,13 +225,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("FP32_Q0.31 parameter max value out of bounds = 1") value = "1" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q0.31') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q0.31").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP32_Q15_16.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q15_16.py index d83ace9..013855a 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP32_Q15_16.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q15_16.py @@ -51,6 +51,7 @@ Test cases : - FP32_Q15.16 parameter max value out of bounds = 32767.999985 - FP32_Q15.16 parameter in nominal case = 12345.12345 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -97,7 +98,7 @@ class TestCases(PfwTestCase): assert round(float(out),4) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") @@ -133,7 +134,7 @@ class TestCases(PfwTestCase): assert round(float(out),5) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -158,15 +159,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("FP32_Q15.16 parameter min value out of bounds = -32768.000001") value = "-32768.00001" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -201,7 +202,7 @@ class TestCases(PfwTestCase): assert round(float(out),5) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -226,13 +227,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("FP32_Q15.16 parameter max value out of bounds = 32767.999985") value = "32767.999985" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q15.16') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q15.16").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP32_Q31_0.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q31_0.py index f91dcca..4497d52 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP32_Q31_0.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q31_0.py @@ -51,6 +51,7 @@ Test cases : - FP32_Q31.0 parameter max value out of bounds = 12147483648 - FP32_Q31.0 parameter in nominal case = 2222 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -100,7 +101,7 @@ class TestCases(PfwTestCase): assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -138,7 +139,7 @@ class TestCases(PfwTestCase): assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -163,15 +164,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("FP32_Q31.0 parameter min value out of bounds = -4147483649") value = "-4147483649" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -209,7 +210,7 @@ class TestCases(PfwTestCase): assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -234,13 +235,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("FP32_Q31.0 parameter max value out of bounds = 12147483648") value = "12147483648" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q31.0') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q31.0").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP32_Q8_20.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q8_20.py index 567acce..126a6a2 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP32_Q8_20.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP32_Q8_20.py @@ -51,6 +51,7 @@ Test cases : - FP32_Q8.20 parameter max value out of bounds = 3200.8888 - FP32_Q8.20 parameter in nominal case = -128.123456 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -100,7 +101,7 @@ class TestCases(PfwTestCase): assert round(float(out),6) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -137,7 +138,7 @@ class TestCases(PfwTestCase): assert round(float(out),6) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -162,15 +163,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("FP32_Q8.20 parameter min value out of bounds = -500") value = "-500" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -208,7 +209,7 @@ class TestCases(PfwTestCase): assert round(float(out),6) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -233,12 +234,12 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("FP32_Q8.20 parameter max value out of bounds = 3200.8888") value = "3200.8888" - param_check = commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') + param_check = open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP32_Q8.20') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP32_Q8.20").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP8_Q0_7.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP8_Q0_7.py index 876cb7f..dc1d733 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP8_Q0_7.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP8_Q0_7.py @@ -51,6 +51,7 @@ Test cases : - FP8_Q0.7 parameter max value out of bounds = 0.992189 - FP8_Q0.7 parameter in nominal case = 0.50 """ +import os import commands import unittest from Util.PfwUnitTestLib import PfwTestCase @@ -102,7 +103,7 @@ class TestCases(PfwTestCase): assert round(float(out), 2) == float(value), log.F("BLACKBOARD - Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') == hex_value, log.F("FILESYSTEM - parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] == hex_value, log.F("FILESYSTEM - parameter update error") log.I("test OK") def test_TypeMin(self): @@ -140,7 +141,7 @@ class TestCases(PfwTestCase): assert round(float(out), 6) == float(value), log.F("BLACKBOARD - Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') == hex_value, log.F("FILESYSTEM - parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] == hex_value, log.F("FILESYSTEM - parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -164,16 +165,16 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMin_Overflow.__doc__) value = "-1.000001" - param_check = commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') + param_check = open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') == param_check, log.F("FILESYSTEM - Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] == param_check, log.F("FILESYSTEM - Forbiden parameter change") log.I("test OK") @unittest.expectedFailure @@ -211,7 +212,7 @@ class TestCases(PfwTestCase): % (self.param_name, err)) assert round(float(out), 6) == float(value), "ERROR : BLACKBOARD - Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') == hex_value, "ERROR : FILESYSTEM - parameter update error" + assert open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] == hex_value, "ERROR : FILESYSTEM - parameter update error" log.I("test OK") def test_TypeMax_Overflow(self): @@ -235,14 +236,14 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMax_Overflow.__doc__) value = "0.992189" - param_check = commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') + param_check = open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q0.7') == param_check, log.F("FILESYSTEM - Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q0.7").read()[:-1] == param_check, log.F("FILESYSTEM - Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP8_Q3_4.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP8_Q3_4.py index 83269ef..825d3d2 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP8_Q3_4.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP8_Q3_4.py @@ -51,6 +51,7 @@ Test cases : - FP8_Q0.7 parameter max value out of bounds = 7.9376 - FP8_Q0.7 parameter in nominal case = 4.3 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -101,7 +102,7 @@ class TestCases(PfwTestCase): assert round(float(out), 1) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -139,7 +140,7 @@ class TestCases(PfwTestCase): assert round(float(out), 4) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" log.I("test OK") def test_TypeMin_Overflow(self): @@ -164,15 +165,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) value = "-8.0001" log.I("Setting %s to value %s" % (self.type_name, value)) - param_check = commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') + param_check = open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -210,7 +211,7 @@ class TestCases(PfwTestCase): assert round(float(out), 4) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -234,14 +235,14 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMax_Overflow.__doc__) value = "7.9376" - param_check = commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') + param_check = open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q3.4') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q3.4").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tFP8_Q7_0.py b/test/functional-tests-legacy/PfwTestCase/Types/tFP8_Q7_0.py index 029af64..4918aa7 100755 --- a/test/functional-tests/PfwTestCase/Types/tFP8_Q7_0.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tFP8_Q7_0.py @@ -51,6 +51,7 @@ Test cases : - FP8_Q7.0 parameter max value out of bounds = 127.1 - FP8_Q7.0 parameter in nominal case = 64 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -101,7 +102,7 @@ class TestCases(PfwTestCase): assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -139,7 +140,7 @@ class TestCases(PfwTestCase): assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -163,16 +164,16 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMin_Overflow.__doc__) value = "-128.1" - param_check = commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') + param_check = open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -210,7 +211,7 @@ class TestCases(PfwTestCase): assert float(out) == float(value), log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -234,14 +235,14 @@ class TestCases(PfwTestCase): """ log.D(self.test_TypeMax_Overflow.__doc__) value = "127.1" - param_check = commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') + param_check = open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] log.I("Setting %s to value %s" % (self.type_name, value)) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/FP8_Q7.0') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/FP8_Q7.0").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tINT16.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT16.py index f927cda..774bc56 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT16.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT16.py @@ -50,6 +50,7 @@ Test cases : - INT16 parameter max value out of bounds = 1001 - INT16 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -99,7 +100,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -137,7 +138,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -162,15 +163,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("INT16 parameter min value out of bounds = -1001") value = "-1001" - param_check = commands.getoutput('cat $PFW_RESULT/INT16') + param_check = open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -208,7 +209,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -233,13 +234,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("INT16 parameter max value out of bounds = 1001") value = "1001" - param_check = commands.getoutput('cat $PFW_RESULT/INT16') + param_check = open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT16").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tINT16_ARRAY.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT16_ARRAY.py index 50a19bc..34fa1cc 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT16_ARRAY.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT16_ARRAY.py @@ -51,6 +51,7 @@ Test cases : - Testing maximum overflow - Testing array index out of bounds """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -64,7 +65,7 @@ class TestCases(PfwTestCase): def setUp(self): self.param_name = "/Test/Test/TEST_DIR/INT16_ARRAY" - self.param_short_name = "$PFW_RESULT/INT16_ARRAY" + self.param_short_name = os.environ["PFW_RESULT"] + "/INT16_ARRAY" print '\r' self.pfw.sendCmd("setTuningMode", "on") print '\r' @@ -114,8 +115,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -155,8 +155,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -188,17 +187,16 @@ class TestCases(PfwTestCase): % (self.param_name, str(index), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index), out)) - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check = commands.getoutput(files_system_check) + param_check = open(self.param_short_name).read().splitlines()[index] #Check final parameter value setting indexed_array_value = indexed_array_value - 1 - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=False) assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) assert out != "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == param_check, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) @@ -238,8 +236,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -271,17 +268,16 @@ class TestCases(PfwTestCase): % (self.param_name, str(index), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index), out)) - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check = commands.getoutput(files_system_check) + param_check = open(self.param_short_name).read().splitlines()[index] #Check final parameter value setting indexed_array_value = indexed_array_value + 1 - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=False) assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) assert out != "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == param_check, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) @@ -310,7 +306,7 @@ class TestCases(PfwTestCase): indexed_array_value = self.array_max indexed_array_value_path = "".join([self.param_name, "/", str(index)]) #Check parameter value setting - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=None) if index in [0, self.array_size-1]: assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) diff --git a/test/functional-tests/PfwTestCase/Types/tINT16_Max.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT16_Max.py index 968f3d2..62d2db1 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT16_Max.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT16_Max.py @@ -50,6 +50,7 @@ Test cases : - INT16_Max parameter max value out of bounds = 32768 - INT16_Max parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -99,7 +100,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -137,7 +138,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -162,15 +163,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("INT16_Max parameter min value out of bounds = -32769") value = "-32769" - param_check = commands.getoutput('cat $PFW_RESULT/INT16_Max') + param_check = open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -208,7 +209,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -233,13 +234,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("INT16_Max parameter max value out of bounds = 32768") value = "32768" - param_check = commands.getoutput('cat $PFW_RESULT/INT16_Max') + param_check = open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT16_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT16_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tINT32.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT32.py index 579e4f8..fc82b03 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT32.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT32.py @@ -50,6 +50,7 @@ Test cases : - INT32 parameter max value out of bounds = 1001 - INT32 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -95,7 +96,7 @@ class TestCases(PfwTestCase): assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out == value, "BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" print "INFO : test OK" def test_TypeMin(self): @@ -129,7 +130,7 @@ class TestCases(PfwTestCase): assert err == None, "PFW : Error when setting parameter %s : %s" % (self.param_name, err) assert out == value, "BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" print "INFO : test OK" def test_TypeMin_Overflow(self): @@ -154,13 +155,13 @@ class TestCases(PfwTestCase): print self.test_TypeMin_Overflow.__doc__ print "INFO : INT32 parameter min value out of bounds = -1001" value = "-1001" - param_check = commands.getoutput('cat $PFW_RESULT/INT32') + param_check = open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out != "Done", "PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32') == param_check, "FILESYSTEM : Forbiden parameter change" + assert open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] == param_check, "FILESYSTEM : Forbiden parameter change" print "INFO : test OK" def test_TypeMax(self): @@ -194,7 +195,7 @@ class TestCases(PfwTestCase): assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out == value, "BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" print "INFO : test OK" def test_TypeMax_Overflow(self): @@ -219,11 +220,11 @@ class TestCases(PfwTestCase): print self.test_TypeMax_Overflow.__doc__ print "INFO : INT32 parameter max value out of bounds = 1001" value = "1001" - param_check = commands.getoutput('cat $PFW_RESULT/INT32') + param_check = open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out != "Done", "PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32') == param_check, "FILESYSTEM : Forbiden parameter change" + assert open(os.environ["PFW_RESULT"] + "/INT32").read()[:-1] == param_check, "FILESYSTEM : Forbiden parameter change" print "INFO : test OK" diff --git a/test/functional-tests/PfwTestCase/Types/tINT32_Max.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT32_Max.py index 147e7d4..15e5dde 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT32_Max.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT32_Max.py @@ -50,6 +50,7 @@ Test cases : - INT32_Max parameter max value out of bounds = 2147483648 - INT32_Max parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -99,7 +100,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -136,7 +137,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -161,15 +162,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("INT32_Max parameter min value out of bounds = -2147483649") value = "-2147483649" - param_check = commands.getoutput('cat $PFW_RESULT/INT32_Max') + param_check = open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -207,7 +208,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -232,13 +233,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("INT32_Max parameter max value out of bounds = 2147483648") value = "2147483648" - param_check = commands.getoutput('cat $PFW_RESULT/INT32_Max') + param_check = open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT32_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT32_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tINT8.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT8.py index 55612c5..f82a524 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT8.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT8.py @@ -50,6 +50,7 @@ Test cases : - INT8 parameter max value out of bounds = 101 - INT8 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -99,7 +100,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -137,7 +138,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -162,15 +163,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("INT8 parameter min value out of bounds = -101") value = "-101" - param_check = commands.getoutput('cat $PFW_RESULT/INT8') + param_check = open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -208,7 +209,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -233,13 +234,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("INT8 parameter max value out of bounds = 101") value = "101" - param_check = commands.getoutput('cat $PFW_RESULT/INT8') + param_check = open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/INT8").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tINT8_Max.py b/test/functional-tests-legacy/PfwTestCase/Types/tINT8_Max.py index 2c42d96..9eff0bb 100644 --- a/test/functional-tests/PfwTestCase/Types/tINT8_Max.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tINT8_Max.py @@ -50,6 +50,7 @@ Test cases : - INT8_Max parameter max value out of bounds = 128 - INT8_Max parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -95,7 +96,7 @@ class TestCases(PfwTestCase): assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out == value, "BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8_Max') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" print "INFO : test OK" def test_TypeMin(self): @@ -129,7 +130,7 @@ class TestCases(PfwTestCase): assert err == None, "PFW : Error when setting parameter %s : %s" % (self.param_name, err) assert out == value, "BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8_Max') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" print "INFO : test OK" def test_TypeMin_Overflow(self): @@ -154,13 +155,13 @@ class TestCases(PfwTestCase): print self.test_TypeMin_Overflow.__doc__ print "INFO : INT8_Max parameter min value out of bounds = -129" value = "-129" - param_check = commands.getoutput('cat $PFW_RESULT/INT8_Max') + param_check = open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out != "Done", "PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8_Max') == param_check, "FILESYSTEM : Forbiden parameter change" + assert open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] == param_check, "FILESYSTEM : Forbiden parameter change" print "INFO : test OK" def test_TypeMax(self): @@ -194,7 +195,7 @@ class TestCases(PfwTestCase): assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out == value, "BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8_Max') == hex_value, "FILESYSTEM : parameter update error" + assert open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] == hex_value, "FILESYSTEM : parameter update error" print "INFO : test OK" def test_TypeMax_Overflow(self): @@ -219,11 +220,11 @@ class TestCases(PfwTestCase): print self.test_TypeMax_Overflow.__doc__ print "INFO : INT8_Max parameter max value out of bounds = 128" value = "128" - param_check = commands.getoutput('cat $PFW_RESULT/INT8_Max') + param_check = open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, "Error when setting parameter %s : %s" % (self.param_name, err) assert out != "Done", "PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/INT8_Max') == param_check, "FILESYSTEM : Forbiden parameter change" + assert open(os.environ["PFW_RESULT"] + "/INT8_Max").read()[:-1] == param_check, "FILESYSTEM : Forbiden parameter change" print "INFO : test OK" diff --git a/test/functional-tests/PfwTestCase/Types/tParameter_Block.py b/test/functional-tests-legacy/PfwTestCase/Types/tParameter_Block.py index dcbe098..76317b4 100644 --- a/test/functional-tests/PfwTestCase/Types/tParameter_Block.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tParameter_Block.py @@ -50,6 +50,7 @@ Test cases : - Testing error : Out of range TestCase - Testing error : Try to set an undefined param """ +import os import commands import unittest from Util.PfwUnitTestLib import PfwTestCase @@ -65,14 +66,14 @@ class TestCases(PfwTestCase): self.filesystem_name = [] #UINT8_0, size = 8 - self.param_name.append(self.block_name+"/UINT8") - self.filesystem_name.append("$PFW_RESULT/BLOCK_UINT8") + self.param_name.append(self.block_name+"/BLOCK_UINT8") + self.filesystem_name.append(os.environ["PFW_RESULT"] + "/BLOCK_UINT8") #UINT16_1, size = 16 - self.param_name.append(self.block_name+"/UINT16") - self.filesystem_name.append("$PFW_RESULT/BLOCK_UINT16") + self.param_name.append(self.block_name+"/BLOCK_UINT16") + self.filesystem_name.append(os.environ["PFW_RESULT"] + "/BLOCK_UINT16") #UINT32_2, size = 32 - self.param_name.append(self.block_name+"/UINT32") - self.filesystem_name.append("$PFW_RESULT/BLOCK_UINT32") + self.param_name.append(self.block_name+"/BLOCK_UINT32") + self.filesystem_name.append(os.environ["PFW_RESULT"] + "/BLOCK_UINT32") self.pfw.sendCmd("setTuningMode", "on") @@ -123,7 +124,7 @@ class TestCases(PfwTestCase): assert out == value_param[index_param], log.F("getParameter %s - Expected : %s Found : %s" %(self.param_name[index_param],value_param[index_param], out)) log.I("Check filesystem value") - assert (commands.getoutput("cat %s" % (self.filesystem_name[index_param])) + assert (open(self.filesystem_name[index_param]).read()[:-1] == filesystem_value[index_param]), log.F("FILESYSTEM : parameter update error for %s after setting %s " %(self.block_name, self.param_name[index_param])) @@ -158,26 +159,25 @@ class TestCases(PfwTestCase): for index_param in range(len(self.param_name)): out,err = self.pfw.sendCmd("getParameter",self.param_name[index_param]) init_value_param.append(out) - init_filesystem_value.append(commands.getoutput("cat %s" - %(self.filesystem_name[index_param]))) + init_filesystem_value.append(open(self.filesystem_name[index_param]).read()[:-1]) log.I("Try to set parameter %s to %s, failed expected" %(self.block_name,value)) - out,err = self.pfw.sendCmd("setParameter",self.block_name, value) + out,err = self.pfw.sendCmd("setParameter",self.block_name, value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.block_name, value, err)) assert out != "Done", log.F("Error not detected when setting directly the block %s" % (self.block_name)) log.I("Try to get parameter %s to %s, failed expected" %(self.block_name,value)) - out,err = self.pfw.sendCmd("getParameter",self.block_name, value) + out,err = self.pfw.sendCmd("getParameter",self.block_name, value, expectSuccess=False) assert err == None, log.E("getParameter %s : %s" % (self.block_name, err)) assert out != value, log.F("Error not detected when getting directly the block %s" % (self.block_name)) log.I("Check filesystem value") for index_param in range(len(self.param_name)): - assert (commands.getoutput("cat %s"%(self.filesystem_name[index_param])) + assert (open(self.filesystem_name[index_param]).read()[:-1] == init_filesystem_value[index_param]), log.F("FILESYSTEM : parameter update error for %s" %(self.block_name)) @@ -220,12 +220,11 @@ class TestCases(PfwTestCase): for index_param in range(len(self.param_name)): out,err = self.pfw.sendCmd("getParameter",self.param_name[index_param]) init_value_param.append(out) - init_filesystem_value.append(commands.getoutput("cat %s" - %(self.filesystem_name[index_param]))) + init_filesystem_value.append(open(self.filesystem_name[index_param]).read()[:-1]) log.I("set parameter %s to %s, failed expected" %(self.param_name[1],param_value)) - out,err = self.pfw.sendCmd("setParameter",self.param_name[1],param_value) + out,err = self.pfw.sendCmd("setParameter",self.param_name[1],param_value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (self.param_name[1],param_value, err)) assert out != "Done", log.F("Error not detected when setting parameter %s to out of bound value %s" @@ -236,7 +235,7 @@ class TestCases(PfwTestCase): assert out == init_value_param[index_param], log.F("BLACKBOARD: Forbidden change value for %s - Expected : %s Found : %s" %(self.param_name[index_param],init_value_param[index_param],out)) log.I("Check filesystem value") - assert (commands.getoutput("cat %s"%(self.filesystem_name[index_param])) + assert (open(self.filesystem_name[index_param]).read()[:-1] == init_filesystem_value[index_param]), log.F("FILESYSTEM : parameter update error for %s" %(self.block_name)) @@ -271,12 +270,11 @@ class TestCases(PfwTestCase): for index_param in range(len(self.param_name)) : out,err = self.pfw.sendCmd("getParameter",self.param_name[index_param]) init_value_param.append(out) - init_filesystem_value.append(commands.getoutput("cat %s" - %(self.filesystem_name[index_param]))) + init_filesystem_value.append(open(self.filesystem_name[index_param]).read()[:-1]) log.I("set parameter %s to %s, failed expected" %(param_undefined_name,param_value)) - out,err = self.pfw.sendCmd("setParameter",param_undefined_name,param_value) + out,err = self.pfw.sendCmd("setParameter",param_undefined_name,param_value, expectSuccess=False) assert err == None, log.E("setParameter %s %s : %s" % (param_undefined_name,param_value, err)) assert out != "Done", log.F("Error not detected when setting parameter %s to out of bound value %s" @@ -287,6 +285,6 @@ class TestCases(PfwTestCase): assert out == init_value_param[index_param], log.F("BLACKBOARD: Forbidden change value for %s - Expected : %s Found : %s" %(self.param_name[index_param],init_value_param[index_param],out)) log.I("Check filesystem value") - assert (commands.getoutput("cat %s"%(self.filesystem_name[index_param])) + assert (open(self.filesystem_name[index_param]).read()[:-1] == init_filesystem_value[index_param]), log.F("FILESYSTEM : parameter update error for %s" %(self.block_name)) diff --git a/test/functional-tests/PfwTestCase/Types/tRAW.py b/test/functional-tests-legacy/PfwTestCase/Types/tRAW.py index dc3a037..eb7dc5b 100644 --- a/test/functional-tests/PfwTestCase/Types/tRAW.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tRAW.py @@ -66,6 +66,7 @@ Test cases : - UINT16 parameter max value out of bounds = 0x03E9 : - Writing Raw """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -75,9 +76,9 @@ log=ACTLogging.Logger() class TestCases(PfwTestCase): def setUp(self): self.param_name = "/Test/Test/TEST_DIR/UINT16_Max" - self.filesystem_name="$PFW_RESULT/UINT16_Max" + self.filesystem_name=os.environ["PFW_RESULT"] + "/UINT16_Max" self.param_name_2 = "/Test/Test/TEST_DIR/UINT16" - self.filesystem_name_2="$PFW_RESULT/UINT16" + self.filesystem_name_2=os.environ["PFW_RESULT"] + "/UINT16" self.pfw.sendCmd("setTuningMode", "on") def tearDown(self): @@ -226,7 +227,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" % (self.param_name)) def test_04_WReal_RHex_Nominal_Case(self): @@ -276,7 +277,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) def test_05_WRaw_RDec_Nominal_Case(self): @@ -325,7 +326,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) @@ -377,7 +378,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) def test_07_WReal_RHex_TypeMin_Case(self): @@ -429,7 +430,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) def test_08_WRaw_RDec_TypeMin_Case(self): @@ -481,7 +482,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) @@ -531,7 +532,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) def test_10_WReal_RHex_TypeMax_Case(self): @@ -583,7 +584,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) def test_11_WRaw_RDec_TypeMax_Case(self): @@ -635,7 +636,7 @@ class TestCases(PfwTestCase): assert out == blackboard_value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, blackboard_value, out)) #Check parameter value on filesystem - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, log.F("FILESYSTEM : parameter update error for %s" %(self.param_name)) @@ -662,7 +663,7 @@ class TestCases(PfwTestCase): """ log.D(self.test_12_WRaw_UINT16_Max_OutOfBound.__doc__) value = "0x10000" - filesystem_value = commands.getoutput("cat %s"%(self.filesystem_name)) + filesystem_value = open(self.filesystem_name).read()[:-1] value_space = "raw" outputraw_format = "hex" @@ -672,13 +673,13 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setValueSpace", value_space) self.pfw.sendCmd("setOutputRawFormat", outputraw_format) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s -> %s" % (self.param_name, err)) assert out != "Done", log.F("Error not detected when setting parameter %s out of bound" % (self.param_name)) #Check parameter value on blackboard - assert commands.getoutput("cat %s"%(self.filesystem_name)) == filesystem_value, "FILESYSTEM : Forbiden parameter change" + assert open(self.filesystem_name).read()[:-1] == filesystem_value, "FILESYSTEM : Forbiden parameter change" def test_13_WRaw_UINT16_OutOfBound(self): @@ -704,7 +705,7 @@ class TestCases(PfwTestCase): """ log.D(self.test_13_WRaw_UINT16_OutOfBound.__doc__) value = "0x03E9" - filesystem_value = commands.getoutput("cat %s"%(self.filesystem_name_2)) + filesystem_value = open(self.filesystem_name_2).read()[:-1] value_space = "raw" outputraw_format = "hex" @@ -714,10 +715,10 @@ class TestCases(PfwTestCase): self.pfw.sendCmd("setValueSpace", value_space) self.pfw.sendCmd("setOutputRawFormat", outputraw_format) #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name_2, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name_2, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s -> %s" % (self.param_name_2, err)) assert out != "Done", log.F("Error not detected when setting parameter %s out of bound" % (self.param_name_2)) #Check parameter value on blackboard - assert commands.getoutput("cat %s"%(self.filesystem_name_2)) == filesystem_value, "FILESYSTEM : Forbiden parameter change" + assert open(self.filesystem_name_2).read()[:-1] == filesystem_value, "FILESYSTEM : Forbiden parameter change" diff --git a/test/functional-tests/PfwTestCase/Types/tSTRING_128.py b/test/functional-tests-legacy/PfwTestCase/Types/tSTRING_128.py index 26c5bc0..78f829f 100644 --- a/test/functional-tests/PfwTestCase/Types/tSTRING_128.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tSTRING_128.py @@ -28,6 +28,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import os import commands, string, random from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -91,7 +92,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("when getting parameter %s -> %s" % (self.param_name, err)) assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == value, log.F("FILESYSTEM : parameter update error") def test_Empty_String_Case(self): """ @@ -110,7 +111,7 @@ class TestCases(PfwTestCase): """ log.D(self.test_Empty_String_Case.__doc__) log.I("STR_CHAR128 parameter empty string = \'\'") - value = "\"\"" + value = "" #Set parameter value out, err = self.pfw.sendCmd("setParameter", self.param_name, value) assert err == None, log.E("when setting parameter %s -> %s" % (self.param_name, err)) @@ -120,7 +121,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("when getting parameter %s -> %s" % (self.param_name, err)) assert out == "", log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == "", log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == "", log.F("FILESYSTEM : parameter update error") def test_OverSize_String_Case(self): """ @@ -142,13 +143,13 @@ class TestCases(PfwTestCase): value="" for i in range(self.size_max+1): value=value+str(random.choice(string.letters)) - param_check = commands.getoutput('cat $PFW_RESULT/STR_CHAR128') + param_check = open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s -> %s" % (self.param_name, err)) assert out != "Done", log.F("Error not detected when setting parameter %s over size" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") def test_Full_Letters_String_Case(self): """ @@ -179,7 +180,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name, err)) assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == value, log.F("FILESYSTEM : parameter update error") def test_Nominal_String_Case(self): """ @@ -208,7 +209,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s -> %s" % (self.param_name, err)) assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == value, log.F("FILESYSTEM : parameter update error") def test_Punctuation_Empty_Parenthese_String_Case(self): """ @@ -227,9 +228,9 @@ class TestCases(PfwTestCase): log.D(self.test_Punctuation_Empty_Parenthese_String_Case.__doc__) value = "ParentheseTest()" log.I("STR_CHAR128 parameter Parenthese Char = %s" % (value)) - param_check = commands.getoutput('cat $PFW_RESULT/STR_CHAR128') + param_check = open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, "'%s'" % (value)) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value) assert err == None, log.E("When setting parameter %s : %s" % (self.param_name, err)) assert out == "Done", log.F("Expected : Done, found : %s" % (out)) #Get parameter value @@ -237,7 +238,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When getting parameter %s : %s" % (self.param_name, err)) assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == value, log.F("FILESYSTEM : parameter update error") def test_Punctuation_Full_Parenthese_String_Case(self): """ @@ -256,9 +257,9 @@ class TestCases(PfwTestCase): log.D(self.test_Punctuation_Full_Parenthese_String_Case.__doc__) value = "ParentheseTest(test)" log.I("STR_CHAR128 parameter Parenthese Char = %s" % (value)) - param_check = commands.getoutput('cat $PFW_RESULT/STR_CHAR128') + param_check = open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, "'%s'" % value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value) assert err == None, log.E("When setting parameter %s : %s" % (self.param_name, err)) assert out == "Done", log.F("Expected : Done, found : %s" % (out)) #Get parameter value @@ -266,7 +267,7 @@ class TestCases(PfwTestCase): assert err == None, log.E("When getting parameter %s : %s" % (self.param_name, err)) assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == value, log.F("FILESYSTEM : parameter update error") def test_SpaceChar_String_Case(self): """ @@ -295,4 +296,4 @@ class TestCases(PfwTestCase): assert err == None, log.E("When setting parameter %s : %s" % (self.param_name, err)) assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value_check, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/STR_CHAR128') == value_check, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/STR_CHAR128").read()[:-1] == value_check, log.F("FILESYSTEM : parameter update error") diff --git a/test/functional-tests/PfwTestCase/Types/tUINT16.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT16.py index 5237a3d..f7fc72e 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT16.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT16.py @@ -53,6 +53,7 @@ Test cases : - UINT16 parameter max value out of bounds = 1001 - UINT16 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -103,7 +104,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -141,7 +142,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -166,15 +167,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("UINT16 parameter min value out of bounds = -1") value = "-1" - param_check = commands.getoutput('cat $PFW_RESULT/UINT16') + param_check = open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -212,7 +213,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -237,13 +238,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("UINT16 parameter max value out of bounds = 1001") value = "1001" - param_check = commands.getoutput('cat $PFW_RESULT/UINT16') + param_check = open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT16").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tUINT16_Max.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT16_Max.py index cf9939c..805017e 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT16_Max.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT16_Max.py @@ -52,6 +52,7 @@ Test cases : - UINT16_Max parameter max value out of bounds = 65536 - UINT16_Max parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -102,7 +103,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -140,7 +141,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -165,15 +166,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("UINT16_Max parameter min value out of bounds = -1") value = "-1" - param_check = commands.getoutput('cat $PFW_RESULT/UINT16_Max') + param_check = open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -211,7 +212,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -236,13 +237,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("UINT16_Max parameter max value out of bounds = 65536") value = "65536" - param_check = commands.getoutput('cat $PFW_RESULT/UINT16_Max') + param_check = open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT16_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT16_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tUINT32.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT32.py index f31361a..e33296b 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT32.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT32.py @@ -52,6 +52,7 @@ Test cases : - UINT32 parameter max value out of bounds = 1001 - UINT32 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -102,7 +103,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -140,7 +141,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -165,15 +166,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("UINT32 parameter min value out of bounds = -1") value = "-1" - param_check = commands.getoutput('cat $PFW_RESULT/UINT32') + param_check = open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -211,7 +212,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -236,13 +237,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("UINT32 parameter max value out of bounds = 1001") value = "1001" - param_check = commands.getoutput('cat $PFW_RESULT/UINT32') + param_check = open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT32").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tUINT32_ARRAY.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT32_ARRAY.py index a20d404..c277a06 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT32_ARRAY.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT32_ARRAY.py @@ -53,6 +53,7 @@ Test cases : - Testing array index out of bounds - Testing value format error """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -65,7 +66,7 @@ class TestCases(PfwTestCase): def setUp(self): self.param_name = "/Test/Test/TEST_DIR/UINT32_ARRAY" - self.param_short_name = "$PFW_RESULT/UINT32_ARRAY" + self.param_short_name = os.environ["PFW_RESULT"] + "/UINT32_ARRAY" print '\r' self.pfw.sendCmd("setTuningMode", "on") print '\r' @@ -115,8 +116,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -156,8 +156,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -189,17 +188,16 @@ class TestCases(PfwTestCase): % (self.param_name, str(index), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index), out)) - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check = commands.getoutput(files_system_check) + param_check = open(self.param_short_name).read().splitlines()[index] #Check final parameter value setting indexed_array_value = indexed_array_value - 1 - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=False) assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) assert out != "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == param_check, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) @@ -239,8 +237,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -272,17 +269,16 @@ class TestCases(PfwTestCase): % (self.param_name, str(index), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index), out)) - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check = commands.getoutput(files_system_check) + param_check = open(self.param_short_name).read().splitlines()[index] #Check final parameter value setting indexed_array_value = indexed_array_value + 1 - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=False) assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) assert out != "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == param_check, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) @@ -311,7 +307,7 @@ class TestCases(PfwTestCase): indexed_array_value = self.array_max indexed_array_value_path = "".join([self.param_name, "/", str(index)]) #Check parameter value setting - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=None) if index in [0, self.array_size-1]: assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) diff --git a/test/functional-tests/PfwTestCase/Types/tUINT32_Max.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT32_Max.py index 2e99495..9966ac3 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT32_Max.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT32_Max.py @@ -52,6 +52,7 @@ Test cases : - UINT16 parameter max value out of bounds = 4294967296 - UINT16 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -102,7 +103,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -140,7 +141,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -165,15 +166,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("UINT32_Max parameter min value out of bounds = -1") value = "-1" - param_check = commands.getoutput('cat $PFW_RESULT/UINT32_Max') + param_check = open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -211,7 +212,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -236,13 +237,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("UINT32_Max parameter max value out of bounds = 4294967296") value = "4294967296" - param_check = commands.getoutput('cat $PFW_RESULT/UINT32_Max') + param_check = open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT32_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT32_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tUINT8.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT8.py index b41712b..8a6c815 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT8.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT8.py @@ -52,6 +52,7 @@ Test cases : - UINT8 parameter max value out of bounds = 101 - UINT8 parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -101,7 +102,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -139,7 +140,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -164,15 +165,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("UINT8 parameter min value out of bounds = -1") value = "-1" - param_check = commands.getoutput('cat $PFW_RESULT/UINT8') + param_check = open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -210,7 +211,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -235,13 +236,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("UINT8 parameter max value out of bounds = 101") value = "101" - param_check = commands.getoutput('cat $PFW_RESULT/UINT8') + param_check = open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT8").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/Types/tUINT8_ARRAY.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT8_ARRAY.py index 89be43c..88c2e58 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT8_ARRAY.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT8_ARRAY.py @@ -53,6 +53,7 @@ Test cases : - Testing array index out of bounds - Testing value format error """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -65,7 +66,7 @@ class TestCases(PfwTestCase): def setUp(self): self.param_name = "/Test/Test/TEST_DIR/UINT8_ARRAY" - self.param_short_name = "$PFW_RESULT/UINT8_ARRAY" + self.param_short_name = os.environ["PFW_RESULT"] + "/UINT8_ARRAY" print '\r' self.pfw.sendCmd("setTuningMode", "on") print '\r' @@ -115,8 +116,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -156,8 +156,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -189,17 +188,16 @@ class TestCases(PfwTestCase): % (self.param_name, str(index), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index), out)) - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check = commands.getoutput(files_system_check) + param_check= open(self.param_short_name).read().splitlines()[index] #Check final parameter value setting indexed_array_value = indexed_array_value - 1 - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=False) assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) assert out != "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == param_check, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) @@ -239,8 +237,7 @@ class TestCases(PfwTestCase): assert out == str(indexed_array_value), log.F("BLACKBOARD : Incorrect value for %s[%s], expected: %s, found: %s" % (self.param_name, str(index), str(indexed_array_value), out)) #Check parameter value on filesystem - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == hex_indexed_array_value, log.F("FILESSYSTEM : %s[%s] update error" % (self.param_name, str(index))) @@ -272,17 +269,16 @@ class TestCases(PfwTestCase): % (self.param_name, str(index), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index), out)) - files_system_check = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check = commands.getoutput(files_system_check) + param_check= open(self.param_short_name).read().splitlines()[index] #Check final parameter value setting indexed_array_value = indexed_array_value + 1 - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=False) assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) assert out != "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value = commands.getoutput(files_system_check) + indexed_files_system_array_value = open(self.param_short_name).read().splitlines()[index] assert indexed_files_system_array_value == param_check, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) @@ -311,7 +307,7 @@ class TestCases(PfwTestCase): indexed_array_value = self.array_max indexed_array_value_path = "".join([self.param_name, "/", str(index)]) #Check parameter value setting - out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value)) + out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path), str(indexed_array_value), expectSuccess=None) if index in [0, self.array_size-1]: assert err == None, log.E("when setting parameter %s[%s]: %s" % (self.param_name, str(index), err)) @@ -359,10 +355,8 @@ class TestCases(PfwTestCase): % (self.param_name, str(index+1), err)) assert out == "Done", log.F("when setting parameter %s[%s]: %s" % (self.param_name, str(index+1), out)) - files_system_check_1 = "awk -v ligne="+str(index)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check_1 = commands.getoutput(files_system_check_1) - files_system_check_2 = "awk -v ligne="+str(index+1)+" 'NR == ligne+1 { print $0}' "+self.param_short_name - param_check_2 = commands.getoutput(files_system_check_2) + param_check_1 = open(self.param_short_name).read().splitlines()[index] + param_check_2 = open(self.param_short_name).read().splitlines()[index + 1] #Check final parameter value setting (!= or == ?) out, err = self.pfw.sendCmd("setParameter", str(indexed_array_value_path_1), str(var_uint16)) assert err == None, log.E("Error when setting parameter %s[%s]: %s" @@ -371,6 +365,6 @@ class TestCases(PfwTestCase): assert out == "Done", log.F("Error not detected when setting parameter %s[%s] out of bounds" % (self.param_name, str(index))) #Check parameter value on filesystem - indexed_files_system_array_value_2 = commands.getoutput(files_system_check_2) + indexed_files_system_array_value_2 = open(self.param_short_name).read().splitlines()[index + 1] assert indexed_files_system_array_value_2 == param_check_2, log.F("FILESSYSTEM : %s[%s] forbiden update" % (self.param_name, str(index))) diff --git a/test/functional-tests/PfwTestCase/Types/tUINT8_Max.py b/test/functional-tests-legacy/PfwTestCase/Types/tUINT8_Max.py index 4e40867..71bfdab 100644 --- a/test/functional-tests/PfwTestCase/Types/tUINT8_Max.py +++ b/test/functional-tests-legacy/PfwTestCase/Types/tUINT8_Max.py @@ -52,6 +52,7 @@ Test cases : - UINT8_Max parameter max value out of bounds = 256 - UINT8_Max parameter in nominal case = 50 """ +import os import commands from Util.PfwUnitTestLib import PfwTestCase from Util import ACTLogging @@ -102,7 +103,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin(self): @@ -140,7 +141,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMin_Overflow(self): @@ -165,15 +166,15 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMin_Overflow.__doc__) log.I("UINT8_Max parameter min value out of bounds = -1") value = "-1" - param_check = commands.getoutput('cat $PFW_RESULT/UINT8_Max') + param_check = open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") def test_TypeMax(self): @@ -211,7 +212,7 @@ class TestCases(PfwTestCase): assert out == value, log.F("BLACKBOARD : Incorrect value for %s, expected: %s, found: %s" % (self.param_name, value, out)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8_Max') == hex_value, log.F("FILESYSTEM : parameter update error") + assert open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] == hex_value, log.F("FILESYSTEM : parameter update error") log.I("test OK") def test_TypeMax_Overflow(self): @@ -236,13 +237,13 @@ class TestCases(PfwTestCase): log.D(self.test_TypeMax_Overflow.__doc__) log.I("UINT8_Max parameter max value out of bounds = 256") value = "256" - param_check = commands.getoutput('cat $PFW_RESULT/UINT8_Max') + param_check = open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] #Set parameter value - out, err = self.pfw.sendCmd("setParameter", self.param_name, value) + out, err = self.pfw.sendCmd("setParameter", self.param_name, value, expectSuccess=False) assert err == None, log.E("when setting parameter %s : %s" % (self.param_name, err)) assert out != "Done", log.F("PFW : Error not detected when setting parameter %s out of bounds" % (self.param_name)) #Check parameter value on filesystem - assert commands.getoutput('cat $PFW_RESULT/UINT8_Max') == param_check, log.F("FILESYSTEM : Forbiden parameter change") + assert open(os.environ["PFW_RESULT"] + "/UINT8_Max").read()[:-1] == param_check, log.F("FILESYSTEM : Forbiden parameter change") log.I("test OK") diff --git a/test/functional-tests/PfwTestCase/__init__.py b/test/functional-tests-legacy/PfwTestCase/__init__.py index e69de29..e69de29 100644 --- a/test/functional-tests/PfwTestCase/__init__.py +++ b/test/functional-tests-legacy/PfwTestCase/__init__.py diff --git a/test/functional-tests/README.md b/test/functional-tests-legacy/README.md index 43f5c59..43f5c59 100644 --- a/test/functional-tests/README.md +++ b/test/functional-tests-legacy/README.md diff --git a/test/functional-tests/Util/ACTLogging.py b/test/functional-tests-legacy/Util/ACTLogging.py index fdc71ef..fdc71ef 100644 --- a/test/functional-tests/Util/ACTLogging.py +++ b/test/functional-tests-legacy/Util/ACTLogging.py diff --git a/test/functional-tests-legacy/Util/PfwUnitTestLib.py b/test/functional-tests-legacy/Util/PfwUnitTestLib.py new file mode 100644 index 0000000..78b1f76 --- /dev/null +++ b/test/functional-tests-legacy/Util/PfwUnitTestLib.py @@ -0,0 +1,155 @@ +# -*-coding:utf-8 -* + +# Copyright (c) 2011-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. + +import os +import subprocess +import unittest +import time +import socket + +class RemoteCli(object): + + def setRemoteProcess(self, remoteProcess): + self.remoteProcess = remoteProcess + + def sendCmd(self, cmd, *args, **kwargs): + """ Execute a remote-process command and assert its result. + @param[in] cmd, *args the command to execute and its arguments + @param[in] expectSuccess If True, assert that the command will succeed + If False, assert that the command will succeed + If None, do not assert result + Default to True + @return (command stdout, None) None is return for legacy reason + """ + expectSuccess=kwargs.get("expectSuccess", True) + + assert self.remoteProcess.poll() == None, "Can not send command to Test platform as it has died. Return code: %s" % self.remoteProcess.returncode + + sys_cmd = self.platform_command + [cmd] + if args is not None: + sys_cmd += args + print "CMD : %s" % sys_cmd + + try: + p = subprocess.Popen(sys_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except Exception as (errno, strerror): + return None, strerror + out, err = p.communicate() + out = out.rstrip('\r\n') + + if (expectSuccess != None): + assert (p.returncode == 0) == expectSuccess, "Unexpected command result:\nexpectedSuccess=%s\nCMD=%s\nreturncode=%s\nstdout=%s\nstderr=%s" % (expectSuccess, sys_cmd, p.returncode, out, err) + + return out, None + +class Pfw(RemoteCli): + platform_command = ["remote-process", "localhost", "5000"] + +class Hal(RemoteCli): + # Arbitrary choosen port, try to avoid conflicting with IANA registered ports + testPlatformPort = 18444 + platform_command = ["remote-process", "localhost", str(testPlatformPort)] + + def __init__(self, pfw): + self.pfw = pfw + + # Starts the HAL exe + def startHal(self): + cmd= ["test-platform", os.environ["PFW_TEST_CONFIGURATION"], str(self.testPlatformPort)] + self.setRemoteProcess(subprocess.Popen(cmd)) + # Wait for the test-platform listening socket + while socket.socket().connect_ex(("localhost", self.testPlatformPort)) != 0: + assert self.remoteProcess.poll() == None, "Test platform has failed to start. Return code: %s" % self.remoteProcess.returncode + time.sleep(0.01) + + # Send command "stop" to the HAL + def stopHal(self): + try: + self.sendCmd("exit") + except Exception as exitEx: + # Kill test-platform as cooperative exit failed + try: + self.remoteProcess.terminate() + except Exception as killEx: + raise Exception("Fail to terminate after a exit request failed", exitEx, killEx) + raise + else: + # exit request accepted, wait for server to stop + returncode = self.remoteProcess.wait() + assert returncode == 0, "test-platform did not stop succesfully: %s" % returncode + + def createInclusiveCriterion(self, name, nb): + self.sendCmd("createInclusiveSelectionCriterion", name, nb) + + def createExclusiveCriterion(self, name, nb): + self.sendCmd("createExclusiveSelectionCriterion", name, nb) + + # Starts the Pfw + def start(self): + self.sendCmd("setSchemaUri", os.environ["PFW_SCHEMAS"]) + self.sendCmd("setValidateSchemasOnStart", "true") + self.sendCmd("start") + self.pfw.setRemoteProcess(self.remoteProcess) + +# A PfwTestCase gather tests performed on one instance of the PFW. +class PfwTestCase(unittest.TestCase): + + pfw = Pfw() + hal = Hal(pfw) + + @classmethod + def setUpClass(cls): + cls.startHal() + + @classmethod + def tearDownClass(cls): + cls.stopHal() + + @classmethod + def startHal(cls): + # set up the Hal & pfw + cls.hal.startHal() + try: + # create criterions + cls.hal.createInclusiveCriterion("Crit_0", "2") + cls.hal.createExclusiveCriterion("Crit_1", "2") + # start the Pfw + cls.hal.start() + except Exception as startE: + # Leave the hal stopped in case of start failure + try: + cls.stopHal() + except Exception as stopE: + raise Exception("Fail to stop after a failed start: ", startE, stopE) + raise + + @classmethod + def stopHal(cls): + cls.hal.stopHal() diff --git a/test/functional-tests/Util/__init__.py b/test/functional-tests-legacy/Util/__init__.py index e69de29..e69de29 100644 --- a/test/functional-tests/Util/__init__.py +++ b/test/functional-tests-legacy/Util/__init__.py diff --git a/test/functional-tests/xml/XML_Test/Reference_Compliant.xml b/test/functional-tests-legacy/xml/XML_Test/Reference_Compliant.xml index 48b1720..29bd3c5 100644 --- a/test/functional-tests/xml/XML_Test/Reference_Compliant.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Reference_Compliant.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/home/lab/ICS/hardware/intel/PRIVATE/parameter-framework/test/configuration/Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -21,6 +22,8 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> + <!-- The 'Component' tag has been renamed to 'ParameterBlock', but retro-compatibility is needed. + So keeping 'Component' to test it. --> <Component Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> diff --git a/test/functional-tests/xml/XML_Test/Reference_Criteria.xml b/test/functional-tests-legacy/xml/XML_Test/Reference_Criteria.xml index 76664e2..a2bd7cf 100644 --- a/test/functional-tests/xml/XML_Test/Reference_Criteria.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Reference_Criteria.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -21,7 +21,7 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <!-- Tested FixedPoints --> @@ -55,12 +55,12 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">1</BooleanParameter> <!-- Tested FixedPoints --> @@ -94,7 +94,7 @@ <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_0</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> @@ -121,20 +121,20 @@ <Settings> <Configuration Name="Conf_2_1"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_0"> - <Component Name="TEST_DOMAIN_0"> + <ParameterBlock Name="TEST_DOMAIN_0"> <IntegerParameter Name="Param_00">4</IntegerParameter> <IntegerParameter Name="Param_01">4</IntegerParameter> <IntegerParameter Name="Param_02">4</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_2_0"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_0"> - <Component Name="TEST_DOMAIN_0"> + <ParameterBlock Name="TEST_DOMAIN_0"> <IntegerParameter Name="Param_00">5</IntegerParameter> <IntegerParameter Name="Param_01">5</IntegerParameter> <IntegerParameter Name="Param_02">5</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> @@ -161,20 +161,20 @@ <Settings> <Configuration Name="Conf_3_1"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_1"> - <Component Name="TEST_DOMAIN_1"> + <ParameterBlock Name="TEST_DOMAIN_1"> <IntegerParameter Name="Param_10">4</IntegerParameter> <IntegerParameter Name="Param_11">4</IntegerParameter> <IntegerParameter Name="Param_12">4</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_3_0"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_1"> - <Component Name="TEST_DOMAIN_1"> + <ParameterBlock Name="TEST_DOMAIN_1"> <IntegerParameter Name="Param_10">5</IntegerParameter> <IntegerParameter Name="Param_11">5</IntegerParameter> <IntegerParameter Name="Param_12">5</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/XML_Test/Reference_Split_Domain.xml b/test/functional-tests-legacy/xml/XML_Test/Reference_Split_Domain.xml index 7f7edbc..e6dfa55 100644 --- a/test/functional-tests/xml/XML_Test/Reference_Split_Domain.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Reference_Split_Domain.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!--DOMAIN 1 DEFINITION--> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -25,8 +26,8 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_MAIN"> - <Component Name="TEST_MAIN"> - <Component Name="TEST_DIR_0"> + <ParameterBlock Name="TEST_MAIN"> + <ParameterBlock Name="TEST_DIR_0"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <!-- Tested FixedPoints --> @@ -60,24 +61,24 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> - <Component Name="TEST_DIR_1"> + </ParameterBlock> + <ParameterBlock Name="TEST_DIR_1"> <IntegerParameter Name="Param_00">4</IntegerParameter> <IntegerParameter Name="Param_01">4</IntegerParameter> <IntegerParameter Name="Param_02">4</IntegerParameter> - </Component> - <Component Name="TEST_DIR_2"> + </ParameterBlock> + <ParameterBlock Name="TEST_DIR_2"> <IntegerParameter Name="Param_10">4</IntegerParameter> <IntegerParameter Name="Param_11">4</IntegerParameter> <IntegerParameter Name="Param_12">4</IntegerParameter> - </Component> - </Component> + </ParameterBlock> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_MAIN"> - <Component Name="TEST_MAIN"> - <Component Name="TEST_DIR_0"> + <ParameterBlock Name="TEST_MAIN"> + <ParameterBlock Name="TEST_DIR_0"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <!-- Tested FixedPoints --> @@ -111,18 +112,18 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> - <Component Name="TEST_DIR_1"> + </ParameterBlock> + <ParameterBlock Name="TEST_DIR_1"> <IntegerParameter Name="Param_00">5</IntegerParameter> <IntegerParameter Name="Param_01">5</IntegerParameter> <IntegerParameter Name="Param_02">5</IntegerParameter> - </Component> - <Component Name="TEST_DIR_2"> + </ParameterBlock> + <ParameterBlock Name="TEST_DIR_2"> <IntegerParameter Name="Param_10">5</IntegerParameter> <IntegerParameter Name="Param_11">5</IntegerParameter> <IntegerParameter Name="Param_12">5</IntegerParameter> - </Component> - </Component> + </ParameterBlock> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/XML_Test/Reference_dumpDomains b/test/functional-tests-legacy/xml/XML_Test/Reference_dumpDomains index 9277d20..9277d20 100644 --- a/test/functional-tests/xml/XML_Test/Reference_dumpDomains +++ b/test/functional-tests-legacy/xml/XML_Test/Reference_dumpDomains diff --git a/test/functional-tests/xml/XML_Test/Reference_dumpDomains.xml b/test/functional-tests-legacy/xml/XML_Test/Reference_dumpDomains.xml index 844099e..b80cc61 100644 --- a/test/functional-tests/xml/XML_Test/Reference_dumpDomains.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Reference_dumpDomains.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/home/lab/ICS/hardware/intel/PRIVATE/parameter-framework/test/configuration/Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_0_1"> <Configurations> @@ -11,11 +12,11 @@ <Settings> <Configuration Name="Conf_0_0"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_0"> - <Component Name="TEST_DOMAIN_0"> + <ParameterBlock Name="TEST_DOMAIN_0"> <IntegerParameter Name="Param_00">0</IntegerParameter> <IntegerParameter Name="Param_01">0</IntegerParameter> <IntegerParameter Name="Param_02">0</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> @@ -41,20 +42,20 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_1"> - <Component Name="TEST_DOMAIN_1"> + <ParameterBlock Name="TEST_DOMAIN_1"> <IntegerParameter Name="Param_10">4</IntegerParameter> <IntegerParameter Name="Param_11">4</IntegerParameter> <IntegerParameter Name="Param_12">4</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_1"> - <Component Name="TEST_DOMAIN_1"> + <ParameterBlock Name="TEST_DOMAIN_1"> <IntegerParameter Name="Param_10">5</IntegerParameter> <IntegerParameter Name="Param_11">5</IntegerParameter> <IntegerParameter Name="Param_12">5</IntegerParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/XML_Test/Uncompliant_OutboundParameter.xml b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_OutboundParameter.xml index 339a75c..f7fd329 100644 --- a/test/functional-tests/xml/XML_Test/Uncompliant_OutboundParameter.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_OutboundParameter.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -21,7 +22,7 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">2</BooleanParameter> <!-- Tested FixedPoints --> @@ -55,12 +56,12 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">1</BooleanParameter> <!-- Tested FixedPoints --> @@ -94,7 +95,7 @@ <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_0</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/XML_Test/Uncompliant_UndeclaredConfigurableElement.xml b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_UndeclaredConfigurableElement.xml index f8c00be..98be4c5 100644 --- a/test/functional-tests/xml/XML_Test/Uncompliant_UndeclaredConfigurableElement.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_UndeclaredConfigurableElement.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -21,7 +22,7 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/ERROR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <!-- Tested FixedPoints --> @@ -55,12 +56,12 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">1</BooleanParameter> <!-- Tested FixedPoints --> @@ -94,7 +95,7 @@ <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_0</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/XML_Test/Uncompliant_UndeclaredParameter.xml b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_UndeclaredParameter.xml index f831de5..01d4507 100644 --- a/test/functional-tests/xml/XML_Test/Uncompliant_UndeclaredParameter.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_UndeclaredParameter.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -21,7 +22,7 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <BooleanParameter Name="UNDECLARED">0</BooleanParameter> @@ -56,12 +57,12 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">1</BooleanParameter> <BooleanParameter Name="UNDECLARED">0</BooleanParameter> @@ -96,7 +97,7 @@ <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_0</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/XML_Test/Uncompliant_UnorderConfigurableElement.xml b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_UnorderConfigurableElement.xml index 3d9aaa4..39af533 100644 --- a/test/functional-tests/xml/XML_Test/Uncompliant_UnorderConfigurableElement.xml +++ b/test/functional-tests-legacy/xml/XML_Test/Uncompliant_UnorderConfigurableElement.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains SystemClassName="Test"> <ConfigurableDomain Name="Domain_1"> <Configurations> <Configuration Name="Conf_1_0"> @@ -21,7 +21,7 @@ <Settings> <Configuration Name="Conf_1_1"> <ConfigurableElement Path="/Test/Test/TEST_DOMAIN_0"> - <Component Name="TEST_DOMAIN_0"> + <ParameterBlock Name="TEST_DOMAIN_0"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <!-- Tested FixedPoints --> @@ -55,12 +55,12 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_1</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1_0"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">1</BooleanParameter> <!-- Tested FixedPoints --> @@ -94,7 +94,7 @@ <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1_0</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/configuration/ParameterFrameworkConfiguration.xml b/test/functional-tests-legacy/xml/configuration/ParameterFrameworkConfiguration.xml index 85e9a0a..d050376 100644 --- a/test/functional-tests/xml/configuration/ParameterFrameworkConfiguration.xml +++ b/test/functional-tests-legacy/xml/configuration/ParameterFrameworkConfiguration.xml @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<ParameterFrameworkConfiguration SystemClassName="Test" ServerPort="5000" TuningAllowed="true"> +<ParameterFrameworkConfiguration + SystemClassName="Test" ServerPort="5000" TuningAllowed="true"> <SubsystemPlugins> <Location Folder=""> - <Plugin Name="libtest-subsystem.so"/> + <Plugin Name="test-subsystem"/> </Location> </SubsystemPlugins> <StructureDescriptionFileLocation Path="Structure/Test/TestClass.xml"/> diff --git a/test/functional-tests/xml/TestConfigurableDomains.xml b/test/functional-tests-legacy/xml/configuration/Settings/Test/TestConfigurableDomains.xml index fdc77e1..c53e027 100644 --- a/test/functional-tests/xml/TestConfigurableDomains.xml +++ b/test/functional-tests-legacy/xml/configuration/Settings/Test/TestConfigurableDomains.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/home/lab/ICS/hardware/intel/PRIVATE/parameter-framework/test/configuration/Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> +<ConfigurableDomains + SystemClassName="Test"> <ConfigurableDomain Name="Domain_0"> <Configurations> <Configuration Name="Conf_0"> @@ -24,7 +25,7 @@ <Settings> <Configuration Name="Conf_0"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">0</BooleanParameter> <!-- Tested FixedPoints --> @@ -58,10 +59,10 @@ <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_0</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> <ConfigurableElement Path="/Test/Test/TEST_TYPES"> - <Component Name="TEST_TYPES"> + <ParameterBlock Name="TEST_TYPES"> <EnumParameter Name="ENUM">ENUM_NOMINAL</EnumParameter> <BitParameterBlock Name="BLOCK_8BIT"> <BitParameter Name="BIT_0_3">0</BitParameter> @@ -71,16 +72,16 @@ <BitParameter Name="BIT_7_1">0</BitParameter> </BitParameterBlock> <ParameterBlock Name="BLOCK_PARAMETER"> - <IntegerParameter Name="UINT8">0</IntegerParameter> - <IntegerParameter Name="UINT16">0</IntegerParameter> - <IntegerParameter Name="UINT32">0</IntegerParameter> + <IntegerParameter Name="BLOCK_UINT8">0</IntegerParameter> + <IntegerParameter Name="BLOCK_UINT16">0</IntegerParameter> + <IntegerParameter Name="BLOCK_UINT32">0</IntegerParameter> </ParameterBlock> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> <Configuration Name="Conf_1"> <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> + <ParameterBlock Name="TEST_DIR"> <!-- Tested Booleans --> <BooleanParameter Name="BOOL">1</BooleanParameter> <!-- Tested FixedPoints --> @@ -114,10 +115,10 @@ <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> <!-- Tested String--> <StringParameter Name="STR_CHAR128">string_Conf_1</StringParameter> - </Component> + </ParameterBlock> </ConfigurableElement> <ConfigurableElement Path="/Test/Test/TEST_TYPES"> - <Component Name="TEST_TYPES"> + <ParameterBlock Name="TEST_TYPES"> <!--Tested Enum--> <EnumParameter Name="ENUM">ENUM_MIN</EnumParameter> <!--Tested Bit parameter block--> @@ -129,11 +130,11 @@ <BitParameter Name="BIT_7_1">0</BitParameter> </BitParameterBlock> <ParameterBlock Name="BLOCK_PARAMETER"> - <IntegerParameter Name="UINT8">0</IntegerParameter> - <IntegerParameter Name="UINT16">0</IntegerParameter> - <IntegerParameter Name="UINT32">0</IntegerParameter> + <IntegerParameter Name="BLOCK_UINT8">0</IntegerParameter> + <IntegerParameter Name="BLOCK_UINT16">0</IntegerParameter> + <IntegerParameter Name="BLOCK_UINT32">0</IntegerParameter> </ParameterBlock> - </Component> + </ParameterBlock> </ConfigurableElement> </Configuration> </Settings> diff --git a/test/functional-tests/xml/configuration/Structure/Test/TestClass.xml b/test/functional-tests-legacy/xml/configuration/Structure/Test/TestClass.xml index 480aa05..f2bd54c 100644 --- a/test/functional-tests/xml/configuration/Structure/Test/TestClass.xml +++ b/test/functional-tests-legacy/xml/configuration/Structure/Test/TestClass.xml @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<SystemClass Name="Test"> +<SystemClass + Name="Test"> <SubsystemInclude Path="TestSubsystem.xml"/> </SystemClass> diff --git a/test/functional-tests/xml/configuration/Structure/Test/TestSubsystem.xml.in b/test/functional-tests-legacy/xml/configuration/Structure/Test/TestSubsystem.xml.in index 1987ec4..e7a8155 100644 --- a/test/functional-tests/xml/configuration/Structure/Test/TestSubsystem.xml.in +++ b/test/functional-tests-legacy/xml/configuration/Structure/Test/TestSubsystem.xml.in @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/home/lab/ICS/hardware/intel/PRIVATE/parameter-framework/test/configuration/Schemas/Subsystem.xsd" Name="Test" Type="TEST" Endianness="Little"> +<Subsystem + Name="Test" Type="TEST"> <ComponentLibrary> <ComponentType Name="TEST_DIR"> <!-- Tested Booleans --> @@ -63,9 +64,9 @@ <BitParameter Name="BIT_7_1" Size="1" Pos="7"/> </BitParameterBlock> <ParameterBlock Name="BLOCK_PARAMETER"> - <IntegerParameter Name="UINT8" Size="8" Signed="false" Mapping="Binary:BLOCK_UINT8"/> - <IntegerParameter Name="UINT16" Size="16" Signed="false" Mapping="Binary:BLOCK_UINT16"/> - <IntegerParameter Name="UINT32" Size="32" Signed="false" Mapping="Binary:BLOCK_UINT32"/> + <IntegerParameter Name="BLOCK_UINT8" Size="8" Signed="false" Mapping="Binary:BLOCK_UINT8"/> + <IntegerParameter Name="BLOCK_UINT16" Size="16" Signed="false" Mapping="Binary:BLOCK_UINT16"/> + <IntegerParameter Name="BLOCK_UINT32" Size="32" Signed="false" Mapping="Binary:BLOCK_UINT32"/> </ParameterBlock> </ComponentType> <ComponentType Name="TEST_MAIN"> diff --git a/test/functional-tests/AutoSync.cpp b/test/functional-tests/AutoSync.cpp new file mode 100644 index 0000000..9353b8d --- /dev/null +++ b/test/functional-tests/AutoSync.cpp @@ -0,0 +1,133 @@ +/* + * 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 "Config.hpp" +#include "ParameterFramework.hpp" +#include <SubsystemObject.h> +#include <IntrospectionEntryPoint.h> +#include "Test.hpp" +#include <catch.hpp> +#include <string> + +using std::string; + +namespace parameterFramework +{ + +struct BoolPF : public ParameterFramework +{ + BoolPF() : ParameterFramework{createConfig()} {} + + /** Set the boolean parameter value within the "Conf" configuration, + * which is always applicable. */ + void setParameterValue(bool value) + { + std::string valueStr = value ? "1" : "0"; + setConfigurationParameter("Domain", "Conf", "/test/test/param", valueStr); + } + +private: + static Config createConfig() + { + Config config; + config.instances = R"(<BooleanParameter Name="param" Mapping="Object"/>)"; + config.plugins = {{"", {"introspection-subsystem"}}}; + config.subsystemType = "INTROSPECTION"; + + config.domains = R"(<ConfigurableDomain Name="Domain"> + <Configurations> + <Configuration Name="Conf"> + <CompoundRule Type="All"/> + </Configuration> + </Configurations> + + <ConfigurableElements> + <ConfigurableElement Path="/test/test/param"/> + </ConfigurableElements> + + <Settings> + <Configuration Name="Conf"> + <ConfigurableElement Path="/test/test/param"> + <BooleanParameter Name="param">0</BooleanParameter> + </ConfigurableElement> + </Configuration> + </Settings> + </ConfigurableDomain>)"; + + return config; + } +}; + +SCENARIO_METHOD(BoolPF, "Auto sync") +{ + GIVEN ("A Pfw that starts") { + REQUIRE_NOTHROW(start()); + + THEN ("Parameter value is false according to the settings") { + REQUIRE_FALSE(introspectionSubsystem::getParameterValue()); + + AND_THEN ("Tuning is off") { + REQUIRE_FALSE(isTuningModeOn()); + + WHEN ("Turning autosync on") { + REQUIRE_NOTHROW(setAutoSync(true)); + + AND_WHEN ("A parameter is set") { + REQUIRE_NOTHROW(setParameterValue(true)); + + THEN ("Sync is done") { + CHECK(introspectionSubsystem::getParameterValue()); + } + } + } + WHEN ("Turning autosync off") { + REQUIRE_NOTHROW(setAutoSync(false)); + + AND_WHEN ("A parameter is set") { + REQUIRE_NOTHROW(setParameterValue(true)); + + THEN ("Sync should not have occurred yet") { + REQUIRE_FALSE(introspectionSubsystem::getParameterValue()); + + WHEN ("Turning autosync on") { + REQUIRE_NOTHROW(setAutoSync(true)); + + THEN ("Sync is done") { + CHECK(introspectionSubsystem::getParameterValue()); + } + } + } + } + } + } + } + } +} +} diff --git a/test/functional-tests/Basic.cpp b/test/functional-tests/Basic.cpp new file mode 100644 index 0000000..60e6bbc --- /dev/null +++ b/test/functional-tests/Basic.cpp @@ -0,0 +1,181 @@ +/* + * 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 "Test.hpp" +#include "Config.hpp" +#include "StoreLogger.hpp" +#include "ParameterFramework.hpp" + +#include <catch.hpp> + +#include <list> +#include <string> + +#include <cstdio> + +namespace parameterFramework +{ + +SCENARIO_METHOD(ParameterFramework, "Default logger", "[log]") +{ + WHEN ("No logger is set") { + THEN ("Start should succeed") { + CHECK_NOTHROW(start()); + } + } +} + +SCENARIO_METHOD(ParameterFramework, "No Logger", "[log]") +{ + WHEN ("A nullptr logger is set") { + setLogger(nullptr); + THEN ("Start should succeed") { + CHECK_NOTHROW(start()); + } + } +} + +SCENARIO("Logger should receive info and warnings", "[log]") +{ + GIVEN ("A logger that stores logs") { + /* Instantiating logger first to ensure that its lifetime is longer than the pfw's one, + * because the pfw references the logger. */ + StoreLogger logger{}; + GIVEN ("A parameter framework") { + WarningPF pfw; + GIVEN ("Config files that emit warnings") { + WHEN ("The record logger is set") { + pfw.setLogger(&logger); + THEN ("Start should succeed") { + REQUIRE_NOTHROW(pfw.start()); + AND_THEN ("The logger should have stored info and warning log") { + using Logs = StoreLogger::Logs; + using Level = StoreLogger::Log::Level; + CHECK(logger.filter(Level::warning) != Logs{}); + CHECK(logger.getLogs() != Logs{}); + } + } + AND_WHEN ("A nullptr logger is set") { + pfw.setLogger(nullptr); + THEN ("Start should succeed") { + REQUIRE_NOTHROW(pfw.start()); + AND_THEN ("The record logger should NOT have stored any info or " + "warning log") { + CHECK(logger.getLogs() == StoreLogger::Logs{}); + } + } + } + } + } + } + } +} + +SCENARIO_METHOD(LazyPF, "Tuning OK", "[properties][remote interface]") +{ +} + +SCENARIO_METHOD(LazyPF, "Invalid XML configuration") +{ + for (auto &xmlT : Tests<std::string>{{"an unknown tag", "<unknown_tag/>"}, + {"an unclosed tag", "<unclosed>"}}) { + auto invalidXml = xmlT.payload; + GIVEN ("An invalid xml: containing " + xmlT.title) { + Config::Plugins ps{}; + for (auto &&configT : Tests<Config>{ + {"top config", {&Config::plugins, Config::Plugins{{"", {invalidXml}}}}}, + {"structure", {&Config::instances, invalidXml}}, + {"settings", {&Config::domains, invalidXml}}}) { + WHEN ("Used in the " + configT.title) { + create(std::move(configT.payload)); + THEN ("Start should fail") { + CHECK_THROWS_AS(mPf->start(), Exception); + } + } + } + } + } +} + +SCENARIO_METHOD(LazyPF, "Plugin OK", "[properties][missing plugin policy]") +{ + for (auto &pluginNameT : + Tests<std::string>{{"an non existing plugin", "libdonetexist.so"}, + {"an existing library but invalid (linux) PF plugin", "libc.so.6"}}) { + GIVEN ("An" + pluginNameT.title) { + create({&Config::plugins, Config::Plugins{{"", {pluginNameT.payload}}}}); + WHEN ("The missing subsystem policy is left to default") { + THEN ("Start should fail") { + CHECK_THROWS_AS(mPf->start(), Exception); + } + } + WHEN ("The missing subsystem policy is set to failure") { + mPf->setFailureOnMissingSubsystem(true); + THEN ("Start should fail") { + CHECK_THROWS_AS(mPf->start(), Exception); + } + } + WHEN ("The missing subsystem policy is set to ignore") { + mPf->setFailureOnMissingSubsystem(false); + THEN ("Start should success") { + CHECK_NOTHROW(mPf->start()); + } + } + } + } +} + +SCENARIO_METHOD(LazyPF, "Invalid domains", "[properties]") +{ + GIVEN ("An invalid domain file") { + create({&Config::domains, "<Domain name='Invalid'/>"}); + THEN ("Start should fail") { + CHECK_THROWS_AS(mPf->start(), Exception); + } + WHEN ("Changing failure setting load policy to ignore") { + mPf->setFailureOnFailedSettingsLoad(false); + THEN ("Start should succeed") { + CHECK_NOTHROW(mPf->start()); + } + } + } +} + +SCENARIO_METHOD(ParameterFramework, "Raw value space") +{ + WHEN ("Raw value space is set") { + setRawValueSpace(true); + THEN ("Value space should be raw") { + CHECK(isValueSpaceRaw() == true); + } + } +} + +} // parameterFramework diff --git a/test/functional-tests/CMakeLists.txt b/test/functional-tests/CMakeLists.txt index f1f8544..1ab0449 100644 --- a/test/functional-tests/CMakeLists.txt +++ b/test/functional-tests/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,35 +26,27 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -if (BUILD_TESTING) - find_program(python2 python2) +if(BUILD_TESTING) - set(PFW_ROOT ${CMAKE_BINARY_DIR}/tmp/test-parameters) - set(PFW_RESULT ${PFW_ROOT}/result) + # TODO: create a libxml2 library to properly export those definition & include + # so that client only have to link with libxml2 + include_directories(include) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/Structure/Test/TestSubsystem.xml.in - ${PFW_ROOT}/xml/configuration/Structure/Test/TestSubsystem.xml @ONLY) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/Structure/Test/TestClass.xml - ${PFW_ROOT}/xml/configuration/Structure/Test/TestClass.xml - COPYONLY) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/ParameterFrameworkConfiguration.xml - ${PFW_ROOT}/xml/configuration/ParameterFrameworkConfiguration.xml - COPYONLY) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/xml/configuration/Settings/Test/TestConfigurableDomains.xml - ${PFW_ROOT}/xml/configuration/Settings/Test/TestConfigurableDomains.xml - COPYONLY) + # Add unit test + add_executable(parameterFunctionalTest + Basic.cpp + FloatingPoint.cpp + Handle.cpp + AutoSync.cpp) - add_test(NAME functional-test - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND ${python2} ACTCampaignEngine.py) + find_package(LibXml2 REQUIRED) + + target_link_libraries(parameterFunctionalTest + PRIVATE parameter catch tmpfile LibXml2::libxml2 introspection-subsystem) + + add_test(NAME parameterFunctionalTest + COMMAND parameterFunctionalTest) # Custom function defined in the top-level CMakeLists - set_test_env(functional-test) - set_property(TEST functional-test APPEND PROPERTY ENVIRONMENT - PFW_ROOT=${PFW_ROOT} - PFW_RESULT=${PFW_RESULT}) + set_test_env(parameterFunctionalTest) endif() diff --git a/test/functional-tests/FloatingPoint.cpp b/test/functional-tests/FloatingPoint.cpp new file mode 100644 index 0000000..fd41797 --- /dev/null +++ b/test/functional-tests/FloatingPoint.cpp @@ -0,0 +1,179 @@ +/* + * 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 "Config.hpp" +#include "ParameterFramework.hpp" +#include "ElementHandle.hpp" +#include "Test.hpp" +#include "BinaryCopy.hpp" + +#include <catch.hpp> + +#include <string> + +using std::string; + +namespace parameterFramework +{ + +const auto validInstances = Config{&Config::instances, + // Size is fixed at 32 and as such is optional */ + R"(<FloatingPointParameter Name="Empty"/> + <FloatingPointParameter Name="trivial" Size="32"/> + <FloatingPointParameter Name="nominal" Size="32" Min="-50.4" Max="12.2"/> + <FloatingPointParameter Name="defaultMin" Size="32" Max="12.2"/> + <FloatingPointParameter Name="defaultMax" Size="32" Min="-50.4"/>)"}; +const auto &invalidParameters = + Tests<string>{{"invalid Size(64)", "<FloatingPointParameter Name='error' Size='64'/>"}, + {"invalid Size(16)", "<FloatingPointParameter Name='error' Size='16'/>"}, + {"minimum > maximum", "<FloatingPointParameter Name='error' Min='1' Max='0'/>"}}; + +struct FloatsPF : public ParameterFramework +{ + FloatsPF() : ParameterFramework{std::move(validInstances)} {} +}; + +SCENARIO_METHOD(LazyPF, "Invalid floating points XML structure", "[floating point]") +{ + for (auto &vec : invalidParameters) { + GIVEN ("intentional error: " + vec.title) { + create(Config{&Config::instances, vec.payload}); + THEN ("Start should fail") { + CHECK_THROWS_AS(mPf->start(), Exception); + } + } + } +} + +SCENARIO_METHOD(FloatsPF, "Floating points", "[floating points]") +{ + GIVEN ("A valid XML structure file") { + THEN ("Start should succeed") { + CHECK_NOTHROW(start()); + REQUIRE_NOTHROW(setTuningMode(true)); + string path = "/test/test/nominal"; + + AND_THEN ("Set/Get a floating point parameter in real value space") { + + for (auto &vec : Tests<string>{ + {"(too high)", "12.3"}, + {"(too low)", "-50.5"}, + {"(not a number)", "foobar"}, + }) { + GIVEN ("Invalid value " + vec.title) { + CHECK_THROWS_AS(setParameter(path, vec.payload), Exception); + } + } + for (auto &vec : Tests<string>{ + {"(upper limit)", "12.2"}, + {"(lower limit)", "-50.4"}, + {"(inside range)", "0"}, + }) { + GIVEN ("A valid value " + vec.title) { + CHECK_NOTHROW(setParameter(path, vec.payload)); + string getValueBack; + REQUIRE_NOTHROW(getParameter(path, getValueBack)); + CHECK(getValueBack == vec.payload); + } + } + } + + AND_THEN ("Set/Get a floating point parameter in raw value space") { + const float tooHigh = 12.3f; + const float tooLow = -50.5f; + const float nan = std::numeric_limits<float>::quiet_NaN(); + const float inf = std::numeric_limits<float>::infinity(); + REQUIRE_NOTHROW(setRawValueSpace(true)); + for (auto &vec : Tests<string>{ + {"(too high, as decimal)", + std::to_string(::utility::binaryCopy<uint32_t>(tooHigh))}, + {"(too low, as decimal)", + std::to_string(::utility::binaryCopy<uint32_t>(tooLow))}, + {"(meaningless)", "foobar"}, + {"(infinity)", std::to_string(::utility::binaryCopy<uint32_t>(inf))}, + {"(NaN)", std::to_string(::utility::binaryCopy<uint32_t>(nan))}, + }) { + GIVEN ("Invalid value " + vec.title) { + CHECK_THROWS_AS(setParameter(path, vec.payload), Exception); + } + } + const float upper = 12.2f; + const float lower = -50.4f; + const float zero = 0.0f; + for (auto &vec : Tests<string>{ + {"(upper limit, as decimal)", + std::to_string(::utility::binaryCopy<uint32_t>(upper))}, + {"(lower limit, as decimal)", + std::to_string(::utility::binaryCopy<uint32_t>(lower))}, + {"(inside range, as decimal)", + std::to_string(::utility::binaryCopy<uint32_t>(zero))}, + }) { + GIVEN ("A valid value " + vec.title) { + CHECK_NOTHROW(setParameter(path, vec.payload)); + string getValueBack; + REQUIRE_NOTHROW(getParameter(path, getValueBack)); + CHECK(getValueBack == vec.payload); + } + } + } + + AND_THEN ("Set/Get floating point parameter handle") { + ElementHandle handle{*this, path}; + /** @FIXME: 'set' operations on a ParameterHandle are silently + * ignored in tuning mode. Does it make sense ? */ + REQUIRE_NOTHROW(setTuningMode(false)); + + /* warning: even though the API below takes a double as + * argument, we need to define the test vector as floats in + * order to prevent rounding issues */ + for (auto &vec : Tests<float>{ + {"(upper limit)", 12.2f}, + {"(lower limit)", -50.4f}, + {"(inside range)", 0.0f}, + }) { + GIVEN ("A valid value " + vec.title) { + CHECK_NOTHROW(handle.setAsDouble(vec.payload)); + double getValueBack; + REQUIRE_NOTHROW(handle.getAsDouble(getValueBack)); + CHECK(getValueBack == vec.payload); + } + } + for (auto &vec : Tests<float>{ + {"(too high)", 12.3f}, {"(too low)", -50.5f}, + }) { + GIVEN ("An invalid value " + vec.title) { + CHECK_THROWS_AS(handle.setAsDouble(vec.payload), Exception); + } + } + } + } + } +} +} diff --git a/test/functional-tests/Handle.cpp b/test/functional-tests/Handle.cpp new file mode 100644 index 0000000..d7aafb9 --- /dev/null +++ b/test/functional-tests/Handle.cpp @@ -0,0 +1,665 @@ +/* + * 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 "Config.hpp" +#include "Test.hpp" +#include "Exception.hpp" +#include "TmpFile.hpp" + +#include "ParameterFramework.hpp" +#include "ElementHandle.hpp" + +#include <catch.hpp> + +#include <libxml/parser.h> +#include <libxml/tree.h> + +#include <string> +#include <list> + +#include <stdlib.h> + +using std::string; +using std::list; +using Bytes = std::vector<uint8_t>; + +namespace parameterFramework +{ + +struct AllParamsPF : public ParameterFramework +{ + AllParamsPF() : ParameterFramework{getConfig()} { REQUIRE_NOTHROW(start()); } + + string getBasicParams() + { + string structure = R"( + <BooleanParameter Name="bool" Description="bool"/> + <BooleanParameter ArrayLength="2" Name="bool_array" Description="bool-array"/> + + <IntegerParameter Signed="false" Min="33" Max="123" Size="16" Name="integer"/> + <IntegerParameter Signed="true" Min="-10" Max="10" Size="32" ArrayLength="4" Name="integer_array"/> + + <FixedPointParameter Size="32" Integral="3" Fractional="4" Name="fix_point"/> + <FixedPointParameter Size="32" Integral="3" Fractional="4" ArrayLength="3" Name="fix_point_array"/> + + <EnumParameter Size="8" Name="enum"> + <ValuePair Literal="min" Numerical="-128"/> + <ValuePair Literal="five" Numerical="5"/> + <ValuePair Literal="max" Numerical="127"/> + </EnumParameter> + <EnumParameter Size="16" ArrayLength="4" Name="enum_array"> + <ValuePair Literal="eight" Numerical="8"/> + <ValuePair Literal="min" Numerical="-32767"/> + </EnumParameter>)"; + + // String and bit parameter arrays are not supported + structure += R"( + <StringParameter MaxLength="63" Name="string"/> + + <BitParameterBlock Size="64" Name="bit_block"> + <BitParameter Pos="1" Size="1" Max="1" Name="one"/> + <BitParameter Pos="2" Size="2" Max="2" Name="two"/> + <BitParameter Pos="6" Size="6" Max="10" Name="six"/> + <BitParameter Pos="16" Size="16" Max="99" Name="sixteen"/> + <BitParameter Pos="32" Size="32" Max="4294967295" Name="thirty_two"/> + </BitParameterBlock> + )"; + return structure; + } + + Config getConfig() + { + Config config; + config.components = nodeDesc("ComponentType", "component_type", getBasicParams()); + config.instances = + getBasicParams() + nodeDesc("ParameterBlock", "parameter_block", getBasicParams()) + + nodeDesc("ParameterBlock", "parameter_block_array", getBasicParams(), + "ArrayLength='2'") + + nodeDesc("Component", "component_scalar", "", "Type='component_type'") + + nodeDesc("Component", "component_array", "", "Type='component_type' ArrayLength='2'"); + return config; + } + + void checkStructure(const string &path, const string &expected) + { + CHECK_NOTHROW(checkXMLEq(ElementHandle{*this, path}.getStructureAsXML(), expected)); + } + + /** Use libxml2 to pretty format xml. + * Equivalent of xmllint --format + */ + static string canonicalizeXML(const string &xml) + { + // Parse xml + // Might be better to specialize std::default_delete<xmlDoc>. + std::unique_ptr<xmlDoc, void (*)(xmlDoc *)> doc{ + xmlReadMemory(xml.c_str(), (int)xml.length(), "structure.xml", nullptr, + XML_PARSE_NOBLANKS), + xmlFreeDoc}; + if (doc == nullptr) { + throw Exception{"Failed to parse document: " + xml}; + } + + // Dump it formated + int size; + + // Need to use exception unsafe raw pointer as of libxml2 c api + xmlChar *unsafeFormated; + + // TODO: Should use canonicalization (aka c14n). + // cf: http://xmlsoft.org/html/libxml-c14n.html + // https://en.wikipedia.org/wiki/Canonical_XML + // Additionally to what is listed on that page, + // attributes are also ordered deterministically. + // That would solve the workaround in the node function with pre/post attributes. + // Unfortunately c14n is not available in appveyor (Windows CI) libxml2 prebuild + xmlDocDumpFormatMemoryEnc(doc.get(), &unsafeFormated, &size, "UTF-8", 1); + std::unique_ptr<xmlChar, void (*)(void *)> formated{unsafeFormated, xmlFree}; + + if (formated == nullptr) { + throw Exception{"Could not dump xml: " + xml}; + } + + return string{(char *)formated.get()}; + } + + static void checkEq(const string &result, const string &expected) + { + CHECK(result == expected); + + // Pretty print the word differences with colors + // It does not matter if it fails as the test would still fail + // due to the above CHECK. + if (result != expected) { + utility::TmpFile resultFile(result); + utility::TmpFile expectedFile(expected); + string command = "git --no-pager diff --word-diff-regex='[^ <>]+'" + " --color --no-index --exit-code " + + resultFile.getPath() + ' ' + expectedFile.getPath(); + + // `system` return -1 or 127 on failure, the command error code otherwise + // `git diff` return 1 if the files are the different (thanks to --exit-code) + auto status = system(command.c_str()); +#ifdef WIFEXITED // Posix platform + bool success = WIFEXITED(status) and WEXITSTATUS(status) == 1; +#else + bool success = status == 1; +#endif + if (not success) { + WARN("Warning: Failed to pretty-print the difference between " + "actual and expected results with `git diff'"); + } + } + } + + static void checkXMLEq(const string &result, const string &expected) + { + checkEq(canonicalizeXML(result), canonicalizeXML(expected)); + } + + static string node(string tag, string name, string content, string attributes = "", + string postAttributes = "") + { + return "<" + tag + " " + attributes + " Name='" + name + "' " + postAttributes + ">" + + content + "</" + tag + ">"; + } + /** Node with a description. + * @param[in] maybeDescription If nullptr, description will be generated from the name + * Otherwise, the description. + */ + static string nodeDesc(string tag, string name, string content, string attributes = "", + const char *maybeDescription = nullptr) + { + string description = "description_" + name; + if (maybeDescription != nullptr) { + description = maybeDescription; + } + return node(tag, name, content, attributes, "Description='" + description + "'"); + } + + static string rootNode(string name, string attributes, string content) + { + return '<' + name + ' ' + attributes + '>' + content + "</" + name + '>'; + } +}; + +SCENARIO_METHOD(AllParamsPF, "Export boolean", "[handler][structure][xml]") +{ + string expected = rootNode("BooleanParameter", "Name='bool' Description='bool'", ""); + checkStructure("/test/test/bool", expected); +} + +SCENARIO_METHOD(AllParamsPF, "Export component", "[handler][structure][xml]") +{ + string expected = rootNode("ParameterBlock", "Name='component_scalar' " + "Description='description_component_scalar'", + getBasicParams()); + checkStructure("/test/test/component_scalar", expected); +} + +SCENARIO_METHOD(AllParamsPF, "Export component array", "[handler][structure][xml]") +{ + string expected = rootNode( + "ParameterBlock", "Name='component_array' Description='description_component_array'", + nodeDesc("ParameterBlock", "0", getBasicParams(), "", "description_component_array") + + nodeDesc("ParameterBlock", "1", getBasicParams(), "", "description_component_array")); + checkStructure("/test/test/component_array", expected); +} + +SCENARIO_METHOD(AllParamsPF, "Export all parameters", "[handler][structure][xml]") +{ + string paramExpected = getBasicParams() + + nodeDesc("ParameterBlock", "parameter_block", getBasicParams()) + + nodeDesc("ParameterBlock", "parameter_block_array", + nodeDesc("ParameterBlock", "0", getBasicParams(), "", + // description is inherited from array + "description_parameter_block_array") + + nodeDesc("ParameterBlock", "1", getBasicParams(), "", + "description_parameter_block_array")) + + // Components should be exported as parameterBlock + nodeDesc("ParameterBlock", "component_scalar", getBasicParams()) + + nodeDesc("ParameterBlock", "component_array", + nodeDesc("ParameterBlock", "0", getBasicParams(), "", + // description is inherited from array + "description_component_array") + + nodeDesc("ParameterBlock", "1", getBasicParams(), "", + "description_component_array")); + + WHEN ("Exporting subsystem") { + string expected = rootNode("Subsystem", "Name='test'", paramExpected); + checkStructure("/test/test", expected); + } + + WHEN ("Exporting systemClass") { + string expected = rootNode("SystemClass", "Name='test'", + "<Subsystem Name='test'>" + paramExpected + "</Subsystem>"); + + // Awkwardly, the root and its first child are the same element + checkStructure("/test", expected); + checkStructure("/", expected); + } +} + +struct SettingsTestPF : public AllParamsPF +{ + static string parameterBlockNode(string name, string settings) + { + return node("ParameterBlock", name, settings); + }; + static string mkBasicSettings(string settings, string name) + { + return rootNode("ParameterBlock", "Name='" + name + "'", settings); + } + + static string fullXMLSettings(const string &basicSettings) + { + string settings = basicSettings; + settings += + parameterBlockNode("parameter_block", settings) + + parameterBlockNode("parameter_block_array", parameterBlockNode("0", settings) + + parameterBlockNode("1", settings)) + + parameterBlockNode("component_scalar", settings) + + parameterBlockNode("component_array", parameterBlockNode("0", settings) + + parameterBlockNode("1", settings)); + + return rootNode("SystemClass", "Name='test'", node("Subsystem", "test", settings, "")); + } + + static string fullBytesSettings(const string &basicSettings) + { + string fullSettings; + // We have the "basic params" repeated 7 times across the test + // structure + for (size_t i = 0; i < 7; ++i) { + fullSettings += basicSettings; + } + return fullSettings; + } + + /** Print Bytes as string separated hexadecimal number. */ + static string showBytes(const Bytes &bytes) + { + using namespace std; + ostringstream ss; + ss.exceptions(ostream::badbit | ostream::failbit); + for (auto byte : bytes) { + ss << hex << setw(2) << setfill('0') << int{byte} << ' '; + } + return ss.str(); + } + + static Bytes readBytes(const string &strBytes) + { + using namespace std; + istringstream ss{strBytes}; + ss.exceptions(istream::badbit | istream::failbit); + Bytes bytes(strBytes.size() / 3); + + for (auto &byte : bytes) { + uint16_t notCharByte; + ss >> hex >> setw(2) >> notCharByte; + byte = static_cast<char>(notCharByte); + } + return bytes; + } + + static void checkBytesEq(const Bytes &result, const string &expect) + { + checkEq(showBytes(result), expect); + } + static void checkBytesEq(const Bytes &result, const Bytes &expect) + { + checkEq(showBytes(result), showBytes(expect)); + } +}; + +static const char *defaultBasicSettingsXML = R"( + <BooleanParameter Name="bool">0</BooleanParameter> + <BooleanParameter Name="bool_array">0 0</BooleanParameter> + <IntegerParameter Name="integer">33</IntegerParameter> + <IntegerParameter Name="integer_array">-10 -10 -10 -10</IntegerParameter> + <FixedPointParameter Name="fix_point">0.0000</FixedPointParameter> + <FixedPointParameter Name="fix_point_array">0.0000 0.0000 0.0000</FixedPointParameter> + <EnumParameter Name="enum">min</EnumParameter> + <EnumParameter Name="enum_array">eight eight eight eight</EnumParameter> + <StringParameter Name="string"></StringParameter> + <BitParameterBlock Name="bit_block"> + <BitParameter Name="one">0</BitParameter> + <BitParameter Name="two">0</BitParameter> + <BitParameter Name="six">0</BitParameter> + <BitParameter Name="sixteen">0</BitParameter> + <BitParameter Name="thirty_two">0</BitParameter> + </BitParameterBlock> +)"; + +static const char *testBasicSettingsXML = R"( + <BooleanParameter Name="bool">1</BooleanParameter> + <BooleanParameter Name="bool_array">0 1</BooleanParameter> + <IntegerParameter Name="integer">100</IntegerParameter> + <IntegerParameter Name="integer_array">-10 0 8 10</IntegerParameter> + <FixedPointParameter Name="fix_point">2.2500</FixedPointParameter> + <FixedPointParameter Name="fix_point_array">7.1250 0.6875 -1.0000</FixedPointParameter> + <EnumParameter Name="enum">five</EnumParameter> + <EnumParameter Name="enum_array">eight min eight min</EnumParameter> + <StringParameter Name="string">A string of 32 character.@@@@@@@</StringParameter> + <BitParameterBlock Name="bit_block"> + <BitParameter Name="one">1</BitParameter> + <BitParameter Name="two">2</BitParameter> + <BitParameter Name="six">10</BitParameter> + <BitParameter Name="sixteen">72</BitParameter> + <BitParameter Name="thirty_two">4294967295</BitParameter> + </BitParameterBlock> +)"; +static const char *testRawHexBasicSettingsXML = R"( + <BooleanParameter Name="bool">0x1</BooleanParameter> + <BooleanParameter Name="bool_array">0x0 0x1</BooleanParameter> + <IntegerParameter Name="integer">0x0064</IntegerParameter> + <IntegerParameter Name="integer_array">0xFFFFFFF6 0x00000000 0x00000008 0x0000000A</IntegerParameter> + <FixedPointParameter ValueSpace="Raw" Name="fix_point">0x24000000</FixedPointParameter> + <FixedPointParameter ValueSpace="Raw" Name="fix_point_array">0x72000000 0x0B000000 0xF0000000</FixedPointParameter> + <EnumParameter Name="enum">five</EnumParameter> + <EnumParameter Name="enum_array">eight min eight min</EnumParameter> + <StringParameter Name="string">A string of 32 character.@@@@@@@</StringParameter> + <BitParameterBlock Name="bit_block"> + <BitParameter Name="one">0x1</BitParameter> + <BitParameter Name="two">0x2</BitParameter> + <BitParameter Name="six">0xA</BitParameter> + <BitParameter Name="sixteen">0x48</BitParameter> + <BitParameter Name="thirty_two">0xFFFFFFFF</BitParameter> + </BitParameterBlock> +)"; + +SCENARIO_METHOD(SettingsTestPF, "Export and import XML settings", "[handler][settings][xml]") +{ + WHEN ("Exporting root XML") { + auto getAsXML = [this](string path) { return ElementHandle(*this, path).getAsXML(); }; + CHECK(getAsXML("/") == getAsXML("/test")); + checkXMLEq(getAsXML("/"), fullXMLSettings(defaultBasicSettingsXML)); + } + + ElementHandle basicParams(*this, "/test/test/parameter_block"); + WHEN ("Exporting basic parameter XML") { + checkXMLEq(basicParams.getAsXML(), + mkBasicSettings(defaultBasicSettingsXML, "parameter_block")); + } + string testSettings = mkBasicSettings(testBasicSettingsXML, "parameter_block"); + string rawTestSettings = mkBasicSettings(testRawHexBasicSettingsXML, "parameter_block"); + + auto checkExport = [&] { + THEN ("Exported settings should be the ones imported") { + checkXMLEq(basicParams.getAsXML(), testSettings); + } + THEN ("Exported raw settings should be the ones imported") { + setRawValueSpace(true); + setHexOutputFormat(true); + checkXMLEq(basicParams.getAsXML(), rawTestSettings); + } + }; + WHEN ("Importing basic parameter XML") { + CHECK_NOTHROW(basicParams.setAsXML(testSettings)); + checkExport(); + } + WHEN ("Importing raw basic parameter XML") { + CHECK_NOTHROW(basicParams.setAsXML(rawTestSettings)); + checkExport(); + } +} + +static const string defaultBasicSettingsBytes = + "00 00 00 21 00 f6 ff ff ff f6 ff ff ff f6 ff ff ff f6 ff ff ff 00 00 00 00 " + "00 00 00 00 00 00 00 00 00 00 00 00 80 08 00 08 00 08 00 08 00 00 00 00 00 00 " + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "; + +static const string testBasicSettingsBytes = + "01 00 01 64 00 f6 ff ff ff 00 00 00 00 08 00 00 00 0a 00 00 00 00 00 00 24 " + "00 00 00 72 00 00 00 0b 00 00 00 f0 05 08 00 01 80 08 00 01 80 41 20 73 74 72 " + "69 6e 67 20 6f 66 20 33 32 20 63 68 61 72 61 63 74 65 72 2e 40 40 40 40 40 40 " + "40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "00 00 00 00 00 00 00 8a 02 48 00 ff ff ff ff "; + +SCENARIO_METHOD(SettingsTestPF, "Bijection of binary show and read", "[identity][test]") +{ + CHECK(showBytes(readBytes(testBasicSettingsBytes)) == testBasicSettingsBytes); +} + +SCENARIO_METHOD(SettingsTestPF, "Export and import root binary settings", + "[handler][settings][bytes]") +{ + ElementHandle root(*this, "/"); + ElementHandle systemClass(*this, "/"); + + THEN ("Root and system class should export the same binary") { + checkBytesEq(root.getAsBytes(), systemClass.getAsBytes()); + } + WHEN ("Exporting root binary") { + checkBytesEq(root.getAsBytes(), fullBytesSettings(defaultBasicSettingsBytes)); + } + WHEN ("Importing root binary") { + string rootTestSettings = fullBytesSettings(testBasicSettingsBytes); + REQUIRE_NOTHROW(root.setAsBytes(readBytes(rootTestSettings))); + THEN ("Exported settings should be the ones imported") { + checkBytesEq(root.getAsBytes(), rootTestSettings); + } + } +} + +SCENARIO_METHOD(SettingsTestPF, "Export and import basic binary settings", + "[handler][settings][bytes]") +{ + ElementHandle basicParams(*this, "/test/test/parameter_block"); + WHEN ("Exporting basic parameter binary") { + checkBytesEq(basicParams.getAsBytes(), defaultBasicSettingsBytes); + } + WHEN ("Importing basic parameter binary") { + REQUIRE_NOTHROW(basicParams.setAsBytes(readBytes(testBasicSettingsBytes))); + THEN ("Exported settings should be the ones imported") { + checkBytesEq(basicParams.getAsBytes(), testBasicSettingsBytes); + } + } +} + +SCENARIO_METHOD(SettingsTestPF, "Export and import array binary settings", + "[handler][settings][bytes]") +{ + ElementHandle array(*this, "/test/test/parameter_block_array"); + ElementHandle elem0(*this, "/test/test/parameter_block_array/0"); + WHEN ("Importing one array element") { + REQUIRE_NOTHROW(elem0.setAsBytes(readBytes(testBasicSettingsBytes))); + THEN ("The other element should not have changed") { + checkBytesEq(array.getAsBytes(), testBasicSettingsBytes + defaultBasicSettingsBytes); + } + } +} + +SCENARIO_METHOD(SettingsTestPF, "Import root in one format, export in an other", + "[handler][settings][bytes][xml]") +{ + ElementHandle root(*this, "/test"); + string rootBytesSettings = fullBytesSettings(testBasicSettingsBytes); + string rootXMLSettings = fullXMLSettings(testBasicSettingsXML); + + WHEN ("Importing root binary") { + REQUIRE_NOTHROW(root.setAsBytes(readBytes(rootBytesSettings))); + THEN ("Exported XML settings should be the ones imported") { + checkXMLEq(root.getAsXML(), rootXMLSettings); + } + } + + WHEN ("Importing root XML") { + REQUIRE_NOTHROW(root.setAsXML(rootXMLSettings)); + THEN ("Exported bytes settings should be the ones imported") { + checkBytesEq(root.getAsBytes(), rootBytesSettings); + } + } +} + +SCENARIO_METHOD(SettingsTestPF, "Import basic params in one format, export in an other", + "[handler][settings][bytes][xml]") +{ + ElementHandle basicParams(*this, "/test/test/parameter_block_array/0"); + string basicXMLSettings = mkBasicSettings(testBasicSettingsXML, "0"); + + WHEN ("Importing basic parameters binary") { + REQUIRE_NOTHROW(basicParams.setAsBytes(readBytes(testBasicSettingsBytes))); + THEN ("Exported XML settings should be the ones imported") { + checkXMLEq(basicParams.getAsXML(), basicXMLSettings); + } + } + + WHEN ("Importing basic parameters XML") { + REQUIRE_NOTHROW(basicParams.setAsXML(basicXMLSettings)); + THEN ("Exported bytes settings should be the ones imported") { + checkBytesEq(basicParams.getAsBytes(), testBasicSettingsBytes); + } + } +} + +struct MappingPF : public ParameterFramework +{ + MappingPF() : ParameterFramework{getConfig()} { REQUIRE_NOTHROW(start()); } + + struct TestVector + { + string path; + string humanReadable; + list<string> valid; + list<string> invalid; + }; + + list<TestVector> testVectors = { + // clang-format off + {"/test/test", + {"rootK:rootV"}, + {"root"}, + {"param", "type", "instance", "derived"}}, + {"/test/test/param", + {"rootK:rootV, paramK:paramV"}, + {"root", "param"}, + {"type", "derived", "instance"}}, + {"/test/test/component", + {"rootK:rootV, typeK:typeV, derivedK:derivedV, instanceK:instanceV"}, + {"root", "type", "derived", "instance"}, + {"param"}} + // clang-format on + }; + + Config getConfig() + { + Config config; + config.subsystemMapping = "rootK:rootV"; + config.components = "<ComponentType Name='componentType' Mapping='typeK:typeV' />" + "<ComponentType Extends='componentType' Name='derivedComponentType' " + "Mapping='derivedK:derivedV' />"; + config.instances = "<BooleanParameter Name='param' Mapping='paramK:paramV' />" + "<Component Name='component' Mapping='instanceK:instanceV' " + " Type='derivedComponentType' />"; + return config; + } +}; + +SCENARIO_METHOD(MappingPF, "showMapping command", "[mapping]") +{ + auto cmdHandler = std::unique_ptr<CommandHandlerInterface>(createCommandHandler()); + + for (auto &testVector : testVectors) { + string output; + CHECK(cmdHandler->process("showMapping", {testVector.path}, output)); + CHECK(output == testVector.humanReadable); + } +} + +SCENARIO_METHOD(MappingPF, "Mapping handle access", "[handler][mapping]") +{ + GIVEN ("A PF with mappings") { + for (auto &test : testVectors) { + GIVEN ("An element handle of " + test.path) { + ElementHandle handle(*this, test.path); + + for (auto &valid : test.valid) { + THEN ("The following mapping should exist: " + valid) { + CHECK(handle.getMappingData(valid + "K") == valid + "V"); + } + } + + for (auto &invalid : test.invalid) { + THEN ("The following mapping should not exist: " + invalid) { + CHECK_THROWS_AS(handle.getMappingData(invalid + "K"), Exception); + } + } + } + } + } +} + +SCENARIO_METHOD(SettingsTestPF, "Handle Get/Set as various kinds", "[handler][dynamic]") +{ + ElementHandle intScalar(*this, "/test/test/parameter_block/integer"); + WHEN ("Setting a scalar integer") { + WHEN ("As an array") { + THEN ("It should fail") { + CHECK_THROWS(intScalar.setAsIntegerArray({0, 0})); + } + } + WHEN ("As a scalalar") { + THEN ("It should succeed") { + uint32_t expected = 111; + CHECK_NOTHROW(intScalar.setAsInteger(expected)); + AND_THEN ("Getting it back should give the same value") { + uint32_t back = 42; + CHECK_NOTHROW(intScalar.getAsInteger(back)); + CHECK(back == expected); + } + } + } + } + + ElementHandle intArray(*this, "/test/test/parameter_block/integer_array"); + WHEN ("Setting a array integer") { + WHEN ("As a scalar") { + THEN ("It should fail") { + CHECK_THROWS(intArray.setAsSignedInteger(0)); + } + } + WHEN ("As a integer") { + THEN ("It should succeed") { + const std::vector<int32_t> expected = {-9, 8, -7, 6}; + CHECK_NOTHROW(intArray.setAsSignedIntegerArray(expected)); + AND_THEN ("Getting it back should give the same value") { + std::vector<int32_t> back = {-42, 42, 43, -43}; + CHECK_NOTHROW(intArray.getAsSignedIntegerArray(back)); + CHECK(back == expected); + } + } + } + } +} +} // namespace parameterFramework diff --git a/test/functional-tests/Util/PfwUnitTestLib.py b/test/functional-tests/Util/PfwUnitTestLib.py deleted file mode 100644 index d9c2f8c..0000000 --- a/test/functional-tests/Util/PfwUnitTestLib.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*-coding:utf-8 -* - -# Copyright (c) 2011-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. - -import subprocess -import unittest -import time - -class RemoteCli(object): - def sendCmd(self, cmd, *args): - shell_cmd = " ".join([self.platform_command, cmd]) - if args is not None: - shell_cmd += " " + " ".join(args) - print "CMD :", - print "[" + shell_cmd + "]" - try: - p = subprocess.Popen(shell_cmd, shell=True, stdout=subprocess.PIPE) - except Exception as (errno, strerror): - return None, strerror - out, err = p.communicate() - if out is not None: - out = out.strip() - return out, err - -class Pfw(RemoteCli): - def __init__(self): - self.platform_command = "remote-process localhost 5000 " - -class Hal(RemoteCli): - def __init__(self): - self.platform_command = "remote-process localhost 5001 " - - # Starts the HAL exe - def startHal(self): - cmd= "test-platform $PFW_TEST_CONFIGURATION" - subprocess.Popen(cmd, shell=True) - pass - - # Send command "stop" to the HAL - def stopHal(self): - subprocess.call("remote-process localhost 5001 exit", shell=True) - - def createInclusiveCriterion(self, name, nb): - self.sendCmd("createInclusiveSelectionCriterion", name, nb) - - def createExclusiveCriterion(self, name, nb): - self.sendCmd("createExclusiveSelectionCriterion", name, nb) - - # Starts the Pfw - def start(self): - self.sendCmd("start") - -# A PfwTestCase gather tests performed on one instance of the PFW. -class PfwTestCase(unittest.TestCase): - - hal = Hal() - - def __init__(self, argv): - super(PfwTestCase, self).__init__(argv) - self.pfw = Pfw() - - @classmethod - def setUpClass(cls): - cls.startHal() - - @classmethod - def tearDownClass(cls): - cls.stopHal() - - @classmethod - def startHal(cls): - # set up the Hal & pfw - cls.hal.startHal() - time.sleep(0.1) - # create criterions - cls.hal.createInclusiveCriterion("Crit_0", "2") - cls.hal.createExclusiveCriterion("Crit_1", "2") - # start the Pfw - cls.hal.start() - - @classmethod - def stopHal(cls): - cls.hal.stopHal() - time.sleep(0.1) diff --git a/parameter/BinaryStream.h b/test/functional-tests/include/Config.hpp index 6df777c..3d3f117 100644 --- a/parameter/BinaryStream.h +++ b/test/functional-tests/include/Config.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,50 +29,54 @@ */ #pragma once -#include <stdint.h> #include <string> -#include <fstream> +#include <list> +#include <utility> -class CBinaryStream +namespace parameterFramework { -public: - CBinaryStream(const std::string& strFileName, bool bOut, size_t uiDataSize, uint8_t uiStructureChecksum); - ~CBinaryStream(); - // Open close - bool open(std::string& strError); - void close(); +/** Parameter Framework configuration. */ +struct Config +{ + Config() = default; + + /** Emulate C named parameter. + * { .instances = "fuu" } <=> { &Config::instances, "fuu" } + * Passing multiple named parameters is not implemented. */ + template <class M, class T = M> + Config(M(Config::*member), T &&value) + { + (this->*member) = std::forward<T>(value); + } - // Seek - void reset(); + /** Mapping attribute of the test subsystem. */ + std::string subsystemMapping; - // Read/Write - void write(const uint8_t* puiData, size_t uiSize); - void read(uint8_t* puiData, size_t uiSize); + /** Instances of the test subsystem. + * + * Content of the configuration + * SystemClass/Subsystem[name=test]/InstanceDefinition xml node. + */ + std::string instances; + /** Content of the configuartion ConfigurableDomains xml node. */ + std::string domains; + /** Content of the configuration SubsystemPlugins xml node. */ + std::string components; - // Direction - bool isOut() const; -private: - CBinaryStream(const CBinaryStream&); - CBinaryStream& operator=(const CBinaryStream&); - // Checksum - uint8_t computeChecksum() const; + struct Plugin + { + using Location = std::string; + using Name = std::string; + /** Each plugin has a location and a path. + * Locations can be factorized by using */ + using Collection = std::list<std::pair<Location, std::list<Name>>>; + }; + using Plugins = Plugin::Collection; + Plugins plugins; - // File name - std::string _strFileName; - // Serialization direction - bool _bOut; - // Data size - size_t _uiDataSize; - // System structure checksum - uint8_t _uiStructureChecksum; - // Read/Write data - uint8_t* _puiData; - // File - std::fstream _fileStream; - // Ops in faile - size_t _uiPos; - // File state - bool _bOpen; + /** Subsystem type. Virtual by default. */ + std::string subsystemType = "Virtual"; }; +} // parameterFramework diff --git a/test/functional-tests/include/ConfigFiles.hpp b/test/functional-tests/include/ConfigFiles.hpp new file mode 100644 index 0000000..3d14b86 --- /dev/null +++ b/test/functional-tests/include/ConfigFiles.hpp @@ -0,0 +1,127 @@ +/* + * 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. + */ +#pragma once + +#include "TmpFile.hpp" +#include "Config.hpp" + +#include <string> +#include <map> + +namespace parameterFramework +{ + +/** Create temporary config files on disk. */ +class ConfigFiles +{ +public: + ConfigFiles(const Config &config) + : mStructureFile( + format(mStructureTemplate, {{"type", config.subsystemType}, + {"instances", config.instances}, + {"components", config.components}, + {"subsystemMapping", config.subsystemMapping}})), + mDomainsFile(format(mDomainsTemplate, {{"domains", config.domains}})), + mConfigFile(format(mConfigTemplate, {{"structurePath", mStructureFile.getPath()}, + {"domainsPath", mDomainsFile.getPath()}, + {"plugins", toXml(config.plugins)}})) + { + } + + std::string getPath() { return mConfigFile.getPath(); } + +private: + std::string toXml(const Config::Plugin::Collection &plugins) + { + std::string pluginsXml; + for (auto &pluginLocation : plugins) { + std::string pluginsLocationXml; + auto location = pluginLocation.first; + auto paths = pluginLocation.second; + for (auto &path : paths) { + pluginsLocationXml += "<Plugin Name='" + path + "'/>\n"; + } + pluginsXml += + "<Location Folder='" + location + "'>\n" + pluginsLocationXml + "\n</Location>\n"; + } + return pluginsXml; + } + + std::string format(std::string format, std::map<std::string, std::string> subs) + { + for (auto &sub : subs) { + replace(format, '{' + sub.first + '}', sub.second); + } + return format; + } + + void replace(std::string &on, const std::string &from, const std::string &to) + { + auto from_pos = on.find(from); + if (from_pos != std::string::npos) { + on.replace(from_pos, from.length(), to); + } + } + + const char *mConfigTemplate = R"(<?xml version='1.0' encoding='UTF-8'?> + <ParameterFrameworkConfiguration SystemClassName='test' TuningAllowed='true'> + <SubsystemPlugins> + {plugins} + </SubsystemPlugins> + <StructureDescriptionFileLocation Path='{structurePath}'/> + <SettingsConfiguration> + <ConfigurableDomainsFileLocation Path='{domainsPath}'/> + </SettingsConfiguration> + </ParameterFrameworkConfiguration> + )"; + const char *mStructureTemplate = R"(<?xml version='1.0' encoding='UTF-8'?> + <SystemClass Name='test'> + <Subsystem Name='test' Type='{type}' Mapping='{subsystemMapping}'> + <ComponentLibrary> + {components} + </ComponentLibrary> + <InstanceDefinition> + {instances} + </InstanceDefinition> + </Subsystem> + </SystemClass> + )"; + const char *mDomainsTemplate = R"(<?xml version='1.0' encoding='UTF-8'?> + <ConfigurableDomains SystemClassName="test"> + {domains} + </ConfigurableDomains> + )"; + + utility::TmpFile mStructureFile; + utility::TmpFile mDomainsFile; + utility::TmpFile mConfigFile; +}; + +} // parameterFramework diff --git a/test/functional-tests/include/ElementHandle.hpp b/test/functional-tests/include/ElementHandle.hpp new file mode 100644 index 0000000..fe42b71 --- /dev/null +++ b/test/functional-tests/include/ElementHandle.hpp @@ -0,0 +1,115 @@ +/* + * 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. + */ +#pragma once + +#include "ParameterFramework.hpp" +#include "FailureWrapper.hpp" + +#include <ElementHandle.h> + +namespace parameterFramework +{ +/** Wrapper around ::ElementHandle to throw exceptions on errors and have more + * user friendly methods. + * Contrary to ::ElementHandle, is constructed through it's constructor + * and not a factory method. + * @see parameterFramework::ParameterFramework for the main PF interface. + */ +class ElementHandle : private FailureWrapper<::ElementHandle> +{ + ElementHandle(const ElementHandle &other) = delete; + ElementHandle &operator=(const ElementHandle &other) = delete; + +private: + using EH = ::ElementHandle; + +public: + ElementHandle(ParameterFramework &pf, const std::string &path) + : FailureWrapper(pf.createElementHandle(path)) + { + } + + /** Wrap EH::getSize. + * + * @note: can not use `using EH::getSize` as getSize has private overloads in EH. + */ + size_t getSize() const { return EH::getSize(); } + + std::string getMappingData(const std::string &key) + { + std::string value; + if (not EH::getMappingData(key, value)) { + throw Exception("Could not find mapping key \"" + key + "\" in " + EH::getPath()); + } + return value; + } + + /** Wrap EH::setAsDouble to throw an exception on failure. */ + void setAsDouble(double value) { mayFailCall(&EH::setAsDouble, value); } + /** Wrap EH::getAsDouble to throw an exception on failure. */ + void getAsDouble(double &value) const { mayFailCall(&EH::getAsDouble, value); } + + void setAsInteger(uint32_t value) { mayFailCall(&EH::setAsInteger, value); } + void getAsInteger(uint32_t &value) const { mayFailCall(&EH::getAsInteger, value); } + void setAsIntegerArray(const std::vector<uint32_t> &value) + { + mayFailCall(&EH::setAsIntegerArray, value); + } + void getAsIntegerArray(std::vector<uint32_t> &value) const + { + mayFailCall(&EH::getAsIntegerArray, value); + } + + void setAsSignedInteger(int32_t value) { mayFailCall(&EH::setAsSignedInteger, value); } + void getAsSignedInteger(int32_t &value) const { mayFailCall(&EH::getAsSignedInteger, value); } + void setAsSignedIntegerArray(const std::vector<int32_t> &value) + { + mayFailCall(&EH::setAsSignedIntegerArray, value); + } + void getAsSignedIntegerArray(std::vector<int32_t> &value) const + { + mayFailCall(&EH::getAsSignedIntegerArray, value); + } + + std::string getStructureAsXML() const { return mayFailGet(&EH::getStructureAsXML); } + + std::string getAsXML() const { return mayFailGet(&EH::getAsXML); } + void setAsXML(const std::string &settings) { mayFailSet(&EH::setAsXML, settings); } + + std::vector<uint8_t> getAsBytes() const + { + std::vector<uint8_t> settings(getSize()); + mayFailCall(&EH::getAsBytes, settings); + return settings; + } + void setAsBytes(const std::vector<uint8_t> &settings) { mayFailSet(&EH::setAsBytes, settings); } +}; + +} // parameterFramework diff --git a/parameter/AutoLock.h b/test/functional-tests/include/Exception.hpp index ab24a94..8ae0597 100644 --- a/parameter/AutoLock.h +++ b/test/functional-tests/include/Exception.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,22 +29,16 @@ */ #pragma once -#include <pthread.h> +#include <stdexcept> +#include <string> -class CAutoLock +namespace parameterFramework { -public: - CAutoLock(pthread_mutex_t* pMutex) : _pMutex(pMutex) - { - pthread_mutex_lock(_pMutex); - } - ~CAutoLock() - { - pthread_mutex_unlock(_pMutex); - } - -private: - pthread_mutex_t* _pMutex; +/** Base class to all exception thrown by the Parameter Framework. */ +struct Exception : std::runtime_error +{ + using std::runtime_error::runtime_error; }; +} // parameterFramework diff --git a/test/functional-tests/include/FailureWrapper.hpp b/test/functional-tests/include/FailureWrapper.hpp new file mode 100644 index 0000000..753e1dc --- /dev/null +++ b/test/functional-tests/include/FailureWrapper.hpp @@ -0,0 +1,136 @@ +/* + * 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. + */ +#pragma once + +#include <utility> +#include "Exception.hpp" + +namespace parameterFramework +{ + +namespace details +{ + +static inline bool successTest(bool res) +{ + return res; +} + +template <class T> +static inline bool successTest(T *res) +{ + return res != nullptr; +} + +} // namespace details + +template <class Base> +class FailureWrapper : protected Base +{ +public: + /** Forward construction to base. */ + template <class... Args> + FailureWrapper(Args &&... args) : Base(std::forward<Args>(args)...) + { + } + + /** Wrap a const method that may fail to throw an Exception instead of + * retuning a boolean. + * + * @param[in] method (const) that return a boolean to indicate failure. + * @param[in] args parameters to call method call with. */ + template <class K, class... MArgs, class... Args> + void mayFailCall(bool (K::*method)(MArgs...) const, Args &&... args) const + { + wrapCall<bool>(*this, method, std::forward<Args>(args)...); + } + + /** Wrap a method that may fail to throw an Exception instead of retuning a + * boolean. + * + * @param[in] method that return a boolean to indicate failure. + * @param[in] args parameters to call method call with. */ + template <class K, class... MArgs, class... Args> + void mayFailCall(bool (K::*method)(MArgs...), Args &&... args) + { + wrapCall<bool>(*this, method, std::forward<Args>(args)...); + } + + /** Wrap a method that may indicate failure by returning a null pointer to + * throw an Exception instead of retuning a null pointer. + * + * @param[in] method that return a nullprt to indicate failure. + * @param[in] args parameters to call method call with. */ + template <class K, class ReturnType, class... MArgs, class... Args> + ReturnType *mayFailCall(ReturnType *(K::*method)(MArgs...), Args &&... args) + { + return wrapCall<ReturnType *>(*this, method, std::forward<Args>(args)...); + } + + /** Wrap a const method that may indicate failure by returning a null pointer to + * throw an Exception instead of retuning a null pointer. + * + * @param[in] method that return a nullprt to indicate failure. + * @param[in] args parameters to call method call with. */ + template <class K, class ReturnType, class... MArgs, class... Args> + ReturnType *mayFailCall(ReturnType *(K::*method)(MArgs...) const, Args &&... args) const + { + return wrapCall<ReturnType *>(*this, method, std::forward<Args>(args)...); + } + + /** Wrap a getter to return by value and throw an exception on failure. */ + template <class K, class Value> + Value mayFailGet(bool (K::*accessor)(Value &, std::string &) const) const + { + Value value; + wrapCall<bool>(*this, accessor, value); + return value; + } + + /** Wrap a setter to throw an exception on failure instead of returning a boolean. */ + template <class K, class Value> + void mayFailSet(bool (K::*accessor)(const Value &, std::string &), const Value &value) + { + wrapCall<bool>(*this, accessor, value); + } + +private: + template <class Ret, class I, class M, class... Args> + static Ret wrapCall(I &instance, M method, Args &&... args) + { + std::string error; + auto res = (instance.*method)(std::forward<Args>(args)..., error); + if (not details::successTest(res)) { + throw Exception(std::move(error)); + } + return res; + } +}; +} // parameterFramework diff --git a/test/functional-tests/include/ParameterFramework.hpp b/test/functional-tests/include/ParameterFramework.hpp new file mode 100644 index 0000000..f6f36a8 --- /dev/null +++ b/test/functional-tests/include/ParameterFramework.hpp @@ -0,0 +1,173 @@ +/* + * 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. + */ +#pragma once + +#include "Config.hpp" +#include "ConfigFiles.hpp" +#include "FailureWrapper.hpp" + +#include <ParameterMgrFullConnector.h> + +namespace parameterFramework +{ + +/** This forward declaration is an implementation detail, client should expect its presence. + * @note This forward definition should not be needed as the `friend class ElementHandle` + * declaration in ParameterFramework is itself a forward declaration. + * Unfortunately there seem to be a bug in visual studio 2015, it is required. + */ +class ElementHandle; + +/** Wrapper around the Parameter Framework to throw exceptions on errors and + * have more user friendly methods. + * @see parameterFramework::ElementHandle to access elements of the parameter tree. + */ +class ParameterFramework : private parameterFramework::ConfigFiles, + private FailureWrapper<CParameterMgrFullConnector> +{ +protected: + /** Alias to the Platform Connector PF. + * It should not be usefull as PF is a super set but is useful + * to disambiguate overloaded method for MS visual compiler. + */ + using PPF = CParameterMgrPlatformConnector; + using PF = CParameterMgrFullConnector; + using EH = ::ElementHandle; + +public: + ParameterFramework(const Config &config = Config()) + : ConfigFiles(config), FailureWrapper(getPath()) + { + setForceNoRemoteInterface(true); + } + + void start() { mayFailCall(&PF::start); } + + /** @name Forwarded methods + * Forward those methods without modification as there are ergonomic and + * can not fail (no failure to throw). + * @{ */ + using PF::applyConfigurations; + using PF::getFailureOnMissingSubsystem; + using PF::getFailureOnFailedSettingsLoad; + using PF::getForceNoRemoteInterface; + using PF::setForceNoRemoteInterface; + using PF::getSchemaUri; + using PF::setSchemaUri; + using PF::getValidateSchemasOnStart; + using PF::isValueSpaceRaw; + using PF::isOutputRawFormatHex; + using PF::isTuningModeOn; + using PF::isAutoSyncOn; + using PF::setLogger; + using PF::createCommandHandler; + /** @} */ + + /** Wrap PF::setValidateSchemasOnStart to throw an exception on failure. */ + void setValidateSchemasOnStart(bool validate) + { + mayFailCall(&PPF::setValidateSchemasOnStart, validate); + } + + /** Wrap PF::setFailureOnFailedSettingsLoad to throw an exception on failure. */ + void setFailureOnFailedSettingsLoad(bool fail) + { + mayFailCall(&PPF::setFailureOnFailedSettingsLoad, fail); + } + + /** Wrap PF::setFailureOnMissingSubsystem to throw an exception on failure. */ + void setFailureOnMissingSubsystem(bool fail) + { + mayFailCall(&PPF::setFailureOnMissingSubsystem, fail); + } + + /** Renaming for better readability (and coherency with PF::isValueSpaceRaw) + * of PF::setValueSpace. */ + void setRawValueSpace(bool enable) { setValueSpace(enable); } + + /** Renaming for better readability (and coherency with PF::isValueSpaceRaw) + * of PF::setValueSpace. */ + void setHexOutputFormat(bool enable) { setOutputRawFormat(enable); } + + /** Wrap PF::setTuningMode to throw an exception on failure. */ + void setTuningMode(bool enable) { mayFailCall(&PF::setTuningMode, enable); } + + /** Wrap PF::setAutoSync to throw an exception on failure. */ + void setAutoSync(bool enable) { mayFailCall(&PF::setAutoSync, enable); } + + /** Wrap PF::accessParameterValue in "set" mode (and rename it) to throw an + * exception on failure + */ + void setParameter(const std::string &path, std::string &value) + { + mayFailCall(&PF::accessParameterValue, path, value, true); + } + /** Wrap PF::accessParameterValue in "get" mode (and rename it) to throw an + * exception on failure + */ + void getParameter(const std::string &path, std::string &value) + { + mayFailCall(&PF::accessParameterValue, path, value, false); + } + + /** Wrap PF::accessConfigurationValue in "set" mode (and rename it) to throw an + * exception on failure + */ + void setConfigurationParameter(const std::string domain, const std::string &configuration, + const std::string &path, std::string &value) + { + mayFailCall(&PF::accessConfigurationValue, domain, configuration, path, value, true); + } + + /** Wrap PF::accessConfigurationValue in "get" mode (and rename it) to throw an + * exception on failure + */ + void getConfigurationParameter(const std::string &domain, const std::string &configuration, + const std::string &path, std::string &value) + { + mayFailCall(&PF::accessConfigurationValue, domain, configuration, path, value, false); + } + +private: + /** Create an unwrapped element handle. + * + * Is not public as this method is intended to be used by ElementHandle facade. + */ + EH createElementHandle(const std::string &path) + { + // PF::createElementHandle takes it's handler in the free store + std::unique_ptr<EH> newedHandle{mayFailCall(&PF::createElementHandle, path)}; + EH handle{*newedHandle}; + return handle; + } + friend class ElementHandle; +}; + +} // parameterFramework diff --git a/test/functional-tests/include/StoreLogger.hpp b/test/functional-tests/include/StoreLogger.hpp new file mode 100644 index 0000000..8364157 --- /dev/null +++ b/test/functional-tests/include/StoreLogger.hpp @@ -0,0 +1,118 @@ +/* + * 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 <ParameterMgrFullConnector.h> +#include <vector> +#include <utility> +#include <string> +#include <algorithm> +#include <sstream> +#include <iterator> + +namespace parameterFramework +{ + +/** Logger that stores all fed log in order retrieve them asynchronously. + * Compatible with the ParameterFramework::Ilogger api. + * Usually used in tests to inspect what was logged by a PF instances + * (eg: test if a warring occurred). + */ +class StoreLogger : public CParameterMgrFullConnector::ILogger +{ +public: + struct Log + { + enum class Level + { + info, + warning + }; + Level level; + std::string msg; + bool operator==(const Log &other) const + { + return level == other.level and msg == other.msg; + } + }; + using Logs = std::vector<Log>; + + void warning(const std::string &strLog) override + { + logs.push_back({Log::Level::warning, strLog}); + } + void info(const std::string &strLog) override { logs.push_back({Log::Level::info, strLog}); } + + const Logs &getLogs() const { return logs; } + + const Logs filter(Log::Level level) const + { + return filter([&level](const Log &log) { return log.level == level; }); + }; + + Logs match(const std::string &pattern) const + { + return filter( + [&pattern](const Log &log) { return log.msg.find(pattern) == std::string::npos; }); + } + +private: + template <class Predicate> + Logs filter(Predicate predicate) const + { + Logs filtered; + std::copy_if(logs.begin(), logs.end(), std::back_inserter(filtered), predicate); + return filtered; + } + + Logs logs; +}; + +/** Overload input stream operator to pretty print a StoreLogger::Log::Level. */ +std::ostream &operator<<(std::ostream &os, const StoreLogger::Log::Level &level) +{ + auto levelStr = "UNREACHABLE"; + using L = StoreLogger::Log::Level; + switch (level) { + case L::info: + levelStr = "Info"; + break; + case L::warning: + levelStr = "Warn"; + break; + } + return os << levelStr << ": "; +} + +/** Overload input stream operator to pretty print a StoreLogger::Log. */ +std::ostream &operator<<(std::ostream &os, const StoreLogger::Log &log) +{ + return os << log.level << log.msg << std::endl; +} + +} // parameterFramework diff --git a/test/functional-tests/include/Test.hpp b/test/functional-tests/include/Test.hpp new file mode 100644 index 0000000..51f397a --- /dev/null +++ b/test/functional-tests/include/Test.hpp @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#pragma once + +#include "Config.hpp" +#include "ParameterFramework.hpp" + +#include <catch.hpp> + +#include <string> + +#ifndef SCENARIO_METHOD +/** SCENARIO_METHOD is not available in catch on ubuntu 12.04 */ +#define SCENARIO_METHOD(className, ...) TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__) +#endif + +namespace parameterFramework +{ + +/** Value to test with a title. + * + * When testing code it is often useful to have an list of possible + * values and run the test for each of them. + * This class represents one element of this list. For the complete list + * see Tests. + * + * Catch has no build-in support for such need + * (in fact it has but it is still experimental, look for "generators") + * but it can be emulated with a loop over Tests. + * + * Each Test MUST specify a unique title, Ie all titles of a Tests MUST + * be different. This is dued to the way that catch detects that a SECTION + * has already been run. For more explanation see Tests. + */ +template <class Value> +struct Test +{ + std::string title; + Value payload; +}; + +/** Use a vector to represent a collection of test input. + * + * This type is designed to be used to parametrize tests. + * Use it as follow: + * for (auto &test : Tests<std::string>{ + * // ^~~~~~~~~~~ Test parameter type + * {"an invalid tag", "<invalid tag\"/> "}, + * //^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Test parameters + * {"an unknown tag", "<unknown_tag/>"}, + * // ^~~~~~~~~~~~~~~~ Unique title across the tests + * {"an unclosed tag", "<unclosed>"} }) { + * // ^~~~~~~~~~~ Value to test + * SECTION("Testing: " + test.title) { + * // ^~~~~~~~~~ Section title MUST unique + * test.payload //< value to test + * REQUIRE(getTag() != test.payload); // Example + * ... + * } + * } + * + * + * Beware that if Value is not copyable, only movable this will + * fail to compile as initializer_list does not support move semantic + * (lets hope it will be fix in C++17). + * + * If a new test vector needs to support move, define: + * template <class Value> + * using MovableTests = Test<value>[]; + * This could be the default but VS2013 does not support it. + * VS requires that an array size be defined. Thus define + * template <class Value, size_t size> + * using MovableTests = Test<value>[size]; + * will fix the VS compilation. Nevertheless this means that + * all move only test vector will need to specify their size + * which is redondant. + * This is why it is not the default. + * Hopefully it will be when VS will support deducing the size. + */ +template <class Value> +using Tests = std::vector<Test<Value>>; + +/** Defer Parameter Framework creation. + * A custom configuration can be provided. + */ +class LazyPF +{ +public: + using PF = ParameterFramework; + + void create(Config &&configFile) { mPf.reset(new PF{std::move(configFile)}); } + std::unique_ptr<PF> mPf; +}; + +/** PF that will log a warning at start. */ +struct WarningPF : public ParameterFramework +{ + WarningPF() : ParameterFramework{{&Config::domains, "<InvalidDomain/>"}} + { + setFailureOnFailedSettingsLoad(false); + } +}; +} diff --git a/test/functional-tests/plan.md b/test/functional-tests/plan.md new file mode 100644 index 0000000..8497616 --- /dev/null +++ b/test/functional-tests/plan.md @@ -0,0 +1,402 @@ +# Parameter Framework (PF) test plan + +## Notes +- The unit test code MAY be able to list implemented scenarios + in this same BDD format in order to check scenario coverage. +- All scenarios implicitly start by _"GIVEN a parameter framework"_. +- If a scenario does not specify a config files, + the following minimal files SHOULD be used: + +Top level file (replace `{structurePath}` by its value): +~~~ xml +<?xml version='1.0' encoding='UTF-8'?> +<ParameterFrameworkConfiguration SystemClassName='test' + TuningAllowed='false' ServerPort='1'> + <SubsystemPlugins/> + <StructureDescriptionFileLocation Path='{structurePath}'/> +</ParameterFrameworkConfiguration> +~~~ + +Structure file: +~~~ xml +<?xml version='1.0' encoding='UTF-8'?> +<SystemClass Name='test'> + <Subsystem Name='test' Type='Virtual'> + <ComponentLibrary/> + <InstanceDefinition> + <BooleanParameter Name="placeholder"/> + </InstanceDefinition> + </Subsystem> +</SystemClass> +~~~ + +## Starting the Parameter Framework + +- set a logger + - [X] Scenario: Default logger + * WHEN no logger is set + * THEN start should succeed + + - [X] Scenario: No logger + * WHEN a nullptr logger is set + * THEN start should succeed + + - [X] Scenario: Logger should receive info and warnings + * GIVEN config files that emit warnings + * GIVEN a logger that store logs + * WHEN the record logger is set + * THEN start should succeed + * AND_THEN the logger should have stored info and warning log + + - [X] Scenario: Unset logger + * GIVEN config files that emit warnings + * GIVEN a logger that store logs + * WHEN the record logger is set + * AND_WHEN a nullptr logger is set + * THEN start should succeed + * AND_THEN the record logger should NOT have stored any info or warning log + +- set/get various properties before startup: + - "force no remote interface" + - [ ] Scenario: Tuning OK + * GIVEN config files with tuning enabled on a valid port + * WHEN the remote interface is NOT forbiden + * THEN start should succeed + + - [ ] Scenario: Invalid tunning + * GIVEN config files with tuning enabled on an invalid port (0?) + * WHEN the remote interface is NOT forbiden + * THEN start should fail + + - [ ] Scenario: Forbiden invalid tunning + * GIVEN config files with tuning enabled on an invalid port (0?) + * WHEN the remote interface is forbiden + * THEN start should succeed + + - "failure on missing subsystem" + - [ ] Scenario: Plugin OK + * GIVEN config files with a valid plugin + * WHEN the missing subsystem policy is set to failure + * THEN start should succeed + + - [X] Scenario: Wrong plugin + * GIVEN config files with a invalid plugin + * WHEN the missing subsystem policy is set to failure + * THEN start should fail + + - [ ] Scenario: Wrong plugin but fallback + * GIVEN config files with a invalid plugin + * WHEN the missing subsystem policy is set to success + * THEN start should succeed + + - "failure on failed settings load" + - [X] Scenario: Settings OK + * GIVEN config files with a valid settings file + * WHEN settings load failure is requested to abort start + * THEN start should succeed + + - [X] Scenario: Wrong settings + * GIVEN config files with a invalid (non existant?) settings file + * WHEN settings load failure is requested to abort start + * THEN start should fail + + - [X] Scenario: Wrong settings but ignore + * GIVEN config files with a invalid (non existant?) settings file + * WHEN settings load failure is requested to abort start + * THEN start should succeed + + - "schema folder location" and "validate schema on start" + - [ ] Scenario: Schema OK + * GIVEN config files with correct default schema location + * WHEN schema folder location is left to default + * WHEN schema validation is enabled + * THEN start should succeed + + - [ ] Scenario: Inexisting schemas + * GIVEN config files with correct default schema location + * WHEN schema folder location is set to an invalid location (/doesNotExist ?) + * WHEN schema validation is enabled + * THEN start should fail + + - [ ] Scenario: Inexisting ignored schemas + * GIVEN config files with correct default schema location + * WHEN schema folder location is set to an invalid location (/doesNotExist ?) + * WHEN schema validation is disabled + * THEN start should succeed + + - [ ] Scenario: Inexisting used schemas + * GIVEN config files with custom schema location (./shemaCustomFolderName) + * WHEN schema folder location is set to the custom shema location + * WHEN schema validation is enabled + * THEN start should succeed + + - [ ] Scenario: Schema OK, config KO + * GIVEN incorect config files with correct default schema location + * WHEN schema validation is enabled + * THEN start should fail + +### Error cases/special cases + +- invalid configuration or a file can't be read: + - [X] Scenario: invalid top level config file + * GIVEN an incorect (empty ? wrong balisa ?) config top level file. + * THEN start should fail + + - [X] Scenario: invalid structure + * GIVEN an incorect (empty ? wrong balisa ?) structure file. + * THEN start should fail + + - [X] Scenario: invalid settings + * GIVEN an incorect (empty ? wrong balisa ?) settings file. + * THEN start should fail + +- plugins can't be found (unless silenced by the user) + - Done in "failure on missing subsystem" + +- usage of `<xi:include .../>` + - [ ] Scenario: Arbitrary xincluded node + * GIVEN a top level file xincluding a file with the "SettingsConfiguration" balisa + * THEN start should succeed + +- plugins: + - non-empty "Location" attribute + - [ ] Scenario: Plugin location OK + * GIVEN a top level file with a plugin folder location attribute + * THEN start should succeed + - empty "Location" attribute + - relative path + - [ ] Scenario: Empty Location, standard plugin install + * GIVEN config files with an empty location attribute + * GIVEN a plugin installed in a dlopen standard path + * GIVEN that "Location/Plugin[name]" is the plugin name + * THEN start should succeed + + - [ ] Scenario: Empty Location, non standard plugin install + * GIVEN config files with an empty location attribute + * GIVEN a plugin NOT installed in a dlopen standard path + * GIVEN that "Location/Plugin[name]" is the plugin name + * THEN start should fail + + - absolute path + - [ ] Scenario: Empty Location, plugin absolute path + * GIVEN config files with an empty location attribute + * GIVEN a plugin + * GIVEN that "Location/Plugin[name]" is the plugin absolute path + * THEN start should succeed + + - [ ] Scenario: Empty Location, plugin non existing path + * GIVEN config files with an empty location attribute + * GIVEN that "Location/Plugin[name]" is an non existing path (/libDoesNotExist.so?) + * THEN start should fail + +* * * + +## Logging + +- info and warning + - Partly covered by the "set a logger" section + - [ ] Scenario: Plugin info and warning log + * GIVEN a plugin that log a unique string as info and warning + * GIVEN a logger that store logs + * WHEN the record logger is set + * THEN start should succeed + * AND_THEN the logger should have stored the plugin specific info and warning log + +* * * + +## Basic Domains & Configurations management + +- [ ] Scenario: create and delete an empty domain + * GIVEN a started parameter framework without domains + * THEN creating a domain with an arbitrary name ("domain1"?) should succeed + * (AND_THEN the domain list should contain the domain name) + * THEN deleting the domain should succeed + +- [ ] Scenario: create and delete a configuration + * GIVEN a started parameter framework with a domain + * THEN creating a configuration in this domain with an arbitrary name ("config1") should succeed + * (AND_THEN the domain configuration list should contain the configuration name) + * THEN deleting the configuration should succeed + * (AND_THEN the domain configuration list should not contain the configuration name) + +- [ ] Scenario: delete a domain with configurations + * GIVEN a started parameter framework with a domain and several configuration (3?) + * THEN deleting the domain should succeed + * (AND_THEN the domain list should not contain the domain name) + +- [ ] Scenario: delete all domains + * GIVEN a started parameter framework with several domains + * THEN deleting all domains should succeed + * (AND_THEN the domain list should be empty) + +- [ ] Scenario: rename a domain + * GIVEN a started parameter framework with a domain and several configuration (3?) + * THEN renaming the domain to an arbitrary name should succeed + + +### Error cases/special cases + +- [ ] Scenario: create a domain with an already-existing name + * GIVEN a started parameter framework with a domain (arbitrary name) + * THEN creating a second domain with the same name than the first should fail + +- [ ] Scenario: create a configuration with an already-existing name + * GIVEN a started parameter framework with a domain + containing one configuration (arbitrary name) + * THEN creating a second configuration in this domain + with the same name than the fist should fail + +- [ ] delete a non-existent domain + * GIVEN a started parameter framework without domain + * THEN deleting an arbitrary named domain should fail + +- [ ] delete a non-existent configuration + * GIVEN a started parameter framework one domain + * THEN deleting in this domain a arbitrary named configuration should fail + +- [ ] list configuration of a unknown domain + * GIVEN a started parameter framework without domain + * THEN listing configuration of an arbitrary named domain should fail + +- [ ] Scenario: rename a domain to an already used name + * GIVEN a started parameter framework with two domains + with arbitrary different names ("domain1" and "domain2") + * THEN renaming first domain ("domain1") to the name of the second one ("domain2") should fail + +- [ ] Scenario: rename a configuration to an already used name + * GIVEN a started parameter framework with one domain containing two configuration + with arbitrary different names ("config1" and "config2") + * THEN renaming first configuration ("config1") + to the name of the second one ("config2") should fail + +- [ ] Scenario: rename a domain to its own name + * GIVEN a started parameter framework one arbitrary named domain + * THEN renaming the domain to its own name should succeed + +- [ ] rename a configuration to its own name + * GIVEN a started parameter framework a domain and one configuration + * THEN renaming the configuration to its own name should succeed + +* * * + +## Domain modification + +- set/get sequence awareness +- add/list/remove elements to a domain +- *(split domain ?)* +- *(listBelongingDomains ?)* +- *(listAssociatedDomains ?)* +- *(listAssociatedElements ?)* +- *(listConflictingElements ?)* +- *(listRogueElements ?)* + +### Error cases/special cases + +- add (or remove) a non-existent element +- add (or remove) a parameter to (or from) a non-existent domain + +* * * + +## Configurations modification + +- set a configuration rule; get it back + - trivial rules, complex rules (fuzzing ?) + - clear a rule +- save/restore a configuration +- set/get element sequence +- set/get a parameter for a given configuration +- set a parameter belonging to a domain and save a configuration + +### Error cases + +- set a wrongly-formatted rule +- set a rule using an unknown criterion (or unknown criterion value) +- set/get a rule to a non-existent domain (or configuration) + +* * * + +## Criteria + +- create a criterion + - exclusive + - inclusive +- *(list criteria)* +- set a criterion; get a criterion value + - exclusive criterion + - inclusive criterion + - special case: "none" value + +### Error cases/special cases + +- duplicated criterion name (with the same type/with a different type) +- duplicated criterion value +- max supported number of criterion values + +* * * + +## Settings Import/Export + +- import xml domains + - w/ or w/o settings + - from a file/from a string + - all/single +- export xml domains + - w/ or w/o settings + - to a file/from a string + - all/single + +### Error case/special cases + +- invalid settings + - invalid xml (should we use a fuzzing framework ?) + - valid xml but not matching the XSD (ditto) + - valid but unusable data: + - unknown criterion/criterion values + - unknown parameters +- unreadable/unwritable file +- single domain import overwrite + - fail if overwrite not requested + - succeed if overwrite requested + +* * * + +## Parameters + +- structures are correctly instantiated + - parameters in the "instance definition" + - component types instantiation + - parameter blocks + - bit blocks + - arrays +- check parameter mappings are correctly applied + - at all levels possible (subsystem, component type, component instance, + block, parameter...) + - context mappings, amends, instantiation mappings +- set/get a parameter +- parameter handles +- test on parameter values + - booleans + - bit blocks + - numeric types ranges + - fixed-point tests + - string length + +* * * + +## Configuration application + +- apply configurations + - sequence aware domains +- forced sync + +* * * + +## Misc/to be classified + +- tuning mode +- auto sync +- remote interface instantiation +- value space (raw/real)/format (dec/hex) + +### Error cases + diff --git a/test/functional-tests/xml/configuration/Settings/Test/TestConfigurableDomains.xml b/test/functional-tests/xml/configuration/Settings/Test/TestConfigurableDomains.xml deleted file mode 100644 index fdc77e1..0000000 --- a/test/functional-tests/xml/configuration/Settings/Test/TestConfigurableDomains.xml +++ /dev/null @@ -1,141 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/home/lab/ICS/hardware/intel/PRIVATE/parameter-framework/test/configuration/Schemas/ConfigurableDomains.xsd" SystemClassName="Test"> - <ConfigurableDomain Name="Domain_0"> - <Configurations> - <Configuration Name="Conf_0"> - <CompoundRule Type="All"> - <SelectionCriterionRule SelectionCriterion="Crit_0" MatchesWhen="Includes" Value="State_0x1"/> - <SelectionCriterionRule SelectionCriterion="Crit_1" MatchesWhen="Is" Value="State_1"/> - </CompoundRule> - </Configuration> - <Configuration Name="Conf_1"> - <CompoundRule Type="Any"> - <SelectionCriterionRule SelectionCriterion="Crit_0" MatchesWhen="Includes" Value="State_0x2"/> - <SelectionCriterionRule SelectionCriterion="Crit_1" MatchesWhen="IsNot" Value="State_1"/> - </CompoundRule> - </Configuration> - </Configurations> - - <ConfigurableElements> - <ConfigurableElement Path="/Test/Test/TEST_DIR" /> - <ConfigurableElement Path="/Test/Test/TEST_TYPES" /> - </ConfigurableElements> - - <Settings> - <Configuration Name="Conf_0"> - <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> - <!-- Tested Booleans --> - <BooleanParameter Name="BOOL">0</BooleanParameter> - <!-- Tested FixedPoints --> - <FixedPointParameter Name="FP8_Q0.7">0</FixedPointParameter> - <FixedPointParameter Name="FP8_Q7.0">0</FixedPointParameter> - <FixedPointParameter Name="FP8_Q3.4">0</FixedPointParameter> - <FixedPointParameter Name="FP16_Q0.15">0</FixedPointParameter> - <FixedPointParameter Name="FP16_Q15.0">0</FixedPointParameter> - <FixedPointParameter Name="FP16_Q7.8">0</FixedPointParameter> - <FixedPointParameter Name="FP32_Q0.31">0</FixedPointParameter> - <FixedPointParameter Name="FP32_Q31.0">0</FixedPointParameter> - <FixedPointParameter Name="FP32_Q15.16">0</FixedPointParameter> - <FixedPointParameter Name="FP32_Q8.20">0</FixedPointParameter> - <!-- Tested Integers --> - <IntegerParameter Name="UINT32">0</IntegerParameter> - <IntegerParameter Name="INT32">0</IntegerParameter> - <IntegerParameter Name="UINT32_Max">0</IntegerParameter> - <IntegerParameter Name="INT32_Max">0</IntegerParameter> - <IntegerParameter Name="UINT16">0</IntegerParameter> - <IntegerParameter Name="INT16">0</IntegerParameter> - <IntegerParameter Name="UINT16_Max">0</IntegerParameter> - <IntegerParameter Name="INT16_Max">0</IntegerParameter> - <IntegerParameter Name="UINT8">0</IntegerParameter> - <IntegerParameter Name="INT8">0</IntegerParameter> - <IntegerParameter Name="UINT8_Max">0</IntegerParameter> - <IntegerParameter Name="INT8_Max">0</IntegerParameter> - <!-- Tested Arrays --> - <IntegerParameter Name="UINT32_ARRAY">0</IntegerParameter> - <IntegerParameter Name="INT16_ARRAY">0</IntegerParameter> - <IntegerParameter Name="UINT8_ARRAY">0</IntegerParameter> - <IntegerParameter Name="UINT8_Max_ARRAY">0</IntegerParameter> - <!-- Tested String--> - <StringParameter Name="STR_CHAR128">string_Conf_0</StringParameter> - </Component> - </ConfigurableElement> - <ConfigurableElement Path="/Test/Test/TEST_TYPES"> - <Component Name="TEST_TYPES"> - <EnumParameter Name="ENUM">ENUM_NOMINAL</EnumParameter> - <BitParameterBlock Name="BLOCK_8BIT"> - <BitParameter Name="BIT_0_3">0</BitParameter> - <BitParameter Name="BIT_3_1">0</BitParameter> - <BitParameter Name="BIT_4_1">0</BitParameter> - <BitParameter Name="BIT_6_2">0</BitParameter> - <BitParameter Name="BIT_7_1">0</BitParameter> - </BitParameterBlock> - <ParameterBlock Name="BLOCK_PARAMETER"> - <IntegerParameter Name="UINT8">0</IntegerParameter> - <IntegerParameter Name="UINT16">0</IntegerParameter> - <IntegerParameter Name="UINT32">0</IntegerParameter> - </ParameterBlock> - </Component> - </ConfigurableElement> - </Configuration> - <Configuration Name="Conf_1"> - <ConfigurableElement Path="/Test/Test/TEST_DIR"> - <Component Name="TEST_DIR"> - <!-- Tested Booleans --> - <BooleanParameter Name="BOOL">1</BooleanParameter> - <!-- Tested FixedPoints --> - <FixedPointParameter Name="FP8_Q0.7">0.9</FixedPointParameter> - <FixedPointParameter Name="FP8_Q7.0">1</FixedPointParameter> - <FixedPointParameter Name="FP8_Q3.4">1</FixedPointParameter> - <FixedPointParameter Name="FP16_Q0.15">0.9</FixedPointParameter> - <FixedPointParameter Name="FP16_Q15.0">1</FixedPointParameter> - <FixedPointParameter Name="FP16_Q7.8">1</FixedPointParameter> - <FixedPointParameter Name="FP32_Q0.31">0.9</FixedPointParameter> - <FixedPointParameter Name="FP32_Q31.0">1</FixedPointParameter> - <FixedPointParameter Name="FP32_Q15.16">1</FixedPointParameter> - <FixedPointParameter Name="FP32_Q8.20">1</FixedPointParameter> - <!-- Tested Integers --> - <IntegerParameter Name="UINT32">1</IntegerParameter> - <IntegerParameter Name="INT32">1</IntegerParameter> - <IntegerParameter Name="UINT32_Max">1</IntegerParameter> - <IntegerParameter Name="INT32_Max">1</IntegerParameter> - <IntegerParameter Name="UINT16">1</IntegerParameter> - <IntegerParameter Name="INT16">1</IntegerParameter> - <IntegerParameter Name="UINT16_Max">1</IntegerParameter> - <IntegerParameter Name="INT16_Max">1</IntegerParameter> - <IntegerParameter Name="UINT8">1</IntegerParameter> - <IntegerParameter Name="INT8">1</IntegerParameter> - <IntegerParameter Name="UINT8_Max">1</IntegerParameter> - <IntegerParameter Name="INT8_Max">1</IntegerParameter> - <!-- Tested Arrays --> - <IntegerParameter Name="UINT32_ARRAY">1</IntegerParameter> - <IntegerParameter Name="INT16_ARRAY">1</IntegerParameter> - <IntegerParameter Name="UINT8_ARRAY">1</IntegerParameter> - <IntegerParameter Name="UINT8_Max_ARRAY">1</IntegerParameter> - <!-- Tested String--> - <StringParameter Name="STR_CHAR128">string_Conf_1</StringParameter> - </Component> - </ConfigurableElement> - <ConfigurableElement Path="/Test/Test/TEST_TYPES"> - <Component Name="TEST_TYPES"> - <!--Tested Enum--> - <EnumParameter Name="ENUM">ENUM_MIN</EnumParameter> - <!--Tested Bit parameter block--> - <BitParameterBlock Name="BLOCK_8BIT"> - <BitParameter Name="BIT_0_3">0</BitParameter> - <BitParameter Name="BIT_3_1">0</BitParameter> - <BitParameter Name="BIT_4_1">0</BitParameter> - <BitParameter Name="BIT_6_2">0</BitParameter> - <BitParameter Name="BIT_7_1">0</BitParameter> - </BitParameterBlock> - <ParameterBlock Name="BLOCK_PARAMETER"> - <IntegerParameter Name="UINT8">0</IntegerParameter> - <IntegerParameter Name="UINT16">0</IntegerParameter> - <IntegerParameter Name="UINT32">0</IntegerParameter> - </ParameterBlock> - </Component> - </ConfigurableElement> - </Configuration> - </Settings> - </ConfigurableDomain> -</ConfigurableDomains> diff --git a/test/introspection-subsystem/CMakeLists.txt b/test/introspection-subsystem/CMakeLists.txt new file mode 100644 index 0000000..faccab3 --- /dev/null +++ b/test/introspection-subsystem/CMakeLists.txt @@ -0,0 +1,58 @@ +# 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. + +# The introspection-subsystem provides ability to retrieve +# a boolean parameter value set by the parameter-framework +# at subsystem level. +# +# To get the boolean value, include the "IntrospectionEntryPoint.h" +# header and use the getParameterValue() function. + + +if (BUILD_TESTING) + add_library(introspection-subsystem SHARED + IntrospectionSubsystem.cpp + IntrospectionSubsystemObject.cpp + IntrospectionSubsystemBuilder.cpp + IntrospectionEntryPoint.cpp) + + # generating header used to export shared library symbols + include(GenerateExportHeader) + generate_export_header(introspection-subsystem + BASE_NAME introspection_subsystem) + + # exporting public headers: + # - the header that contains the introspection function + # - the header generated by cmake used to export symbols in shared library. + # + # Note : headers located in root project directory remain private. + target_include_directories(introspection-subsystem + PUBLIC "include" "${CMAKE_CURRENT_BINARY_DIR}") + + target_link_libraries(introspection-subsystem PRIVATE parameter) +endif() diff --git a/remote-processor/RemoteProcessorServerBuilder.cpp b/test/introspection-subsystem/IntrospectionEntryPoint.cpp index 2bd9216..b26e938 100644 --- a/remote-processor/RemoteProcessorServerBuilder.cpp +++ b/test/introspection-subsystem/IntrospectionEntryPoint.cpp @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2014, Intel Corporation +/* + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,14 +27,18 @@ * (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 "RemoteProcessorServer.h" +#include "IntrospectionEntryPoint.h" +#include "IntrospectionSubsystemObject.h" -extern "C" +namespace parameterFramework { -IRemoteProcessorServerInterface* createRemoteProcessorServer(uint16_t uiPort, IRemoteCommandHandler* pCommandHandler) +namespace introspectionSubsystem { - return new CRemoteProcessorServer(uiPort, pCommandHandler); + +bool getParameterValue() +{ + return SubsystemObject::getSingletonInstanceValue(); +} } } - diff --git a/parameter/ErrorContext.cpp b/test/introspection-subsystem/IntrospectionSubsystem.cpp index e9c0b43..7c3e945 100644 --- a/parameter/ErrorContext.cpp +++ b/test/introspection-subsystem/IntrospectionSubsystem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,25 +27,19 @@ * (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 "ErrorContext.h" -CErrorContext::CErrorContext(std::string& strError) : _strError(strError) -{ -} +#include "IntrospectionSubsystem.h" +#include "IntrospectionSubsystemObject.h" +#include <SubsystemObjectFactory.h> -// Error -void CErrorContext::setError(const std::string& strError) +namespace parameterFramework { - _strError = strError; -} - -void CErrorContext::appendToError(const std::string& strAppend) +namespace introspectionSubsystem { - _strError += strAppend; -} -const std::string& CErrorContext::getError() const +Subsystem::Subsystem(const std::string &name, core::log::Logger &logger) : base(name, logger) { - return _strError; + addSubsystemObjectFactory(new TSubsystemObjectFactory<SubsystemObject>("Object", 0)); +} +} } - diff --git a/test/introspection-subsystem/IntrospectionSubsystem.h b/test/introspection-subsystem/IntrospectionSubsystem.h new file mode 100644 index 0000000..1f89841 --- /dev/null +++ b/test/introspection-subsystem/IntrospectionSubsystem.h @@ -0,0 +1,50 @@ +/* + * 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. + */ +#pragma once + +#include <Subsystem.h> + +namespace parameterFramework +{ +namespace introspectionSubsystem +{ + +/** This subsystem allows to retrieve parameter value set by the + * parameter-framework */ +class Subsystem : public CSubsystem +{ +public: + Subsystem(const std::string &name, core::log::Logger &logger); + +private: + using base = CSubsystem; +}; +} +} diff --git a/test/introspection-subsystem/IntrospectionSubsystemBuilder.cpp b/test/introspection-subsystem/IntrospectionSubsystemBuilder.cpp new file mode 100644 index 0000000..23c7134 --- /dev/null +++ b/test/introspection-subsystem/IntrospectionSubsystemBuilder.cpp @@ -0,0 +1,40 @@ +/* + * 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 <Plugin.h> +#include <LoggingElementBuilderTemplate.h> +#include "IntrospectionSubsystem.h" + +void PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1(CSubsystemLibrary *subsystemLibrary, + core::log::Logger &logger) +{ + using Subsystem = parameterFramework::introspectionSubsystem::Subsystem; + subsystemLibrary->addElementBuilder("INTROSPECTION", + new TLoggingElementBuilderTemplate<Subsystem>(logger)); +} diff --git a/test/introspection-subsystem/IntrospectionSubsystemObject.cpp b/test/introspection-subsystem/IntrospectionSubsystemObject.cpp new file mode 100644 index 0000000..2a05981 --- /dev/null +++ b/test/introspection-subsystem/IntrospectionSubsystemObject.cpp @@ -0,0 +1,83 @@ +/* + * 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 "IntrospectionSubsystemObject.h" +#include <InstanceConfigurableElement.h> +#include <ParameterType.h> + +namespace parameterFramework +{ +namespace introspectionSubsystem +{ + +const SubsystemObject *SubsystemObject::mSingletonInstance = nullptr; + +/* Helper function */ +const CParameterType *geParameterType(CInstanceConfigurableElement *element) +{ + return static_cast<const CParameterType *>(element->getTypeElement()); +} + +SubsystemObject::SubsystemObject(const std::string & /*mappingValue*/, + CInstanceConfigurableElement *instanceConfigurableElement, + const CMappingContext & /*context*/, core::log::Logger &logger) + : base(instanceConfigurableElement, logger), mParameter(false) +{ + /* Checking that structure matches the internal parameter */ + ALWAYS_ASSERT(geParameterType(instanceConfigurableElement)->getSize() == parameterSize, + "Wrong parameter size"); + ALWAYS_ASSERT((instanceConfigurableElement->getFootPrint() / parameterSize) == 1, + "Parameter shall not be an array"); + ALWAYS_ASSERT(geParameterType(instanceConfigurableElement)->isScalar(), + "Parameter shall be scalar"); + + /* Registering the instance into a singleton */ + registerInstance(*this); +} + +SubsystemObject::~SubsystemObject() +{ + /* Unregistering the instance from the singleton */ + unregisterInstance(*this); +} + +bool SubsystemObject::sendToHW(std::string & /*error*/) +{ + blackboardRead(&mParameter, parameterSize); + return true; +} + +bool SubsystemObject::receiveFromHW(std::string & /*error*/) +{ + blackboardRead(&mParameter, parameterSize); + return true; +} +} +} diff --git a/test/introspection-subsystem/IntrospectionSubsystemObject.h b/test/introspection-subsystem/IntrospectionSubsystemObject.h new file mode 100644 index 0000000..f91f686 --- /dev/null +++ b/test/introspection-subsystem/IntrospectionSubsystemObject.h @@ -0,0 +1,89 @@ +/* + * 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. + */ +#pragma once + +#include <SubsystemObject.h> +#include <AlwaysAssert.hpp> +#include <string> + +class CMappingContext; + +namespace parameterFramework +{ +namespace introspectionSubsystem +{ + +/** This subsystem object exposes a boolean parameter. The value of this parameter + * can be retrieved by an external code that calls the getSingletonInstanceValue() + * static method. + */ +class SubsystemObject final : public CSubsystemObject +{ +public: + SubsystemObject(const std::string &mappingValue, + CInstanceConfigurableElement *instanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger); + ~SubsystemObject(); + + static bool getSingletonInstanceValue() + { + ALWAYS_ASSERT(mSingletonInstance != nullptr, "Singleton value has not been registered"); + return mSingletonInstance->mParameter; + } + +private: + using base = CSubsystemObject; + + virtual bool sendToHW(std::string &error) override; + virtual bool receiveFromHW(std::string &error) override; + + static void registerInstance(const SubsystemObject &instance) + { + ALWAYS_ASSERT(mSingletonInstance == nullptr, "An instance is already registered"); + mSingletonInstance = &instance; + } + + static void unregisterInstance(const SubsystemObject &instance) + { + // instance parameter is only used by assertion, so unused in release mode + (void)instance; + + ALWAYS_ASSERT(mSingletonInstance == &instance, "This instance was not registered."); + mSingletonInstance = nullptr; + } + + static const std::size_t parameterSize = sizeof(bool); + + static const SubsystemObject *mSingletonInstance; + + bool mParameter; +}; +} +} diff --git a/remote-processor/RemoteProcessorProtocol.h b/test/introspection-subsystem/include/IntrospectionEntryPoint.h index bdb054b..ce3e22c 100644 --- a/remote-processor/RemoteProcessorProtocol.h +++ b/test/introspection-subsystem/include/IntrospectionEntryPoint.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2014, Intel Corporation +/* + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,11 +29,13 @@ */ #pragma once -#define SYNC_WORD 0xBABE +#include "introspection_subsystem_export.h" -enum RemoteProtocolMsgType +namespace parameterFramework { - ECommandRequest, - ESuccessAnswer, - EFailureAnswer -}; +namespace introspectionSubsystem +{ + +INTROSPECTION_SUBSYSTEM_EXPORT bool getParameterValue(); +} +} diff --git a/test/test-fixed-point-parameter/CMakeLists.txt b/test/test-fixed-point-parameter/CMakeLists.txt index 64b51f3..1b1e0e0 100644 --- a/test/test-fixed-point-parameter/CMakeLists.txt +++ b/test/test-fixed-point-parameter/CMakeLists.txt @@ -26,12 +26,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -if (BUILD_TESTING) - find_program(python2 python2) +if(BUILD_TESTING AND PYTHON_BINDINGS) + find_package(PythonInterp 2.7 REQUIRED) add_test(NAME fix_point_parameter WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND ${python2} Main.py) + COMMAND ${PYTHON_EXECUTABLE} Main.py) # Custom function defined in the top-level CMakeLists set_test_env(fix_point_parameter) diff --git a/test/test-fixed-point-parameter/Main.py b/test/test-fixed-point-parameter/Main.py index 6d7b292..31e10a5 100755 --- a/test/test-fixed-point-parameter/Main.py +++ b/test/test-fixed-point-parameter/Main.py @@ -39,9 +39,11 @@ class PfwLogger(PyPfw.ILogger): super(PfwLogger, self).__init__() self.__logger = logging.root.getChild("parameter-framework") - def log(self, is_warning, message): - log_func = self.__logger.warning if is_warning else self.__logger.info - log_func(message) + def info(self, message): + self.__logger.info(message) + + def warning(self, message): + self.__logger.warning(message) class FixedPointTester(): """ Made for testing a particular Qn.m number diff --git a/test/test-fixed-point-parameter/Schemas b/test/test-fixed-point-parameter/Schemas deleted file mode 120000 index 6b039cb..0000000 --- a/test/test-fixed-point-parameter/Schemas +++ /dev/null @@ -1 +0,0 @@ -../../Schemas/
\ No newline at end of file diff --git a/test/test-fixed-point-parameter/VirtualSubsystem.xml b/test/test-fixed-point-parameter/VirtualSubsystem.xml index b4a7a5f..dca7bb5 100644 --- a/test/test-fixed-point-parameter/VirtualSubsystem.xml +++ b/test/test-fixed-point-parameter/VirtualSubsystem.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<Subsystem Name="test" Type="Virtual" Endianness="Little"> +<Subsystem Name="test" Type="Virtual"> <ComponentLibrary> </ComponentLibrary> <InstanceDefinition> diff --git a/test/test-platform/CMakeLists.txt b/test/test-platform/CMakeLists.txt index b824057..533de3c 100644 --- a/test/test-platform/CMakeLists.txt +++ b/test/test-platform/CMakeLists.txt @@ -26,18 +26,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_executable(test-platform - main.cpp - TestPlatform.cpp) +if(NETWORKING) + add_executable(test-platform + main.cpp + TestPlatform.cpp) -# FIXME: Supress the need for the -Wno-unused-parameter -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter") + target_link_libraries(test-platform + PRIVATE parameter pfw_utility remote-processor) + # Workaround because asio is still leaking to test-platform + target_link_libraries(test-platform PRIVATE asio) -include_directories( - "${PROJECT_SOURCE_DIR}/parameter/include" - "${PROJECT_SOURCE_DIR}/remote-processor" - "${PROJECT_SOURCE_DIR}/utility") - -target_link_libraries(test-platform parameter remote-processor) - -install(TARGETS test-platform RUNTIME DESTINATION bin) + install(TARGETS test-platform RUNTIME DESTINATION bin) +endif() diff --git a/test/test-platform/TestPlatform.cpp b/test/test-platform/TestPlatform.cpp index 6e67b3a..e022131 100644 --- a/test/test-platform/TestPlatform.cpp +++ b/test/test-platform/TestPlatform.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -28,8 +28,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <strings.h> -#include <iostream> #include <stdlib.h> #include <sstream> #include <assert.h> @@ -37,230 +35,201 @@ #include <convert.hpp> #include <sstream> #include "TestPlatform.h" -#include "ParameterMgrPlatformConnector.h" -#include "RemoteProcessorServer.h" using std::string; -class CParameterMgrPlatformConnectorLogger : public CParameterMgrPlatformConnector::ILogger +CTestPlatform::CTestPlatform(const string &strClass, uint16_t iPortNumber) + : mParameterMgrPlatformConnector(strClass), mLogger(), mRemoteProcessorServer(iPortNumber) { -public: - CParameterMgrPlatformConnectorLogger() {} + mParameterMgrPlatformConnector.setLogger(&mLogger); +} - virtual void log(bool bIsWarning, const string& strLog) - { +CTestPlatform::~CTestPlatform() +{ +} - if (bIsWarning) { +CTestPlatform::CommandReturn CTestPlatform::exit(const IRemoteCommand & /*command*/, + string & /*strResult*/) +{ + mRemoteProcessorServer.stop(); - std::cerr << strLog << std::endl; - } else { + return CTestPlatform::CCommandHandler::EDone; +} - std::cout << strLog << std::endl; - } +bool CTestPlatform::run(std::string &strError) +{ + // Start remote processor server + if (!mRemoteProcessorServer.start(strError)) { + + strError = "TestPlatform: Unable to start remote processor server: " + strError; + return false; } -}; -CTestPlatform::CTestPlatform(const string& strClass, int iPortNumber, sem_t& exitSemaphore) : - _pParameterMgrPlatformConnector(new CParameterMgrPlatformConnector(strClass)), - _pParameterMgrPlatformConnectorLogger(new CParameterMgrPlatformConnectorLogger), - _exitSemaphore(exitSemaphore) -{ - _pCommandHandler = new CCommandHandler(this); + CCommandHandler commandHandler(this); // Add command parsers - _pCommandHandler->addCommandParser("exit", &CTestPlatform::exit, - 0, "", "Exit TestPlatform"); - _pCommandHandler->addCommandParser( - "createExclusiveSelectionCriterionFromStateList", - &CTestPlatform::createExclusiveSelectionCriterionFromStateList, - 2, "<name> <stateList>", - "Create inclusive selection criterion from state name list"); - _pCommandHandler->addCommandParser( - "createInclusiveSelectionCriterionFromStateList", - &CTestPlatform::createInclusiveSelectionCriterionFromStateList, - 2, "<name> <stateList>", - "Create exclusive selection criterion from state name list"); - - _pCommandHandler->addCommandParser( - "createExclusiveSelectionCriterion", - &CTestPlatform::createExclusiveSelectionCriterion, - 2, "<name> <nbStates>", "Create inclusive selection criterion"); - _pCommandHandler->addCommandParser( - "createInclusiveSelectionCriterion", - &CTestPlatform::createInclusiveSelectionCriterion, - 2, "<name> <nbStates>", "Create exclusive selection criterion"); - - _pCommandHandler->addCommandParser("start", &CTestPlatform::startParameterMgr, - 0, "", "Start ParameterMgr"); - - _pCommandHandler->addCommandParser("setCriterionState", &CTestPlatform::setCriterionState, - 2, "<name> <state>", - "Set the current state of a selection criterion"); - _pCommandHandler->addCommandParser( - "applyConfigurations", - &CTestPlatform::applyConfigurations, - 0, "", "Apply configurations selected by current selection criteria states"); - - _pCommandHandler->addCommandParser( + commandHandler.addCommandParser("exit", &CTestPlatform::exit, 0, "", "Exit TestPlatform"); + commandHandler.addCommandParser("createExclusiveSelectionCriterionFromStateList", + &CTestPlatform::createExclusiveSelectionCriterionFromStateList, + 2, "<name> <stateList>", + "Create inclusive selection criterion from state name list"); + commandHandler.addCommandParser("createInclusiveSelectionCriterionFromStateList", + &CTestPlatform::createInclusiveSelectionCriterionFromStateList, + 2, "<name> <stateList>", + "Create exclusive selection criterion from state name list"); + + commandHandler.addCommandParser("createExclusiveSelectionCriterion", + &CTestPlatform::createExclusiveSelectionCriterion, 2, + "<name> <nbStates>", "Create inclusive selection criterion"); + commandHandler.addCommandParser("createInclusiveSelectionCriterion", + &CTestPlatform::createInclusiveSelectionCriterion, 2, + "<name> <nbStates>", "Create exclusive selection criterion"); + + commandHandler.addCommandParser("start", &CTestPlatform::startParameterMgr, 0, "", + "Start ParameterMgr"); + + commandHandler.addCommandParser("setCriterionState", &CTestPlatform::setCriterionState, 2, + "<name> <state>", + "Set the current state of a selection criterion"); + commandHandler.addCommandParser( + "applyConfigurations", &CTestPlatform::applyConfigurations, 0, "", + "Apply configurations selected by current selection criteria states"); + + commandHandler.addCommandParser( "setFailureOnMissingSubsystem", - &CTestPlatform::setter<& CParameterMgrPlatformConnector::setFailureOnMissingSubsystem>, - 1, "true|false", "Set policy for missing subsystems, " - "either abort start or fallback on virtual subsystem."); - _pCommandHandler->addCommandParser( + &CTestPlatform::setter<&CParameterMgrPlatformConnector::setFailureOnMissingSubsystem>, 1, + "true|false", "Set policy for missing subsystems, " + "either abort start or fallback on virtual subsystem."); + commandHandler.addCommandParser( "getMissingSubsystemPolicy", - &CTestPlatform::getter<& CParameterMgrPlatformConnector::getFailureOnMissingSubsystem>, - 0, "", "Get policy for missing subsystems, " - "either abort start or fallback on virtual subsystem."); + &CTestPlatform::getter<&CParameterMgrPlatformConnector::getFailureOnMissingSubsystem>, 0, + "", "Get policy for missing subsystems, " + "either abort start or fallback on virtual subsystem."); - _pCommandHandler->addCommandParser( + commandHandler.addCommandParser( "setFailureOnFailedSettingsLoad", - &CTestPlatform::setter<& CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad>, - 1, "true|false", + &CTestPlatform::setter<&CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad>, 1, + "true|false", "Set policy for failed settings load, either abort start or continue without domains."); - _pCommandHandler->addCommandParser( + commandHandler.addCommandParser( "getFailedSettingsLoadPolicy", - &CTestPlatform::getter<& CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad>, - 0, "", - "Get policy for failed settings load, either abort start or continue without domains."); + &CTestPlatform::getter<&CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad>, 0, + "", "Get policy for failed settings load, either abort start or continue without domains."); - _pCommandHandler->addCommandParser( + commandHandler.addCommandParser( "setValidateSchemasOnStart", - &CTestPlatform::setter<& CParameterMgrPlatformConnector::setValidateSchemasOnStart>, - 1, "true|false", - "Set policy for schema validation based on .xsd files (false by default)."); - _pCommandHandler->addCommandParser( + &CTestPlatform::setter<&CParameterMgrPlatformConnector::setValidateSchemasOnStart>, 1, + "true|false", "Set policy for schema validation based on .xsd files (false by default)."); + commandHandler.addCommandParser( "getValidateSchemasOnStart", - &CTestPlatform::getter<& CParameterMgrPlatformConnector::getValidateSchemasOnStart>, - 0, "", + &CTestPlatform::getter<&CParameterMgrPlatformConnector::getValidateSchemasOnStart>, 0, "", "Get policy for schema validation based on .xsd files."); - // Create server - _pRemoteProcessorServer = new CRemoteProcessorServer(iPortNumber, _pCommandHandler); - - _pParameterMgrPlatformConnector->setLogger(_pParameterMgrPlatformConnectorLogger); -} - -CTestPlatform::~CTestPlatform() -{ - delete _pRemoteProcessorServer; - delete _pCommandHandler; - delete _pParameterMgrPlatformConnectorLogger; - delete _pParameterMgrPlatformConnector; -} - -CTestPlatform::CommandReturn CTestPlatform::exit( - const IRemoteCommand& remoteCommand, string& strResult) -{ - (void)remoteCommand; - - // Release the main blocking semaphore to quit application - sem_post(&_exitSemaphore); - - return CTestPlatform::CCommandHandler::EDone; -} - -bool CTestPlatform::load(std::string& strError) -{ - // Start remote processor server - if (!_pRemoteProcessorServer->start(strError)) { - - strError = "TestPlatform: Unable to start remote processor server: " + strError; - return false; - } + commandHandler.addCommandParser("getSchemaUri", &CTestPlatform::getSchemaUri, 0, "", + "Get the directory where schemas can be found."); + commandHandler.addCommandParser("setSchemaUri", &CTestPlatform::setSchemaUri, 1, "<directory>", + "Set the directory where schemas can be found."); - return true; + return mRemoteProcessorServer.process(commandHandler); } //////////////// Remote command parsers /// Selection Criterion CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterionFromStateList( - const IRemoteCommand& remoteCommand, string& strResult) + const IRemoteCommand &remoteCommand, string &strResult) { - return createExclusiveSelectionCriterionFromStateList( - remoteCommand.getArgument(0), remoteCommand, strResult) ? - CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; + return createExclusiveSelectionCriterionFromStateList(remoteCommand.getArgument(0), + remoteCommand, strResult) + ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterionFromStateList( - const IRemoteCommand& remoteCommand, string& strResult) + const IRemoteCommand &remoteCommand, string &strResult) { - return createInclusiveSelectionCriterionFromStateList( - remoteCommand.getArgument(0), remoteCommand, strResult) ? - CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; + return createInclusiveSelectionCriterionFromStateList(remoteCommand.getArgument(0), + remoteCommand, strResult) + ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterion( - const IRemoteCommand& remoteCommand, string& strResult) + const IRemoteCommand &remoteCommand, string &strResult) { - return createExclusiveSelectionCriterion( - remoteCommand.getArgument(0), - strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), - strResult) ? - CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; + return createExclusiveSelectionCriterion(remoteCommand.getArgument(0), + strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), + strResult) + ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterion( - const IRemoteCommand& remoteCommand, string& strResult) + const IRemoteCommand &remoteCommand, string &strResult) { - return createInclusiveSelectionCriterion( - remoteCommand.getArgument(0), - strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), - strResult) ? - CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; + return createInclusiveSelectionCriterion(remoteCommand.getArgument(0), + strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), + strResult) + ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } CTestPlatform::CommandReturn CTestPlatform::startParameterMgr( - const IRemoteCommand& remoteCommand, string& strResult) + const IRemoteCommand & /*remoteCommand*/, string &strResult) { - (void)remoteCommand; - - return _pParameterMgrPlatformConnector->start(strResult) ? - CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; + return mParameterMgrPlatformConnector.start(strResult) + ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } template <CTestPlatform::setter_t setFunction> -CTestPlatform::CommandReturn CTestPlatform::setter( - const IRemoteCommand& remoteCommand, string& strResult) +CTestPlatform::CommandReturn CTestPlatform::setter(const IRemoteCommand &remoteCommand, + string &strResult) { - const string& strAbort = remoteCommand.getArgument(0); + const string &strAbort = remoteCommand.getArgument(0); bool bFail; - if(!convertTo(strAbort, bFail)) { + if (!convertTo(strAbort, bFail)) { return CTestPlatform::CCommandHandler::EShowUsage; } - return (_pParameterMgrPlatformConnector->*setFunction)(bFail, strResult) ? - CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; + return (mParameterMgrPlatformConnector.*setFunction)(bFail, strResult) + ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } template <CTestPlatform::getter_t getFunction> -CTestPlatform::CommandReturn CTestPlatform::getter( - const IRemoteCommand& remoteCommand, string& strResult) +CTestPlatform::CommandReturn CTestPlatform::getter(const IRemoteCommand & /*command*/, + string &strResult) { - (void)remoteCommand; - - strResult = (_pParameterMgrPlatformConnector->*getFunction)() ? "true" : "false"; + strResult = (mParameterMgrPlatformConnector.*getFunction)() ? "true" : "false"; return CTestPlatform::CCommandHandler::ESucceeded; } -CTestPlatform::CommandReturn CTestPlatform::setCriterionState( - const IRemoteCommand& remoteCommand, string& strResult) +CTestPlatform::CommandReturn CTestPlatform::getSchemaUri(const IRemoteCommand & /*remotecommand*/, + string &result) { + result = mParameterMgrPlatformConnector.getSchemaUri(); + return CTestPlatform::CCommandHandler::EDone; +} - bool bSuccess; - - const char* pcState = remoteCommand.getArgument(1).c_str(); +CTestPlatform::CommandReturn CTestPlatform::setSchemaUri(const IRemoteCommand &remotecommand, + string & /*result*/) +{ + mParameterMgrPlatformConnector.setSchemaUri(remotecommand.getArgument(0)); + return CTestPlatform::CCommandHandler::EDone; +} - char* pcStrEnd; +CTestPlatform::CommandReturn CTestPlatform::setCriterionState(const IRemoteCommand &remoteCommand, + string &strResult) +{ - // Reset errno to check if it is updated during the conversion (strtol/strtoul) - errno = 0; + bool bSuccess; - uint32_t state = strtoul(pcState, &pcStrEnd, 0); + uint32_t state; - if (!errno && (*pcStrEnd == '\0')) { + if (convertTo(remoteCommand.getArgument(1), state)) { // Sucessfull conversion, set criterion state by numerical state bSuccess = setCriterionState(remoteCommand.getArgument(0), state, strResult); @@ -269,18 +238,14 @@ CTestPlatform::CommandReturn CTestPlatform::setCriterionState( bSuccess = setCriterionStateByLexicalSpace(remoteCommand, strResult); } - return bSuccess ? CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler:: - EFailed; - + return bSuccess ? CTestPlatform::CCommandHandler::EDone + : CTestPlatform::CCommandHandler::EFailed; } -CTestPlatform::CommandReturn CTestPlatform::applyConfigurations(const IRemoteCommand& remoteCommand, - string& strResult) +CTestPlatform::CommandReturn CTestPlatform::applyConfigurations(const IRemoteCommand & /*command*/, + string & /*strResult*/) { - (void)remoteCommand; - (void)strResult; - - _pParameterMgrPlatformConnector->applyConfigurations(); + mParameterMgrPlatformConnector.applyConfigurations(); return CTestPlatform::CCommandHandler::EDone; } @@ -288,148 +253,117 @@ CTestPlatform::CommandReturn CTestPlatform::applyConfigurations(const IRemoteCom //////////////// Remote command handlers bool CTestPlatform::createExclusiveSelectionCriterionFromStateList( - const string& strName, - const IRemoteCommand& remoteCommand, - string& strResult) + const string &strName, const IRemoteCommand &remoteCommand, string &strResult) { - - assert(_pParameterMgrPlatformConnector != NULL); - - ISelectionCriterionTypeInterface* pCriterionType = - _pParameterMgrPlatformConnector->createSelectionCriterionType(false); + ISelectionCriterionTypeInterface *pCriterionType = + mParameterMgrPlatformConnector.createSelectionCriterionType(false); assert(pCriterionType != NULL); - uint32_t uiNbStates = remoteCommand.getArgumentCount() - 1; - uint32_t uiState; + size_t nbStates = remoteCommand.getArgumentCount() - 1; - for (uiState = 0; uiState < uiNbStates; uiState++) { + for (size_t state = 0; state < nbStates; state++) { - const std::string& strValue = remoteCommand.getArgument(uiState + 1); + const std::string &strValue = remoteCommand.getArgument(state + 1); - if (!pCriterionType->addValuePair(uiState, strValue)) { + // FIXME state type vs addValuePair params + if (!pCriterionType->addValuePair(int(state), strValue, strResult)) { - strResult = "Unable to add value: " + strValue; + strResult = "Unable to add value: " + strValue + ": " + strResult; return false; } } - _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); + mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType); return true; } bool CTestPlatform::createInclusiveSelectionCriterionFromStateList( - const string& strName, - const IRemoteCommand& remoteCommand, - string& strResult) + const string &strName, const IRemoteCommand &remoteCommand, string &strResult) { - assert(_pParameterMgrPlatformConnector != NULL); - - ISelectionCriterionTypeInterface* pCriterionType = - _pParameterMgrPlatformConnector->createSelectionCriterionType(true); + ISelectionCriterionTypeInterface *pCriterionType = + mParameterMgrPlatformConnector.createSelectionCriterionType(true); assert(pCriterionType != NULL); - uint32_t uiNbStates = remoteCommand.getArgumentCount() - 1; - - if (uiNbStates > 32) { - - strResult = "Maximum number of states for inclusive criterion is 32"; - - return false; - } - - uint32_t uiState; + size_t nbStates = remoteCommand.getArgumentCount() - 1; - for (uiState = 0; uiState < uiNbStates; uiState++) { + for (size_t state = 0; state < nbStates; state++) { - const std::string& strValue = remoteCommand.getArgument(uiState + 1); + const std::string &strValue = remoteCommand.getArgument(state + 1); - if (!pCriterionType->addValuePair(0x1 << uiState, strValue)) { + if (!pCriterionType->addValuePair(0x1 << state, strValue, strResult)) { - strResult = "Unable to add value: " + strValue; + strResult = "Unable to add value: " + strValue + ": " + strResult; return false; } } - _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); + mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType); return true; } - -bool CTestPlatform::createExclusiveSelectionCriterion(const string& strName, - uint32_t uiNbStates, - string& strResult) +bool CTestPlatform::createExclusiveSelectionCriterion(const string &strName, size_t nbStates, + string &strResult) { - ISelectionCriterionTypeInterface* pCriterionType = - _pParameterMgrPlatformConnector->createSelectionCriterionType(false); - - uint32_t uistate; + ISelectionCriterionTypeInterface *pCriterionType = + mParameterMgrPlatformConnector.createSelectionCriterionType(false); - for (uistate = 0; uistate < uiNbStates; uistate++) { + for (size_t state = 0; state < nbStates; state++) { - std::ostringstream ostrValue; + std::ostringstream ostrValue; ostrValue << "State_"; - ostrValue << uistate; + ostrValue << state; - if (!pCriterionType->addValuePair(uistate, ostrValue.str())) { + // FIXME state type vs addValuePair params + if (!pCriterionType->addValuePair(int(state), ostrValue.str(), strResult)) { - strResult = "Unable to add value: " + ostrValue.str(); + strResult = "Unable to add value: " + ostrValue.str() + ": " + strResult; return false; } } - _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); + mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType); return true; } -bool CTestPlatform::createInclusiveSelectionCriterion(const string& strName, - uint32_t uiNbStates, - string& strResult) +bool CTestPlatform::createInclusiveSelectionCriterion(const string &strName, size_t nbStates, + string &strResult) { - ISelectionCriterionTypeInterface* pCriterionType = - _pParameterMgrPlatformConnector->createSelectionCriterionType(true); - - if (uiNbStates > 32) { - - strResult = "Maximum number of states for inclusive criterion is 32"; - - return false; - } - - uint32_t uiState; + ISelectionCriterionTypeInterface *pCriterionType = + mParameterMgrPlatformConnector.createSelectionCriterionType(true); - for (uiState = 0; uiState < uiNbStates; uiState++) { + for (size_t state = 0; state < nbStates; state++) { - std::ostringstream ostrValue; + std::ostringstream ostrValue; ostrValue << "State_0x"; - ostrValue << (0x1 << uiState); + ostrValue << (0x1 << state); - if (!pCriterionType->addValuePair(0x1 << uiState, ostrValue.str())) { + if (!pCriterionType->addValuePair(0x1 << state, ostrValue.str(), strResult)) { - strResult = "Unable to add value: " + ostrValue.str(); + strResult = "Unable to add value: " + ostrValue.str() + ": " + strResult; return false; } } - _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); + mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType); return true; } -bool CTestPlatform::setCriterionState(const string& strName, uint32_t uiState, string& strResult) +bool CTestPlatform::setCriterionState(const string &strName, uint32_t uiState, string &strResult) { - ISelectionCriterionInterface* pCriterion = - _pParameterMgrPlatformConnector->getSelectionCriterion(strName); + ISelectionCriterionInterface *pCriterion = + mParameterMgrPlatformConnector.getSelectionCriterion(strName); if (!pCriterion) { @@ -443,15 +377,15 @@ bool CTestPlatform::setCriterionState(const string& strName, uint32_t uiState, s return true; } -bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand& remoteCommand, - string& strResult) +bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand &remoteCommand, + string &strResult) { // Get criterion name std::string strCriterionName = remoteCommand.getArgument(0); - ISelectionCriterionInterface* pCriterion = - _pParameterMgrPlatformConnector->getSelectionCriterion(strCriterionName); + ISelectionCriterionInterface *pCriterion = + mParameterMgrPlatformConnector.getSelectionCriterion(strCriterionName); if (!pCriterion) { @@ -461,13 +395,13 @@ bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand& remote } // Get criterion type - const ISelectionCriterionTypeInterface* pCriterionType = pCriterion->getCriterionType(); + const ISelectionCriterionTypeInterface *pCriterionType = pCriterion->getCriterionType(); // Get substate number, the first argument (index 0) is the criterion name - uint32_t uiNbSubStates = remoteCommand.getArgumentCount() - 1; + size_t nbSubStates = remoteCommand.getArgumentCount() - 1; // Check that exclusive criterion has only one substate - if (!pCriterionType->isTypeInclusive() && uiNbSubStates != 1) { + if (!pCriterionType->isTypeInclusive() && nbSubStates != 1) { strResult = "Exclusive criterion " + strCriterionName + " can only have one state"; @@ -476,31 +410,29 @@ bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand& remote /// Translate lexical state to numerical state int iNumericalState = 0; - uint32_t uiLexicalSubStateIndex; + size_t lexicalSubStateIndex; // Parse lexical substates std::string strLexicalState = ""; - for (uiLexicalSubStateIndex = 1; - uiLexicalSubStateIndex <= uiNbSubStates; - uiLexicalSubStateIndex++) { + for (lexicalSubStateIndex = 1; lexicalSubStateIndex <= nbSubStates; lexicalSubStateIndex++) { /* * getNumericalValue method from ISelectionCriterionTypeInterface strip his parameter * first parameter based on | sign. In case that the user uses multiple parameters * to set InclusiveCriterion value, we aggregate all desired values to be sure * they will be handled correctly. */ - if (uiLexicalSubStateIndex != 1) { + if (lexicalSubStateIndex != 1) { strLexicalState += "|"; } - strLexicalState += remoteCommand.getArgument(uiLexicalSubStateIndex); + strLexicalState += remoteCommand.getArgument(lexicalSubStateIndex); } // Translate lexical to numerical substate if (!pCriterionType->getNumericalValue(strLexicalState, iNumericalState)) { - strResult = "Unable to find lexical state \"" - + strLexicalState + "\" in criteria " + strCriterionName; + strResult = "Unable to find lexical state \"" + strLexicalState + "\" in criteria " + + strCriterionName; return false; } diff --git a/test/test-platform/TestPlatform.h b/test/test-platform/TestPlatform.h index fae8386..f9c27f7 100644 --- a/test/test-platform/TestPlatform.h +++ b/test/test-platform/TestPlatform.h @@ -31,37 +31,41 @@ #include "ParameterMgrPlatformConnector.h" #include "RemoteCommandHandlerTemplate.h" +#include "RemoteProcessorServer.h" #include <string> +#include <iostream> #include <list> -#include <semaphore.h> class CParameterMgrPlatformConnectorLogger; -class CRemoteProcessorServer; class ISelectionCriterionInterface; class CTestPlatform { typedef TRemoteCommandHandlerTemplate<CTestPlatform> CCommandHandler; typedef CCommandHandler::CommandStatus CommandReturn; + public: - CTestPlatform(const std::string &strclass, int iPortNumber, sem_t& exitSemaphore); + CTestPlatform(const std::string &strclass, uint16_t iPortNumber); virtual ~CTestPlatform(); // Init - bool load(std::string& strError); + bool run(std::string &strError); private: //////////////// Remote command parsers /// Selection Criterion CommandReturn createExclusiveSelectionCriterionFromStateList( - const IRemoteCommand& remoteCommand, std::string& strResult); + const IRemoteCommand &remoteCommand, std::string &strResult); CommandReturn createInclusiveSelectionCriterionFromStateList( - const IRemoteCommand& remoteCommand, std::string& strResult); + const IRemoteCommand &remoteCommand, std::string &strResult); + + CommandReturn createExclusiveSelectionCriterion(const IRemoteCommand &remoteCommand, + std::string &strResult); + CommandReturn createInclusiveSelectionCriterion(const IRemoteCommand &remoteCommand, + std::string &strResult); - CommandReturn createExclusiveSelectionCriterion( - const IRemoteCommand& remoteCommand, std::string& strResult); - CommandReturn createInclusiveSelectionCriterion( - const IRemoteCommand& remoteCommand, std::string& strResult); + CommandReturn getSchemaUri(const IRemoteCommand &remotecommand, std::string &result); + CommandReturn setSchemaUri(const IRemoteCommand &remotecommand, std::string &result); /** Callback to set a criterion's value, see ISelectionCriterionInterface::setCriterionState. * @see CCommandHandler::RemoteCommandParser for detail on each arguments and return @@ -72,16 +76,14 @@ private: * if the criterion is provided in numerical space, * the second argument should be the criterion new value */ - CommandReturn setCriterionState( - const IRemoteCommand& remoteCommand, std::string& strResult); + CommandReturn setCriterionState(const IRemoteCommand &remoteCommand, std::string &strResult); /** Callback to start the PFW, see CParameterMgrPlatformConnector::start. * @see CCommandHandler::RemoteCommandParser for detail on each arguments and return * * @param[in] remoteCommand is ignored */ - CommandReturn startParameterMgr( - const IRemoteCommand& remoteCommand, std::string& strResult); + CommandReturn startParameterMgr(const IRemoteCommand &remoteCommand, std::string &strResult); /** Callback to apply PFW configuration, see CParameterMgrPlatformConnector::applyConfiguration. * @see CCommandHandler::RemoteCommandParser for detail on each arguments and return @@ -90,8 +92,7 @@ private: * * @return EDone (never fails) */ - CommandReturn applyConfigurations( - const IRemoteCommand& remoteCommand, std::string& strResult); + CommandReturn applyConfigurations(const IRemoteCommand &remoteCommand, std::string &strResult); /** Callback to exit the test-platform. * @@ -99,10 +100,10 @@ private: * * @return EDone (never fails) */ - CommandReturn exit(const IRemoteCommand& remoteCommand, std::string& strResult); + CommandReturn exit(const IRemoteCommand &remoteCommand, std::string &strResult); /** The type of a CParameterMgrPlatformConnector boolean setter. */ - typedef bool (CParameterMgrPlatformConnector::*setter_t)(bool, std::string&); + typedef bool (CParameterMgrPlatformConnector::*setter_t)(bool, std::string &); /** Template callback to create a _pParameterMgrPlatformConnector boolean setter callback. * @see CCommandHandler::RemoteCommandParser for detail on each arguments and return * @@ -112,12 +113,11 @@ private: * @tparam the boolean setter method. * @param[in] remoteCommand the first argument should be ether "on" or "off". */ - template<setter_t setFunction> - CommandReturn setter( - const IRemoteCommand& remoteCommand, std::string& strResult); + template <setter_t setFunction> + CommandReturn setter(const IRemoteCommand &remoteCommand, std::string &strResult); /** The type of a CParameterMgrPlatformConnector boolean getter. */ - typedef bool (CParameterMgrPlatformConnector::*getter_t)(); + typedef bool (CParameterMgrPlatformConnector::*getter_t)() const; /** Template callback to create a ParameterMgrPlatformConnector boolean getter callback. * @see CCommandHandler::RemoteCommandParser for detail on each arguments and return * @@ -129,31 +129,36 @@ private: * * @return EDone (never fails) */ - template<getter_t getFunction> - CommandReturn getter(const IRemoteCommand& remoteCommand, std::string& strResult); + template <getter_t getFunction> + CommandReturn getter(const IRemoteCommand &remoteCommand, std::string &strResult); // Commands - bool createExclusiveSelectionCriterionFromStateList(const std::string& strName, const IRemoteCommand& remoteCommand, std::string& strResult); - bool createInclusiveSelectionCriterionFromStateList(const std::string& strName, const IRemoteCommand& remoteCommand, std::string& strResult); - - bool createExclusiveSelectionCriterion(const std::string& strName, uint32_t uiNbValues, std::string& strResult); - bool createInclusiveSelectionCriterion(const std::string& strName, uint32_t uiNbValues, std::string& strResult); - bool setCriterionState(const std::string& strName, uint32_t uiState, std::string& strResult); - bool setCriterionStateByLexicalSpace(const IRemoteCommand& remoteCommand, std::string& strResult); + bool createExclusiveSelectionCriterionFromStateList(const std::string &strName, + const IRemoteCommand &remoteCommand, + std::string &strResult); + bool createInclusiveSelectionCriterionFromStateList(const std::string &strName, + const IRemoteCommand &remoteCommand, + std::string &strResult); + + bool createExclusiveSelectionCriterion(const std::string &strName, size_t nbValues, + std::string &strResult); + bool createInclusiveSelectionCriterion(const std::string &strName, size_t nbValues, + std::string &strResult); + bool setCriterionState(const std::string &strName, uint32_t uiState, std::string &strResult); + bool setCriterionStateByLexicalSpace(const IRemoteCommand &remoteCommand, + std::string &strResult); // Connector - CParameterMgrPlatformConnector* _pParameterMgrPlatformConnector; + CParameterMgrPlatformConnector mParameterMgrPlatformConnector; - // Logger - CParameterMgrPlatformConnectorLogger* _pParameterMgrPlatformConnectorLogger; + class : public CParameterMgrPlatformConnector::ILogger + { + public: + virtual void info(const std::string &log) { std::cout << log << std::endl; } - // Command Handler - CCommandHandler* _pCommandHandler; + virtual void warning(const std::string &log) { std::cerr << log << std::endl; } + } mLogger; // Remote Processor Server - CRemoteProcessorServer* _pRemoteProcessorServer; - - // Semaphore used by calling thread to avoid exiting - sem_t& _exitSemaphore; + CRemoteProcessorServer mRemoteProcessorServer; }; - diff --git a/test/test-platform/main.cpp b/test/test-platform/main.cpp index 6a79597..6cb5267 100644 --- a/test/test-platform/main.cpp +++ b/test/test-platform/main.cpp @@ -29,212 +29,83 @@ */ #include "TestPlatform.h" -#include "FullIo.hpp" +#include "convert.hpp" +#include "Utility.h" #include <iostream> -#include <cstdlib> -#include <semaphore.h> -#include <string.h> -#include <unistd.h> -#include <cerrno> -#include <cassert> +#include <string> +#include <vector> +#include <algorithm> -using namespace std; +using std::cerr; +using std::endl; +using std::string; -const int iDefaultPortNumber = 5001; - -// Starts test-platform in blocking mode -static bool startBlockingTestPlatform(const char *filePath, int portNumber, string &strError) -{ - - // Init semaphore - sem_t sem; - - sem_init(&sem, false, 0); - - // Create param mgr - CTestPlatform testPlatform(filePath, portNumber, sem); - - // Start platformmgr - if (!testPlatform.load(strError)) { - - sem_destroy(&sem); - - return false; - } - - // Block here - sem_wait(&sem); - - sem_destroy(&sem); - - return true; -} - -static void notifyParent(int parentFd, bool success) -{ - if (not utility::fullWrite(parentFd, &success, sizeof(success))) { - cerr << "Unable to warn parent process of load " - << (success ? "success" : "failure") << ": " - << strerror(errno) << endl; - assert(false); - } -} - -// Starts test-platform in daemon mode -static bool startDaemonTestPlatform(const char *filePath, int portNumber, string &strError) -{ - // Pipe used for communication between the child and the parent processes - int pipefd[2]; - - if (pipe(pipefd) == -1) { - - strError = "pipe failed"; - return false; - } - - // Fork the current process: - // - Child process is used to start test-platform - // - Parent process is killed in order to turn its child into a daemon - pid_t pid = fork(); - - if (pid < 0) { - - strError = "fork failed!"; - return false; - - } else if (pid == 0) { - - // Child process : starts test-platform and notify the parent if it succeeds. - - // Close read side of the pipe - close(pipefd[0]); - - // Init semaphore - sem_t sem; - - sem_init(&sem, false, 0); - - // Create param mgr - CTestPlatform testPlatform(filePath, portNumber, sem); - - // Message to send to parent process - bool loadSuccess = testPlatform.load(strError); - - if (!loadSuccess) { - - cerr << strError << endl; - - // Notify parent of failure; - notifyParent(pipefd[1], false); - - } else { - - // Notify parent of success - notifyParent(pipefd[1], true); - - // Block here - sem_wait(&sem); - } - sem_destroy(&sem); - - return loadSuccess; - - } else { - - // Parent process : need to kill it once the child notifies the successs/failure to start - // test-platform (this status is used as exit value of the program). - - // Close write side of the pipe - close(pipefd[1]); - - // Message received from the child process - bool msgFromChild = false; - - if (not utility::fullRead(pipefd[0], &msgFromChild, sizeof(msgFromChild))) { - strError = "Read pipe failed"; - return false; - } - - // return success/failure in exit status - return msgFromChild; - } -} +static const uint16_t defaultPortNumber = 5001; static void showUsage() { - cerr << "test-platform [-dh] <file path> [port number, default " - << iDefaultPortNumber << "]" << endl; + cerr << "test-platform [-h|--help] <file path> [port number, default " << defaultPortNumber + << "]" << endl; } -static void showInvalidUsage() +static void showInvalidUsage(const string &error) { - cerr << "Invalid arguments: "; + cerr << "Invalid arguments: " << error; showUsage(); } static void showHelp() { showUsage(); - cerr << "<file path> must be a valid .xml file, oftenly ParameterFrameworkConfiguration.xml" << endl; - cerr << "Arguments:" << endl - << " -d starts as a deamon" << endl - << " -h display this help and exit" << endl; + cerr << "<file path> must be a valid Paramter top level config file, " + << "often named ParameterFrameworkConfiguration.xml.\n" + << "Arguments:" << endl + << " -h|--help display this help and exit" << endl; } int main(int argc, char *argv[]) { - // Option found by call to getopt() - int opt; - - // Port number to be used by test-platform - int portNumber; - - // Daemon flag - bool isDaemon = false; - - // Index of the <file path> argument in the arguments list provided - int indexFilePath = 1; - - // Handle the -d option - while ((opt = getopt(argc, argv, "dh")) != -1) { - switch (opt) { - case 'd': - isDaemon = true; - indexFilePath = 2; - break; - case 'h': - showHelp(); - return 0; - default: - showInvalidUsage(); - return -1; - } + using Options = std::list<string>; + // argv[0] is the program name, not an option + Options options(argv + 1, argv + argc); + + // Handle help option + auto helpOpts = {"-h", "--help"}; + auto match = std::find_first_of(begin(options), end(options), begin(helpOpts), end(helpOpts)); + if (match != end(options)) { + showHelp(); + return 0; } - // Check the number of arguments - if ((argc < indexFilePath + 1) || (argc > indexFilePath + 2)) { - - showInvalidUsage(); - return -1; + if (options.empty()) { + showInvalidUsage("Expected a path to a Parameter Framework config file."); + return 1; } - char *filePath = argv[indexFilePath]; - portNumber = argc > indexFilePath + 1 ? atoi(argv[indexFilePath + 1]) : iDefaultPortNumber; - - // Choose either blocking or daemon test-platform - bool startError; - string strError; + auto filePath = options.front(); + options.pop_front(); - if (isDaemon) { + // Handle optional port number argument + uint16_t portNumber = defaultPortNumber; - startError = startDaemonTestPlatform(filePath, portNumber, strError); - } else { + if (not options.empty()) { + if (not convertTo(options.front(), portNumber)) { + showInvalidUsage("Could not convert \"" + options.front() + + "\" to a socket port number."); + return 2; + }; + options.pop_front(); + } - startError = startBlockingTestPlatform(filePath, portNumber, strError); + // All arguments should have been consumed + if (not options.empty()) { + showInvalidUsage("Unexpected extra arguments: " + utility::asString(options)); + return 3; } - if (!startError) { + string strError; + if (!CTestPlatform(filePath, portNumber).run(strError)) { cerr << "Test-platform error:" << strError.c_str() << endl; return -1; diff --git a/test/test-subsystem/CMakeLists.txt b/test/test-subsystem/CMakeLists.txt index 52e66b0..eeaa7de 100644 --- a/test/test-subsystem/CMakeLists.txt +++ b/test/test-subsystem/CMakeLists.txt @@ -35,10 +35,5 @@ if (BUILD_TESTING) TESTSubsystemString.cpp TESTSubsystemBuilder.cpp) - include_directories( - "${PROJECT_SOURCE_DIR}/xmlserializer" - "${PROJECT_SOURCE_DIR}/remote-processor" - "${PROJECT_SOURCE_DIR}/parameter") - - target_link_libraries(test-subsystem parameter) + target_link_libraries(test-subsystem PRIVATE parameter) endif() diff --git a/test/test-subsystem/TESTMappingKeys.h b/test/test-subsystem/TESTMappingKeys.h index 90eb869..0134891 100644 --- a/test/test-subsystem/TESTMappingKeys.h +++ b/test/test-subsystem/TESTMappingKeys.h @@ -30,7 +30,8 @@ #pragma once // Mapping item types -enum TESTItemType { +enum TESTItemType +{ ETESTDirectory, ETESTLog }; diff --git a/test/test-subsystem/TESTSubsystem.cpp b/test/test-subsystem/TESTSubsystem.cpp index 214fbb7..473d923 100644 --- a/test/test-subsystem/TESTSubsystem.cpp +++ b/test/test-subsystem/TESTSubsystem.cpp @@ -40,18 +40,21 @@ #define base CSubsystem // Directory for isAlive and NeedResync files -const char* gacFwNamePropName = getenv("PFW_RESULT"); +const char *gacFwNamePropName = getenv("PFW_RESULT"); // Implementation -CTESTSubsystem::CTESTSubsystem(const std::string& strName) : base(strName) +CTESTSubsystem::CTESTSubsystem(const std::string &strName, core::log::Logger &logger) + : base(strName, logger) { // Provide mapping keys to upper layer addContextMappingKey("Directory"); addContextMappingKey("Log"); // Provide creators to upper layer - addSubsystemObjectFactory(new TSubsystemObjectFactory<CTESTSubsystemBinary>("Binary", 1 << ETESTDirectory)); - addSubsystemObjectFactory(new TSubsystemObjectFactory<CTESTSubsystemString>("String", 1 << ETESTDirectory)); + addSubsystemObjectFactory( + new TSubsystemObjectFactory<CTESTSubsystemBinary>("Binary", 1 << ETESTDirectory)); + addSubsystemObjectFactory( + new TSubsystemObjectFactory<CTESTSubsystemString>("String", 1 << ETESTDirectory)); } // Susbsystem sanity health @@ -87,7 +90,7 @@ bool CTESTSubsystem::needResync(bool bClear) } // Read boolean from file -std::string CTESTSubsystem::read(const std::string& strFileName) +std::string CTESTSubsystem::read(const std::string &strFileName) { std::ifstream file; std::string strContent; @@ -100,7 +103,7 @@ std::string CTESTSubsystem::read(const std::string& strFileName) } // Write boolean to file -void CTESTSubsystem::write(const std::string& strFileName, const std::string& strContent) +void CTESTSubsystem::write(const std::string &strFileName, const std::string &strContent) { std::ofstream file; diff --git a/test/test-subsystem/TESTSubsystem.h b/test/test-subsystem/TESTSubsystem.h index bcd0fbd..0546e94 100644 --- a/test/test-subsystem/TESTSubsystem.h +++ b/test/test-subsystem/TESTSubsystem.h @@ -34,16 +34,16 @@ class CTESTSubsystem : public CSubsystem { public: - CTESTSubsystem(const std::string& strName); + CTESTSubsystem(const std::string &strName, core::log::Logger &logger); - // Susbsystem sanity - virtual bool isAlive() const; - // Resynchronization after subsystem restart needed - virtual bool needResync(bool bClear); + // Susbsystem sanity + virtual bool isAlive() const; + // Resynchronization after subsystem restart needed + virtual bool needResync(bool bClear); private: // Read boolean from file - static std::string read(const std::string& strFileName); + static std::string read(const std::string &strFileName); // Write boolean to file - static void write(const std::string& strFileName, const std::string& strContent); + static void write(const std::string &strFileName, const std::string &strContent); }; diff --git a/test/test-subsystem/TESTSubsystemBinary.cpp b/test/test-subsystem/TESTSubsystemBinary.cpp index 540fde8..49a775b 100644 --- a/test/test-subsystem/TESTSubsystemBinary.cpp +++ b/test/test-subsystem/TESTSubsystemBinary.cpp @@ -27,38 +27,54 @@ * (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 <convert.hpp> #include <string.h> +#include <string> #include <sstream> #include <stdlib.h> #include <assert.h> +#include <algorithm> +#include <AlwaysAssert.hpp> +#include <Iterator.hpp> #include "TESTSubsystemBinary.h" #define base CTESTSubsystemObject -CTESTSubsystemBinary::CTESTSubsystemBinary(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context) - : base(strMappingValue, pInstanceConfigurableElement, context) +CTESTSubsystemBinary::CTESTSubsystemBinary( + const std::string &strMappingValue, CInstanceConfigurableElement *pInstanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger) + : base(strMappingValue, pInstanceConfigurableElement, context, logger) { } -std::string CTESTSubsystemBinary::toString(const void* pvValue, uint32_t uiSize) const +std::string CTESTSubsystemBinary::toString(const void *pvValue, size_t size) const { std::ostringstream strStream; uint32_t uiValue = 0; - assert(uiSize <= sizeof(uiValue)); + assert(size <= sizeof(uiValue)); - memcpy((void*)&uiValue, pvValue, uiSize); + auto first = MAKE_ARRAY_ITERATOR(static_cast<const uint8_t *>(pvValue), size); + auto destination = MAKE_ARRAY_ITERATOR(reinterpret_cast<uint8_t *>(&uiValue), sizeof(uiValue)); + + std::copy_n(first, size, destination); strStream << "0x" << std::hex << uiValue; return strStream.str(); } -void CTESTSubsystemBinary::fromString(const std::string& strValue, void* pvValue, uint32_t uiSize) +void CTESTSubsystemBinary::fromString(const std::string &strValue, void *pvValue, size_t size) { - uint32_t uiValue = strtoul(strValue.c_str(), NULL, 0); + uint32_t uiValue; + + assert(size <= sizeof(uiValue)); - assert(uiSize <= sizeof(uiValue)); + if (!convertTo(strValue, uiValue)) { + throw std::runtime_error("Unable to convert \"" + strValue + "\" to uint32"); + } - memcpy(pvValue, (const void*)&uiValue, uiSize); + auto first = MAKE_ARRAY_ITERATOR(reinterpret_cast<const uint8_t *>(&uiValue), size); + auto destination = MAKE_ARRAY_ITERATOR(static_cast<uint8_t *>(pvValue), size); + std::copy_n(first, size, destination); } diff --git a/test/test-subsystem/TESTSubsystemBinary.h b/test/test-subsystem/TESTSubsystemBinary.h index a8d433e..b84c02d 100644 --- a/test/test-subsystem/TESTSubsystemBinary.h +++ b/test/test-subsystem/TESTSubsystemBinary.h @@ -34,12 +34,13 @@ class CTESTSubsystemBinary : public CTESTSubsystemObject { public: - CTESTSubsystemBinary(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context); + CTESTSubsystemBinary(const std::string &strMappingValue, + CInstanceConfigurableElement *configurableElement, + const CMappingContext &context, core::log::Logger &logger); private: // from CTESTSubsystemObject // Format Data - virtual std::string toString(const void* pvValue, uint32_t uiSize) const; - virtual void fromString(const std::string& strValue, void* pvValue, uint32_t uiSize); - + virtual std::string toString(const void *pvValue, size_t size) const; + virtual void fromString(const std::string &strValue, void *pvValue, size_t size); }; diff --git a/test/test-subsystem/TESTSubsystemBuilder.cpp b/test/test-subsystem/TESTSubsystemBuilder.cpp index bcf2afc..6ec062e 100644 --- a/test/test-subsystem/TESTSubsystemBuilder.cpp +++ b/test/test-subsystem/TESTSubsystemBuilder.cpp @@ -27,16 +27,13 @@ * (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 "SubsystemLibrary.h" -#include "NamedElementBuilderTemplate.h" +#include "Plugin.h" +#include "LoggingElementBuilderTemplate.h" #include "TESTSubsystem.h" - -extern "C" -{ -void getTESTSubsystemBuilder(CSubsystemLibrary* pSubsystemLibrary) +void PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1(CSubsystemLibrary *pSubsystemLibrary, + core::log::Logger &logger) { - pSubsystemLibrary->addElementBuilder("TEST", - new TNamedElementBuilderTemplate<CTESTSubsystem>()); -} + pSubsystemLibrary->addElementBuilder( + "TEST", new TLoggingElementBuilderTemplate<CTESTSubsystem>(logger)); } diff --git a/test/test-subsystem/TESTSubsystemObject.cpp b/test/test-subsystem/TESTSubsystemObject.cpp index 706053f..a25b195 100644 --- a/test/test-subsystem/TESTSubsystemObject.cpp +++ b/test/test-subsystem/TESTSubsystemObject.cpp @@ -28,31 +28,36 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <fstream> -#include <alloca.h> #include "ParameterType.h" #include "MappingContext.h" #include "TESTMappingKeys.h" #include "InstanceConfigurableElement.h" #include "TESTSubsystemObject.h" +#include <log/Context.h> +#include <sstream> +#include <vector> #define base CSubsystemObject -CTESTSubsystemObject::CTESTSubsystemObject(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context) - : base(pInstanceConfigurableElement) +CTESTSubsystemObject::CTESTSubsystemObject( + const std::string & /*strMappingValue*/, + CInstanceConfigurableElement *pInstanceConfigurableElement, const CMappingContext &context, + core::log::Logger &logger) + : base(pInstanceConfigurableElement, logger) { - (void)strMappingValue; // Get actual element type - const CParameterType* pParameterType = static_cast<const CParameterType*>(pInstanceConfigurableElement->getTypeElement()); + const CParameterType *pParameterType = + static_cast<const CParameterType *>(pInstanceConfigurableElement->getTypeElement()); - _uiScalarSize = pParameterType->getSize(); - _uiArraySize = pInstanceConfigurableElement->getFootPrint() / _uiScalarSize; + _scalarSize = pParameterType->getSize(); + _arraySize = pInstanceConfigurableElement->getFootPrint() / _scalarSize; _bIsScalar = pParameterType->isScalar(); _strFilePath = context.getItem(ETESTDirectory) + "/" + pInstanceConfigurableElement->getName(); _bLog = context.iSet(ETESTLog) && (context.getItem(ETESTLog) == "yes"); } -bool CTESTSubsystemObject::sendToHW(std::string& strError) +bool CTESTSubsystemObject::sendToHW(std::string &strError) { std::ofstream outputFile; @@ -72,10 +77,8 @@ bool CTESTSubsystemObject::sendToHW(std::string& strError) return true; } - -bool CTESTSubsystemObject::receiveFromHW(std::string& strError) +bool CTESTSubsystemObject::receiveFromHW(std::string & /*strError*/) { - (void)strError; std::ifstream inputFile; inputFile.open(_strFilePath.c_str()); @@ -91,18 +94,18 @@ bool CTESTSubsystemObject::receiveFromHW(std::string& strError) return true; } -void CTESTSubsystemObject::sendToFile(std::ofstream& outputFile) +void CTESTSubsystemObject::sendToFile(std::ofstream &outputFile) { - uint32_t uiIndex; + for (size_t index = 0; index < _arraySize; index++) { - for (uiIndex = 0 ; uiIndex < _uiArraySize ; uiIndex++) { + std::vector<uint8_t> aucValue(_scalarSize); - void* pvValue = alloca(_uiScalarSize); + void *pvValue = aucValue.data(); // Read Value in BlackBoard - blackboardRead(pvValue, _uiScalarSize); + blackboardRead(pvValue, _scalarSize); - std::string strValue = toString(pvValue, _uiScalarSize); + std::string strValue = toString(pvValue, _scalarSize); outputFile << strValue << std::endl; @@ -110,22 +113,23 @@ void CTESTSubsystemObject::sendToFile(std::ofstream& outputFile) if (_bIsScalar) { - log_info("TESTSUBSYSTEM: Writing \"%s\" to file %s", strValue.c_str(), _strFilePath.c_str()); + info() << "TESTSUBSYSTEM: Writing '" << strValue << "' to file " << _strFilePath; } else { - log_info("TESTSUBSYSTEM: Writing \"%s\" to file %s[%d]", strValue.c_str(), _strFilePath.c_str(), uiIndex); + info() << "TESTSUBSYSTEM: Writing '" << strValue << "' to file " << _strFilePath + << "[" << index << "]"; } } } } -void CTESTSubsystemObject::receiveFromFile(std::ifstream& inputFile) +void CTESTSubsystemObject::receiveFromFile(std::ifstream &inputFile) { - uint32_t uiIndex; + for (size_t index = 0; index < _arraySize; index++) { - for (uiIndex = 0 ; uiIndex < _uiArraySize ; uiIndex++) { + std::vector<uint8_t> aucValue(_scalarSize); - void* pvValue = alloca(_uiScalarSize); + void *pvValue = aucValue.data(); std::string strValue; @@ -135,16 +139,17 @@ void CTESTSubsystemObject::receiveFromFile(std::ifstream& inputFile) if (_bIsScalar) { - log_info("TESTSUBSYSTEM: Writing \"%s\" from file %s", strValue.c_str(), _strFilePath.c_str()); + info() << "TESTSUBSYSTEM: Reading '" << strValue << "' to file " << _strFilePath; } else { - log_info("TESTSUBSYSTEM: Writing \"%s\" from file %s[%d]", strValue.c_str(), _strFilePath.c_str(), uiIndex); + info() << "TESTSUBSYSTEM: Reading '" << strValue << "' to file " << _strFilePath + << "[" << index << "]"; } } - fromString(strValue, pvValue, _uiScalarSize); + fromString(strValue, pvValue, _scalarSize); // Write Value in Blackboard - blackboardWrite(pvValue, _uiScalarSize); + blackboardWrite(pvValue, _scalarSize); } } diff --git a/test/test-subsystem/TESTSubsystemObject.h b/test/test-subsystem/TESTSubsystemObject.h index 527e555..a41bcba 100644 --- a/test/test-subsystem/TESTSubsystemObject.h +++ b/test/test-subsystem/TESTSubsystemObject.h @@ -36,23 +36,25 @@ class CMappingContext; class CTESTSubsystemObject : public CSubsystemObject { public: - CTESTSubsystemObject(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context); + CTESTSubsystemObject(const std::string &strMappingValue, + CInstanceConfigurableElement *pInstanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger); protected: // from CSubsystemObject // Sync to/from HW - virtual bool sendToHW(std::string& strError); - virtual bool receiveFromHW(std::string& strError); + virtual bool sendToHW(std::string &strError); + virtual bool receiveFromHW(std::string &strError); private: - void sendToFile(std::ofstream& outputFile); - void receiveFromFile(std::ifstream& inputFile); - virtual std::string toString(const void* pvValue, uint32_t uiSize) const = 0; - virtual void fromString(const std::string& strValue, void* pvValue, uint32_t uiSize) = 0; + void sendToFile(std::ofstream &outputFile); + void receiveFromFile(std::ifstream &inputFile); + virtual std::string toString(const void *pvValue, size_t size) const = 0; + virtual void fromString(const std::string &strValue, void *pvValue, size_t size) = 0; protected: - uint32_t _uiScalarSize; - uint32_t _uiArraySize; + size_t _scalarSize; + size_t _arraySize; std::string _strFilePath; bool _bLog; bool _bIsScalar; diff --git a/test/test-subsystem/TESTSubsystemString.cpp b/test/test-subsystem/TESTSubsystemString.cpp index 81ed793..de2d478 100644 --- a/test/test-subsystem/TESTSubsystemString.cpp +++ b/test/test-subsystem/TESTSubsystemString.cpp @@ -28,23 +28,37 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <string.h> +#include <iterator> +#include <algorithm> +#include <stdexcept> +#include <Iterator.hpp> #include "TESTSubsystemString.h" #define base CTESTSubsystemObject -CTESTSubsystemString::CTESTSubsystemString(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context) - : base(strMappingValue, pInstanceConfigurableElement, context) +CTESTSubsystemString::CTESTSubsystemString( + const std::string &strMappingValue, CInstanceConfigurableElement *pInstanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger) + : base(strMappingValue, pInstanceConfigurableElement, context, logger) { } -std::string CTESTSubsystemString::toString(const void* pvValue, uint32_t uiSize) const +std::string CTESTSubsystemString::toString(const void *pvValue, size_t /*size*/) const { - (void)uiSize; - - return (const char*)pvValue; + return (const char *)pvValue; } -void CTESTSubsystemString::fromString(const std::string& strValue, void* pvValue, uint32_t uiSize) +void CTESTSubsystemString::fromString(const std::string &strValue, void *pvValue, size_t size) { - strncpy((char*)pvValue, strValue.c_str(), uiSize); + std::size_t requiredBufferSize = strValue.length() + 1; /* Adding one for null character */ + if (size < requiredBufferSize) { + throw std::logic_error("Buffer is to small: " + std::to_string(size) + " Minimum size: " + + std::to_string(requiredBufferSize)); + } + + auto destination = MAKE_ARRAY_ITERATOR(static_cast<char *>(pvValue), size); + auto last = std::copy(begin(strValue), end(strValue), destination); + + /* Adding null character */ + *last = 0; } diff --git a/test/test-subsystem/TESTSubsystemString.h b/test/test-subsystem/TESTSubsystemString.h index cf7edb7..1713785 100644 --- a/test/test-subsystem/TESTSubsystemString.h +++ b/test/test-subsystem/TESTSubsystemString.h @@ -34,12 +34,13 @@ class CTESTSubsystemString : public CTESTSubsystemObject { public: - CTESTSubsystemString(const std::string& strMappingValue, CInstanceConfigurableElement* pInstanceConfigurableElement, const CMappingContext& context); + CTESTSubsystemString(const std::string &strMappingValue, + CInstanceConfigurableElement *pInstanceConfigurableElement, + const CMappingContext &context, core::log::Logger &logger); private: // from CTESTSubsystemObject // Format Data - virtual std::string toString(const void* pvValue, uint32_t uiSize) const; - virtual void fromString(const std::string& strValue, void* pvValue, uint32_t uiSize); - + virtual std::string toString(const void *pvValue, size_t size) const; + virtual void fromString(const std::string &strValue, void *pvValue, size_t size); }; diff --git a/test/tmpfile/CMakeLists.txt b/test/tmpfile/CMakeLists.txt new file mode 100644 index 0000000..84818e7 --- /dev/null +++ b/test/tmpfile/CMakeLists.txt @@ -0,0 +1,38 @@ +# 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. + +if(BUILD_TESTING) + if (WIN32) + set(OS_SPECIFIC_TMPFILE windows/TmpFile.cpp) + else () + set(OS_SPECIFIC_TMPFILE posix/TmpFile.cpp) + endif () + + add_library(tmpfile STATIC ${OS_SPECIFIC_TMPFILE}) + target_include_directories(tmpfile PUBLIC .) +endif() diff --git a/test/tmpfile/TmpFile.hpp b/test/tmpfile/TmpFile.hpp new file mode 100644 index 0000000..ebefa93 --- /dev/null +++ b/test/tmpfile/TmpFile.hpp @@ -0,0 +1,106 @@ +/* + * 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. + */ +#pragma once + +#include <exception> +#include <fstream> +#include <string> +#include <array> + +#include <cerrno> +#include <cstring> + +namespace parameterFramework +{ +namespace utility +{ + +/** Create a temporary file with the given content. */ +class TmpFile +{ +public: + TmpFile(std::string content) : mPath(mktmp()) + { + std::ofstream file(mPath); + file.exceptions(std::ofstream::failbit | std::ofstream::badbit); + file << content; + // Close explicitly to detect errors (fstream destructor does not throw) + file.close(); + } + + TmpFile(TmpFile &&right) : mPath(std::move(right.mPath)) { right.mPath.clear(); } + + /** Forbid copy semantic as sharing the tmp file is not needed. + * @{ */ + TmpFile(const TmpFile &right) = delete; + TmpFile &operator=(const TmpFile &right) = delete; + /** @} */ + + TmpFile &operator=(TmpFile &&right) + { + remove(); + mPath = std::move(right.mPath); + right.mPath.clear(); + return *this; + } + + ~TmpFile() { remove(); } + + /** @return the path to the temporary file. + * "" if the file was moved from. + */ + const std::string &getPath() const { return mPath; } +private: + /** @return a valid unique file name. */ + std::string mktmp(); + + /** Throw an std::runtime_error with a message constructed from the context and std::errno. + * + * Call it after a c standard function failure. + */ + static void throwErrnoError(std::string context) + { + auto message = context + ": (" + std::to_string(errno) + ") " + std::strerror(errno); + throw std::runtime_error(message); + } + + void remove() + { + if (not mPath.empty()) { + if (std::remove(mPath.c_str()) != 0) { + throwErrnoError("Could not delete tmpfile"); + } + } + } + std::string mPath; +}; + +} // utility +} // parameterFramework diff --git a/parameter/AutoLog.cpp b/test/tmpfile/posix/TmpFile.cpp index ff7151a..36efbd6 100644 --- a/parameter/AutoLog.cpp +++ b/test/tmpfile/posix/TmpFile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,27 +27,31 @@ * (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 "AutoLog.h" -using std::string; +#include "TmpFile.hpp" -CAutoLog::CAutoLog(const CElement* pElement, const string& strContext, bool bLogOn) - : _pElement(pElement), _strContext(strContext), _bLogOn(bLogOn) +#include <stdlib.h> +#include <unistd.h> + +namespace parameterFramework +{ +namespace utility { - if (_bLogOn) { - // Log - _pElement->doLog(false, _strContext + " {"); - // Nest - _pElement->nestLog(); - } -} -CAutoLog::~CAutoLog() +std::string TmpFile::mktmp() { - if (_bLogOn) { - // Unnest - _pElement->unnestLog(); - // Log - _pElement->doLog(false, "} " + _strContext); + using std::string; + + char path[] = "Tmp_ParameterFramework_XXXXXX"; + int fd = mkstemp(path); + if (fd == -1) { + throwErrnoError("Could not create tmp file with pattern \"" + string(path) + '"'); + } + if (close(fd) != 0) { + throwErrnoError("Could not close tmp file \"" + string(path) + '"'); } + return path; } + +} // utility +} // parameterFramework diff --git a/test/tmpfile/windows/TmpFile.cpp b/test/tmpfile/windows/TmpFile.cpp new file mode 100644 index 0000000..4a0fac3 --- /dev/null +++ b/test/tmpfile/windows/TmpFile.cpp @@ -0,0 +1,89 @@ +/* + * 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 "TmpFile.hpp" + +#include <memory> + +#include <Windows.h> + +using std::to_string; + +namespace parameterFramework +{ +namespace utility +{ + +/** Format an error code returned by GetLastError to a human readable string. */ +static std::string formatError(DWORD error) +{ + LPTSTR formatedError = nullptr; // Pointer to the output buffer + + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | // use system message tables to retrieve error text + FORMAT_MESSAGE_ALLOCATE_BUFFER | // allocate buffer on local heap for error text + FORMAT_MESSAGE_IGNORE_INSERTS, // no insertion parameters + NULL, // unused with FORMAT_MESSAGE_FROM_SYSTEM + error, // the error to format + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Use default language + (LPTSTR)&formatedError, // output a pointer to the formated string + 0, // minimum size for output buffer + NULL); // No arguments + + // Release memory allocated by FormatMessage() on exit + // Ignore LocalFree failure + auto localFree = [](char *ptr) { LocalFree(ptr); }; + std::unique_ptr<char, decltype(localFree)> guard{formatedError, localFree}; + + if (formatedError == nullptr) { + return "Could not format error " + to_string(error) + ": " + to_string(::GetLastError()); + } + return formatedError; +} + +std::string TmpFile::mktmp() +{ + char directory[] = "."; + char prefix[] = "pfw"; // GetTempFileName uses up to the first three characters + char path[MAX_PATH + 1]; + if (::GetTempFileName(directory, prefix, 0, path) == 0) { + auto error = ::GetLastError(); + + auto message = std::string() + "Could not create a tmp file in \"" + directory + + "\", with prefix \"" + prefix + "\": (" + to_string(error) + ") " + + formatError(error); + throw std::runtime_error(message); + } + + return path; +} + +} // utility +} // parameterFramework diff --git a/test/tokenizer/CMakeLists.txt b/test/tokenizer/CMakeLists.txt index 8a00cb9..1ce68dd 100644 --- a/test/tokenizer/CMakeLists.txt +++ b/test/tokenizer/CMakeLists.txt @@ -27,22 +27,10 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if(BUILD_TESTING) - # Add catch unit test framework - # TODO Use gtest as it is the team recommendation - # Unfortunately gtest is very hard to setup as not binary distributed - # catch is only one header so it is very easy - # Catch can be downloaded from: - # https://raw.github.com/philsquared/Catch/master/single_include/catch.hpp - # Then append the download folder to the CMAKE_INCLUDE_PATH variable or - # copy it in a standard location (/usr/include on most linux distribution). - find_path(CATCH_HEADER catch.hpp) - include_directories(${CATCH_HEADER}) - # Add unit test add_executable(tokenizerTest Test.cpp) - include_directories(${PROJECT_SOURCE_DIR}/utility) - target_link_libraries(tokenizerTest pfw_utility) + target_link_libraries(tokenizerTest PRIVATE pfw_utility catch) add_test(NAME tokenizerTest COMMAND tokenizerTest) diff --git a/test/tokenizer/Test.cpp b/test/tokenizer/Test.cpp index 14f9ea4..37a72cb 100644 --- a/test/tokenizer/Test.cpp +++ b/test/tokenizer/Test.cpp @@ -30,7 +30,7 @@ #include "Tokenizer.h" -#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() #include <catch.hpp> #include <string> @@ -39,78 +39,76 @@ using std::string; using std::vector; -SCENARIO("Tokenizer tests") { - GIVEN("A default tokenizer") { +using Expected = vector<string>; - GIVEN("A trivial string") { - Tokenizer tokenizer("a bcd ef"); +SCENARIO("Tokenizer tests") +{ + GIVEN ("A default tokenizer") { - THEN("next() api should work") { - CHECK(tokenizer.next() == "a"); - CHECK(tokenizer.next() == "bcd"); - CHECK(tokenizer.next() == "ef"); - CHECK(tokenizer.next() == ""); - } - THEN("split() api should work") { - vector<string> expected; - expected.push_back("a"); - expected.push_back("bcd"); - expected.push_back("ef"); + GIVEN ("A trivial string") { + Tokenizer tokenizer("a bcd ef"); + Expected expected{"a", "bcd", "ef"}; + THEN ("split() api should work") { CHECK(tokenizer.split() == expected); } } - GIVEN("An empty string") { + GIVEN ("An empty string") { Tokenizer tokenizer(""); + Expected expected{}; - THEN("next() api should work") { - CHECK(tokenizer.next() == ""); + THEN ("split() should be empty") { + CHECK(tokenizer.split() == expected); } - THEN("split() api should work") { - vector<string> expected; + } - CHECK(tokenizer.split().empty()); + GIVEN ("Multiple separators in a row") { + Tokenizer tokenizer(" a \n\t bc "); + Expected expected{"a", "bc"}; + + THEN ("split() api should work") { + CHECK(tokenizer.split() == expected); } } + } - GIVEN("A slash-separated string and tokenizer") { - Tokenizer tokenizer("/a/bcd/ef g/h/", "/"); + GIVEN ("A slash-separated string and tokenizer") { + Tokenizer tokenizer("/a/bcd/ef g/h/", "/"); + Expected expected{"a", "bcd", "ef g", "h"}; - THEN("next() api should work") { - CHECK(tokenizer.next() == "a"); - CHECK(tokenizer.next() == "bcd"); - CHECK(tokenizer.next() == "ef g"); - CHECK(tokenizer.next() == "h"); - CHECK(tokenizer.next() == ""); - } - THEN("split() api should work") { - vector<string> expected; - expected.push_back("a"); - expected.push_back("bcd"); - expected.push_back("ef g"); - expected.push_back("h"); + THEN ("split() api should work") { + CHECK(tokenizer.split() == expected); + } + } + + GIVEN ("A tokenizer that doesn't merge consecutive separators") { + GIVEN ("An empty string") { + Tokenizer tokenizer("", Tokenizer::defaultDelimiters, false); + Expected expected{}; + + THEN ("split() should be empty") { CHECK(tokenizer.split() == expected); } } - GIVEN("Multiple separators in a row") { - Tokenizer tokenizer(" a \n\t bc "); + GIVEN ("A string consisting only of a delimiter") { + Tokenizer tokenizer(",", ",", false); + Expected expected{"", ""}; - THEN("next() api should work") { - CHECK(tokenizer.next() == "a"); - CHECK(tokenizer.next() == "bc"); - CHECK(tokenizer.next() == ""); + THEN ("split() should return two empty tokens") { + CHECK(tokenizer.split() == expected); } - THEN("split() api should work") { - vector<string> expected; - expected.push_back("a"); - expected.push_back("bc"); + } + GIVEN ("Multiple separators in a row") { + Tokenizer tokenizer(" a b \nc d ", Tokenizer::defaultDelimiters, false); + Expected expected{"", "a", "", "b", "", "c", "d", ""}; + + THEN ("split() api should work") { CHECK(tokenizer.split() == expected); } } } - } diff --git a/tools/xmlGenerator/portAllocator.py b/test/xml-generator/CMakeLists.txt index 64e1175..6aeee14 100755..100644 --- a/tools/xmlGenerator/portAllocator.py +++ b/test/xml-generator/CMakeLists.txt @@ -1,6 +1,4 @@ -#!/usr/bin/python2 -# -# Copyright (c) 2011-2014, Intel Corporation +# Copyright (c) 2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -28,21 +26,14 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import sys, socket - -serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -try: - # Create a listening socket on a random available port on localhost - serversock.bind(('127.0.0.1',0)) - serversock.listen(0) +if (BUILD_TESTING) - # Print the chosen port - print(serversock.getsockname()[1]) - serversock.close() + find_package(PythonInterp 2 REQUIRED) -except socket.error, (errno,message): - sys.stderr.write("portAllocator: Socket creation error " + str(errno) + ": " + message + '\n') - if serversock: - serversock.close() - sys.exit(1) + add_test(NAME xml-generator + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tools/xmlGenerator + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py) + # Custom function defined in the top-level CMakeLists + set_test_env(xml-generator) +endif() diff --git a/test/xml-generator/PFConfig/configuration.xml b/test/xml-generator/PFConfig/configuration.xml new file mode 100644 index 0000000..e459644 --- /dev/null +++ b/test/xml-generator/PFConfig/configuration.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ParameterFrameworkConfiguration SystemClassName="Test" ServerPort="5066" TuningAllowed="false"> + <SubsystemPlugins> + </SubsystemPlugins> + <StructureDescriptionFileLocation Path="structure.xml"/> +</ParameterFrameworkConfiguration> diff --git a/test/xml-generator/PFConfig/criteria.txt b/test/xml-generator/PFConfig/criteria.txt new file mode 100644 index 0000000..7ab3d99 --- /dev/null +++ b/test/xml-generator/PFConfig/criteria.txt @@ -0,0 +1,2 @@ +InclusiveCriterion Colors : Red Green Blue +ExclusiveCriterion Switch : On Off diff --git a/test/xml-generator/PFConfig/duplicate_criterion_value.txt b/test/xml-generator/PFConfig/duplicate_criterion_value.txt new file mode 100644 index 0000000..af5ffe6 --- /dev/null +++ b/test/xml-generator/PFConfig/duplicate_criterion_value.txt @@ -0,0 +1 @@ +InclusiveCriterion Duplicate : Foo Foo diff --git a/test/xml-generator/PFConfig/includeStructure.xml b/test/xml-generator/PFConfig/includeStructure.xml new file mode 100644 index 0000000..6ab16c3 --- /dev/null +++ b/test/xml-generator/PFConfig/includeStructure.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Test xi:include feature. + FIXME: this should be done in the functional tests, not in the xmlgeneration tests. --> +<ComponentLibrary> + <ComponentType Name="Included"> + <BooleanParameter Name="bool"/> + </ComponentType> +</ComponentLibrary> diff --git a/test/xml-generator/PFConfig/structure.xml b/test/xml-generator/PFConfig/structure.xml new file mode 100644 index 0000000..e9b621f --- /dev/null +++ b/test/xml-generator/PFConfig/structure.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<SystemClass Name="Test" xmlns:xi="http://www.w3.org/2001/XInclude"> + <Subsystem Name="test" Type="Virtual"> + <ComponentLibrary> + <!-- Test xi:include feature. + FIXME: this should be done in the functional tests, + not in the xml generation test. --> + <xi:include href="includeStructure.xml"/> + </ComponentLibrary> + <InstanceDefinition> + + <Component Name="included" Type="Included"/> + <ParameterBlock Name="inline"> + <BooleanParameter Name="bool"/> + </ParameterBlock> + + <ParameterBlock Name="block" ArrayLength="5"> + <FixedPointParameter Name="q2.5" Size="8" Integral="2" Fractional="5"/> + <IntegerParameter Name="uint8" Signed="false" Size="8"/> + <StringParameter Name="string" MaxLength="50"/> + </ParameterBlock> + + </InstanceDefinition> + </Subsystem> +</SystemClass> diff --git a/test/xml-generator/test.py b/test/xml-generator/test.py new file mode 100644 index 0000000..80287f3 --- /dev/null +++ b/test/xml-generator/test.py @@ -0,0 +1,131 @@ +#! python2.7 +# 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. + +import sys +import os +import subprocess +import difflib +import unittest +import copy + +class PfConfig: + def __init__(self, toplevel, criteria, schemas): + self.toplevel = toplevel + self.criteria = criteria + self.schemas = schemas + +class TestVector: + def __init__(self, initialSettings=None, edds=[], domains=[]): + self.initialSettings = initialSettings + self.edds = edds + self.domains = domains + +class Tester(object): + def __init__(self, pfConfig, testVector): + self.command = [sys.executable, "domainGenerator.py", + "--validate", + "--verbose", + "--toplevel-config", pfConfig.toplevel, + "--criteria", pfConfig.criteria, + "--schemas-dir", pfConfig.schemas] + + if testVector.initialSettings: + self.command += ["--initial-settings", testVector.initialSettings] + if testVector.edds: + self.command += ["--add-edds"] + testVector.edds + if testVector.domains: + self.command += ["--add-domains"] + testVector.domains + + def check(self, reference=None, expectedErrors=0): + process = subprocess.Popen(self.command, stdout=subprocess.PIPE) + actual = process.stdout.read().splitlines() + + if process.wait() != expectedErrors: + raise AssertionError("Expected {} errors, found {}".format( + expectedErrors, + process.returncode)) + + if not reference: + # The caller only wants to check the number of errors + return + + # The generation has succeeded as expected - let's compare with the reference. + if reference != actual: + unified = difflib.unified_diff(reference, + actual, + fromfile="reference.xml", + tofile="-", + lineterm="") + raise AssertionError("The result and the reference don't match:" + "\n".join(unified)) + + +basedir = os.path.dirname(sys.argv[0]) + +config_dir = os.path.join(basedir, "PFConfig") +vector_dir = os.path.join(basedir, "testVector") +class TestCase(unittest.TestCase): + def setUp(self): + self.nominal_reference = open(os.path.join(vector_dir, "reference.xml")).read().splitlines() + self.nominal_pfconfig = PfConfig(os.path.join(config_dir, "configuration.xml"), + os.path.join(config_dir, "criteria.txt"), + os.path.join(basedir, "../../schemas")) + self.nominal_vector = TestVector(os.path.join(vector_dir, "initialSettings.xml"), + [os.path.join(vector_dir, "first.pfw"), + os.path.join(vector_dir, "second.pfw"), + os.path.join(vector_dir, "complex.pfw")], + [os.path.join(vector_dir, "third.xml"), + os.path.join(vector_dir, "fourth.xml")]) + + def test_nominal(self): + tester = Tester(self.nominal_pfconfig, self.nominal_vector) + tester.check(self.nominal_reference) + + def test_nonfatalError(self): + self.nominal_vector.edds.append(os.path.join(vector_dir, "duplicate.pfw")) + + tester = Tester(self.nominal_pfconfig, self.nominal_vector) + tester.check(self.nominal_reference, expectedErrors=1) + + def test_conflicting(self): + vector = TestVector(edds=[os.path.join(vector_dir, "conflicting.pfw")]) + + tester = Tester(self.nominal_pfconfig, vector) + tester.check(expectedErrors=1) + + def test_fail_criteria(self): + self.nominal_pfconfig.criteria = os.path.join(config_dir, "duplicate_criterion_value.txt") + # Empty test vector: we want to make sure that the erroneous criterion + # is the only source of error + empty_vector = TestVector() + + tester = Tester(self.nominal_pfconfig, empty_vector) + tester.check(expectedErrors=1) + +if __name__ == "__main__": + unittest.main() diff --git a/test/xml-generator/testVector/complex.pfw b/test/xml-generator/testVector/complex.pfw new file mode 100644 index 0000000..6339a13 --- /dev/null +++ b/test/xml-generator/testVector/complex.pfw @@ -0,0 +1,40 @@ +domain: sequenceAware sequenceAware + +domainGroup: Red sequenceAware + Colors Includes Red + confType: On + ANY + Switch Is On + # Expecting a empty tree of all (except for the last `Switch Is On` rule) + ALL + ALL + ALL + ALL + ANY + Switch Is On + confType: On + Switch Is On + + domain: Black + Colors Includes Green + confGroup: green.confGroup + # Should add a `.` in the conf name + # Ie an empty confGroup in a legal name + confGroup: + + confType: On + Switch Is On + + # confGroups with the same name should not overwrite one another + confGroup: On + Colors Includes Green + + conf: Blue.dot + Colors Includes Blue + + component: /Test/test + component: block/0 + q2.5 = 1.18750 + string = 12 ab @ < +to learn what it is about. + +## How to create a test environment + +### Test Directory + +A test directory should contains a `conf.json` file containing: + +- The desired command prefix (e.g. `adb shell` in order to execute tests on an + android board or empty to execute locally). +- The port on which the test-platform should be started. +- The criterion file path (see + [this README](https://github.com/01org/parameter-framework/tree/master/tools/xmlGenerator#domaingeneratorpy)). +- The path to the Parameter Framework toplevel configuration file. +- The path to the directory containing the scenario files. +- The path to the scripts definitions file (optional) (see below). +- The path to the actions definitions (aka "ActionGatherer") file (optional) + (see below). +- The path to the log output file (optional but needed for coverage). +- The path to the directory containing the coverage generation tool + (optional; for coverage only). +- The path to the html coverage output file (optional; for coverage only). +- The path to the Parameter Framework domain configuration file (optional; for + coverage only). + +Relative paths in `conf.json` will be evaluated *relative to the test +directory*. + +## Example Client Simulator configuration file + +```{.json} +{ + "PrefixCommand" : "adb shell", + "TestPlatformPort" : "5001", + + "CriterionFile" : "MyCriteria.txt", + "PfwConfFile" : "/home/user/tests/TopLevel.xml", + + "ScenariosDirectory" : "test-vectors", + "ScriptsFile" : "my-test-scripts.json", + "ActionGathererFile" : "my-test-actions.json", + + "LogFile" : "tests.log", + + "CoverageDir" : "/home/user/parameter-framework/tools/coverage", + "CoverageFile" : "coverage.html", + "PfwDomainConfFile" : "MyConfigurableDomains.xml" +} +``` + +### Scenario + +All scenario files need to be put in the directory mentioned by the +`ScenariosDirectory` configuration item. + +A scenario file contains all the actions you want to take. *Note*: it is an +ordered list. There are two possible kind of actions: `setCriterion` and +`script`. +For example: + +```{.json} +[ + {"setCriterion" : + { + "Mood" : "mad" + } + }, + {"script" : "myFirstScript"}, + {"setCriterion" : + { + "Mood" : "glad", + "SmokeGenerator" : "On", + "Colors" : "red blue" + } + }, + {"script" : "mySecondScript"} +] +``` + +This scenario file sets a criterion, then runs a script, then sets three +criteria and finally runs another script. + +The `setCriterion` type allows user to offer a dictionary describing changing +criteria (configurations are automatically applied after using this action +type). Other criteria keep there old values. + +The other type, `script` allows users to launch a script when he wants. + +### Action definitions (aka ActionGatherer) + +You can also define your own types based on the system ones, defined ones. You +have to edit the `ActionGathererFile` specified in the `conf.json` file to do +that. This file has this pattern : + +```{.json} +{ + "getMad": + {"setCriterion" : + { + "Mood" : "mad" + } + }, + "party" : + {"setCriterion" : + { + "SmokeGenerator" : "On", + "Colors":"red blue" + } + } +} +``` + +Here we define five new types based on `setCriterion`. When writing a scenario, +we can now use those types as basis and add some criteria to set in the same +time. + +**For now, defining `script` actions are not supported**; only `setCriterion` +action definitions are supported. + +Here is the example scenario, rewritten using the above definitions: + +```{.json} +[ + {"getMad" : {}}, + {"script" : "myFirstScript"}, + {"party": + { + "Mood":"glad", + } + }, + {"script" : "mySecondScript"}, +] +``` + +During the `party` step, the `SmokeGenerator` and `Colors` criteria are set as +defined in the `ActionGathererFile` but also the `Mood` criteria. + +### Scripts + +Scripts are defined in the `ScriptsFile` specified in the `conf.json` file *or* +they can be an inline shell script. + +This `ScriptsFile` file should look like this : + +```{.json} +{ + "myFirstScript" : ["test-scripts/first.sh","asynchronous"] + "mySecondScript" : ["test-scripts/second.sh","synchronous"], +} +``` + +This dictionary is composed as such: + +```{.json} +name : ["path/to/script",synchronousness] +``` + +The path to the script is relative *to the path of the `ScriptsFile`*. + +The synchronousness can be either `"synchronous"` or `"asynchronous"` and +determines whether the Client Simulator waits for the script to return before +executing the next scenario step. To be clear: + +* asynchronous : The script will run concurrently to the execution of the + Client Simulator; +* synchronous : The Client Simulator will wait the end of the script before + resuming execution and thus, the rest of the scenario won't be executed until + the script returns. diff --git a/MODULE_LICENSE_BSD b/tools/clientSimulator/clientsimulator/__init__.py index e69de29..e69de29 100644 --- a/MODULE_LICENSE_BSD +++ b/tools/clientSimulator/clientsimulator/__init__.py diff --git a/tools/clientSimulator/clientsimulator/configuration/ConfigParser.py b/tools/clientSimulator/clientsimulator/configuration/ConfigParser.py new file mode 100644 index 0000000..8a513ff --- /dev/null +++ b/tools/clientSimulator/clientsimulator/configuration/ConfigParser.py @@ -0,0 +1,71 @@ +# Copyright (c) 2014-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. + +import logging +import json +import os + + +class ConfigParser: + + """ This class define needed configuration environment information """ + + def __init__(self, confFileName, testsDirectory, consoleLogger): + + # Parsing of Json test file + with open(confFileName, "r") as testFile: + self.__conf = json.load(testFile) + + # Preparing mandatory files and directory paths + for key in ["CriterionFile", + "PfwConfFile", + "ScenariosDirectory"]: + self.__conf[key] = os.path.join(testsDirectory, self.__conf[key]) + + # Preparing optional files and directory paths + for key in ["ScriptsFile", + "ActionGathererFile", + "LogFile", + "CoverageFile", + "CoverageDir", + "PfwDomainConfFile"]: + try: + self.__conf[key] = os.path.join(testsDirectory, self.__conf[key]) + except KeyError as e: + self.__conf[key] = "" + + self.__logger = logging.getLogger(__name__) + self.__logger.addHandler(consoleLogger) + + def __getitem__(self, item): + try: + return self.__conf[item] + except KeyError as e: + self.__logger.error( + "The item : {} is not in the configuration file".format(item)) + raise e diff --git a/tools/clientSimulator/clientsimulator/configuration/__init__.py b/tools/clientSimulator/clientsimulator/configuration/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/configuration/__init__.py diff --git a/utility/Android.mk b/tools/clientSimulator/clientsimulator/criterion/Criterion.py index acafaef..f96d583 100644 --- a/utility/Android.mk +++ b/tools/clientSimulator/clientsimulator/criterion/Criterion.py @@ -1,4 +1,4 @@ -# Copyright (c) 2011-2014, Intel Corporation +# Copyright (c) 2014-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,60 +26,36 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -LOCAL_PATH := $(call my-dir) -#################### -# Common definitions +class Criterion: -common_src_files := \ - Tokenizer.cpp \ - Utility.cpp \ - NaiveTokenizer.cpp \ - FullIo.cpp \ + """ A simple class that defines common criterions attributes """ -common_module := libpfw_utility -common_module_tags := optional + @classmethod + def allowedValues(cls): + """ + The getter of the allowedValues attribute -common_cflags := \ - -Wall \ - -Werror \ - -Wextra \ - -Wno-unused-parameter + :return: allowedValues attribute : The lexical states list the + criterion can take. + :rtype: string list + """ -############################# -# Target build + # _allowedValues variable is created in CriterionClassFactory + # when creating dynamic child classes + return cls._allowedValues -include $(CLEAR_VARS) + @property + def noValue(self): + return '0' -LOCAL_SRC_FILES := $(common_src_files) -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +class InvalidCriterionException(Exception): -LOCAL_MODULE := $(common_module) -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) + """ Exception raised in case of problem with a criterion """ -LOCAL_CFLAGS := $(common_cflags) + def __init__(self, msg): + self.__msg = msg -ifeq ($(INCLUDE_STLPORT), true) -include external/stlport/libstlport.mk -endif - -include $(BUILD_STATIC_LIBRARY) - -############################## -# Host build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -LOCAL_MODULE := $(common_module)_host -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_CFLAGS := $(common_cflags) - -include $(BUILD_HOST_STATIC_LIBRARY) + def __str__(self): + return "Invalid Criterion Error : " + self.__msg diff --git a/tools/clientSimulator/clientsimulator/criterion/CriterionClassFactory.py b/tools/clientSimulator/clientsimulator/criterion/CriterionClassFactory.py new file mode 100644 index 0000000..9c48919 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/criterion/CriterionClassFactory.py @@ -0,0 +1,84 @@ +# Copyright (c) 2014-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. + +from clientsimulator.criterion.Criterion import Criterion +from clientsimulator.criterion.ExclusiveCriterion import ExclusiveCriterion +from clientsimulator.criterion.InclusiveCriterion import InclusiveCriterion + + +class CriterionClassFactory: + + def __init__(self, criteriaFileName): + self.__criteriaFileName = criteriaFileName + + def __classFactory(self, name, allowedValues, base): + """ + Private function which allows to dynamically create a new Criterion SubClass + + :param name: name of the futur subclass + :type name: string + :param allowedValues: all values the criterion can take + :type allowedValues: string list + :param base: direct mother class of the created criterion subclass + should be InclusiveCriterion or ExclusiveCriterion + :type base: type + + :return: A criterion subclass + :rtype: type + """ + + def __init__(self): + """ Init Function of a Criterion Child Class """ + base.__init__(self) + + # Creation of the class with allowed values + # (allows to have only one instance of the list) + return type( + name, (base,), { + "__init__": __init__, "_allowedValues": allowedValues}) + + def generateCriterionClasses(self): + """ Function invoqued to generate Criterion Childs classes from an AudioCriteria file""" + + # Parsing criterions File + with open(self.__criteriaFileName, "r") as criteria: + criteriaLines = criteria.readlines() + + parsedCriteria = [(typeAndName.split(), allowedValues.split()) + for typeAndName, allowedValues + in (line.split(':') for line in criteriaLines)] + + generatedClasses = {} + # Creation of needed classes thanks to criteria File information, + # such as BaseClass, criterion name and possible values + generatedClasses = [ + self.__classFactory(className, allowedValues, globals()[classBase]) + for (classBase, className), allowedValues in parsedCriteria + ] + + return generatedClasses diff --git a/tools/clientSimulator/clientsimulator/criterion/ExclusiveCriterion.py b/tools/clientSimulator/clientsimulator/criterion/ExclusiveCriterion.py new file mode 100644 index 0000000..1902181 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/criterion/ExclusiveCriterion.py @@ -0,0 +1,59 @@ +# Copyright (c) 2014-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. + +from clientsimulator.criterion.Criterion import Criterion +from clientsimulator.criterion.Criterion import InvalidCriterionException + + +class ExclusiveCriterion(Criterion): + + """ + This file describe Exclusive Criterion Behavior + + This types of criterion can only have one value at a time + """ + + def __init__(self): + super().__init__() + self.__currentValue = None + + @property + def currentValue(self): + return self.__currentValue + + @currentValue.setter + def currentValue(self, currentValue): + if currentValue in self._allowedValues or currentValue == self.noValue: + self.__currentValue = currentValue + else: + raise InvalidCriterionException( + "Value {} is not allowed for {}.".format( + currentValue, self.__class__.__name__)) + + def __str__(self): + return self.__class__.__name__ + ' : ' + str(self.__currentValue) diff --git a/tools/clientSimulator/clientsimulator/criterion/InclusiveCriterion.py b/tools/clientSimulator/clientsimulator/criterion/InclusiveCriterion.py new file mode 100644 index 0000000..09ec308 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/criterion/InclusiveCriterion.py @@ -0,0 +1,95 @@ +# Copyright (c) 2014-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. + +from clientsimulator.criterion.Criterion import Criterion +from clientsimulator.criterion.Criterion import InvalidCriterionException + + +class InclusiveCriterion(Criterion): + + """ + This file describe Inclusive Criterion Behavior + + This types of criterion can have several values at the same time + """ + + def __init__(self): + super().__init__() + self.__currentValues = set() + + @property + def currentValue(self): + return self.__currentValues + + @currentValue.setter + def currentValue(self, stringNewVal): + """ + Criterion current value setter + + :param stringNewVal: the string containing desired values + separated by a space + :type stringNewVal: string + """ + + # TODO: Avoid string splitting by using a list as parameter + # Warning, we have chosen this solution for now because + # it avoids TestVectorFactory to test criterions type before + # to use this setter. Indeed, ExclusiveCriterion setter has + # exactly the same prototype. + valueList = stringNewVal.split() + + if self.noValue in valueList: + # if we put default value, we empty the list first + self.__currentValues = set() + self.__currentValues.add(self.noValue) + else: + # We set a value, we have to remove default is it's set + if self.noValue in self.__currentValues: + self.__currentValues.remove(self.noValue) + + for currentValue in valueList: + if currentValue in self._allowedValues \ + and currentValue != self.noValue: + self.__currentValues.add(currentValue) + else: + raise InvalidCriterionException( + "Value {} is not allowed for {}.".format( + currentValue, self.__class__.__name__)) + + def removeValue(self, currentValue): + if currentValue in self.__currentValues: + self.__currentValues.remove(currentValue) + else: + raise InvalidCriterionException( + "Value {} is not currently setted.".format(currentValue)) + # If there is no value, assume it's default + if not self.__currentValues: + self.__currentValues.append(self.noValue) + + def __str__(self): + return self.__class__.__name__ + ' : ' + str(self.__currentValues) diff --git a/tools/clientSimulator/clientsimulator/criterion/__init__.py b/tools/clientSimulator/clientsimulator/criterion/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/criterion/__init__.py diff --git a/tools/clientSimulator/clientsimulator/scenario/Scenario.py b/tools/clientSimulator/clientsimulator/scenario/Scenario.py new file mode 100644 index 0000000..965fbe9 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/scenario/Scenario.py @@ -0,0 +1,188 @@ +# Copyright (c) 2014-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. + +import json +import logging + + +class Scenario: + + """ + Class which can handle several TestVectors and script + to play a complete scenario. + """ + + def __init__(self, + consoleLogger, + scenarioFileName, + actionGathererFileName, + testFactory, + testLauncher): + """ + Init function + + :param consoleLogger: console log handler + :type consoleLogger: Handler + :param scenarioFileName: name of file containing scenario description + :type scenarioFileName: string + :param actionGathererFileName: conf file which allows to reduce action repetition + :type actionGathererFileName: string + :param testFactory: the factory used to generate tests from setCriterion actions + :type testFactory: TestVectorFactory + :param testLauncher: object used to execute actions from scenarios + :type testLauncher: TestLauncher + """ + self.__logger = logging.getLogger(__name__) + self.__logger.addHandler(consoleLogger) + + self.__testFactory = testFactory + self.__testLauncher = testLauncher + + # Simplify the way to get an action behaviour + # Python way to replace switch statement but keeping the possibility + # to get keys (usefull in __parseScenarioActions) + self.__actionTypeBehaviour = { + "setCriterion": + lambda rawCriterions: + self.__testLauncher.executeTestVector( + self.__testFactory.generateTestVector(rawCriterions)), + "script": + self.__testLauncher.executeScript + } + + self.__scenarioActions = self.__parseScenarioActions( + scenarioFileName, + actionGathererFileName) + + def __parseScenarioActions(self, scenarioFileName, actionGathererFileName): + """ + Parse actions from a scenario. + Convert user-defined actions in system-known actions. + + :param scenarioFileName: name of file containing scenario description + :type scenarioFileName: string + :param actionGathererFileName: conf file which allows to reduce action repetition + :type actionGathererFileName: string + + :return: parsed scenario's actions with system-known types + :rtype: dict + """ + + # Parsing of Json test file + with open(scenarioFileName, "r") as scenarioFile: + scenarioActions = json.load(scenarioFile) + + # Parsing the action Gatherer file which allows defining new + # actions types + scenarioGatheredActions = {} + if actionGathererFileName: + with open(actionGathererFileName, "r") as actionGathererFile: + scenarioGatheredActions = json.load(actionGathererFile) + + for action in scenarioActions: + actionDefinedType = self.__getActionType(action) + if actionDefinedType in self.__actionTypeBehaviour.keys(): + continue + + try: + actionValue = action.pop(actionDefinedType) + actionGatherer = scenarioGatheredActions[actionDefinedType] + except KeyError as e: + self.__logger.error( + "Actions {} from {} file is not valid".format( + actionDefinedType, + scenarioFileName)) + raise e + + if self.__getActionType(actionGatherer) == "script": + raise UngatherableTypeException( + "Unable to redefine {} type, please edit your {} file".format( + self.__getActionType(actionGatherer), + actionGathererFileName)) + + # Fusion of gathered Actions and other desired actions which + # are directly writed in the scenario's file + actionValue.update(self.__getActionValue(actionGatherer)) + + # Change the user defined key which was previously popped + # by the known one + action[self.__getActionType(actionGatherer)] = actionValue + + return scenarioActions + + def __getActionType(self, action): + """ + Return the type of an action (the key) + An action is a dictionary with only one element + + :param action: the action you want to get the type + :type action: dict + + :return: the type of the desired action + :rtype: string + """ + return list(action.keys())[0] + + def __getActionValue(self, action): + """ + Return the Value of an action + An action is a dictionary with only one element + + :param action: the action you want to get the type + :type action: dict + + :return: the value of the desired action + :rtype: string or dict + """ + return list(action.values())[0] + + def play(self): + """ + Execute a Scenario + """ + + for action in self.__scenarioActions: + # Launch the adequate behaviour depending on the key of the action dict + # No need to try KeyError as it would have been raised during init + # process + self.__actionTypeBehaviour[self.__getActionType(action)]( + self.__getActionValue(action)) + + +class UngatherableTypeException(Exception): + + """ + Exception raised in case of problem with a type that the + user try to personalize + """ + + def __init__(self, msg): + self.__msg = msg + + def __str__(self): + return "Ungatherable type Error : " + self.__msg diff --git a/tools/clientSimulator/clientsimulator/scenario/__init__.py b/tools/clientSimulator/clientsimulator/scenario/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/scenario/__init__.py diff --git a/tools/clientSimulator/clientsimulator/testGenerator/SubprocessLogger.py b/tools/clientSimulator/clientsimulator/testGenerator/SubprocessLogger.py new file mode 100644 index 0000000..bd73dae --- /dev/null +++ b/tools/clientSimulator/clientsimulator/testGenerator/SubprocessLogger.py @@ -0,0 +1,205 @@ +# Copyright (c) 2014-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. + +import threading +import subprocess +import logging +import signal +import os + + +class StreamLoggerThread(threading.Thread): + + """ File-like object used to log Popen stdout and stderr streams """ + + def __init__(self, consoleLogger, level, name): + """ + StreamLoggerThread Object initializer + + :param consoleLogger: console log handler + :type consoleLogger: Handler + :param level: desired logger level of the stream + :type level: logging.level + :param name: Thread name + :type name: string + """ + super().__init__() + + # Pipe to interact with subprocess + self.__readFd, self.__writeFd = os.pipe() + + self.__logger = logging.getLogger(__name__) + self.__logger.addHandler(consoleLogger) + + self.__level = level + + self.name = name + + # Start stream logging + self.start() + + def fileno(self): + """ Give Writing side of internal pipe to receive data """ + + return self.__writeFd + + def run(self): + """ Read the reading side of the pipe until EOF """ + + with os.fdopen(self.__readFd) as stream: + for line in stream: + self.__logger.log(self.__level, line.strip('\n')) + + def close(self): + """ Close writing pipe side """ + + os.close(self.__writeFd) + + +class SubprocessLoggerThread(threading.Thread): + + """ This class is here to log long process stdout and stderr """ + + # Event used to ask all SubprocessLoggerThread object to die + __closeEvent = threading.Event() + + def __init__(self, cmd, consoleLogger): + """ + SubprocessLoggerThread Object initializer + + :param cmd: command to launch + :type cmd: list + :param consoleLogger: console log handler + :type consoleLogger: Handler + """ + + super().__init__() + + self.__cmd = cmd + self.__subProc = None + + self.name = "Thread : " + ' '.join(cmd) + + self.__consoleLogger = consoleLogger + + # Default logging level + self._stdOutLogLevel = logging.DEBUG + + @classmethod + def closeAll(cls): + """ Set the closeEvent to ask the thread to die """ + cls.__closeEvent.set() + + def __cleanup(self): + """ + Close properly the child with SIGINT. + + The signal is sended to all the group to kill + subprocess launched by Popen + """ + os.killpg(self.__subProc.pid, signal.SIGINT) + + def __subProcPreExec(self): + """ + Make Popen object a Group leader. + + Avoid subprocess to receive signal destinated + to the MainThread. + """ + os.setpgrp() + + def run(self): + """ Create Popen object and manage it """ + + # Logging threaded file-object + stdOutLogger = StreamLoggerThread( + self.__consoleLogger, + self._stdOutLogLevel, + self.name + "STDOUT") + stdErrLogger = StreamLoggerThread( + self.__consoleLogger, + logging.ERROR, + self.name + "STDERR") + + # Logging stdout and stderr through objects + self.__subProc = subprocess.Popen( + [os.getenv("SHELL"), "-c", ' '.join(self.__cmd)], + bufsize=1, + stdout=stdOutLogger, + stderr=stdErrLogger, + preexec_fn=self.__subProcPreExec, + shell=False) + + # Waiting process close or closing order + while True: + try: + # We end the thread if we are requested to do so + if SubprocessLoggerThread.__closeEvent.wait(0.01): + self.__cleanup() + break + + # or if the subprocess is dead + if self.__subProc.poll() is not None: + break + except KeyboardInterrupt: + continue + + # Close pipes + if stdOutLogger.is_alive(): + stdOutLogger.close() + if stdErrLogger.is_alive(): + stdErrLogger.close() + + +class ScriptLoggerThread(SubprocessLoggerThread): + + """ This class is used to log script subprocess """ + + def __init__(self, cmd, consoleLogger): + """ + ScriptLoggerThread Object initializer + + :param cmd: command to launch + :type cmd: list + :param consoleLogger: console log handler + :type consoleLogger: Handler + """ + super().__init__(cmd, consoleLogger) + + # Script logging level + self._stdOutLogLevel = logging.INFO + + @classmethod + def getRunningInstances(cls): + """ + Running ScriptLoggerThread instances getter + + :return: The list of running ScriptLoggerThread instances + :rtype: list + """ + return [t for t in threading.enumerate() if isinstance(t, cls)] diff --git a/tools/clientSimulator/clientsimulator/testGenerator/TestLauncher.py b/tools/clientSimulator/clientsimulator/testGenerator/TestLauncher.py new file mode 100644 index 0000000..eb68bfb --- /dev/null +++ b/tools/clientSimulator/clientsimulator/testGenerator/TestLauncher.py @@ -0,0 +1,203 @@ +# Copyright (c) 2014-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. + +from clientsimulator.criterion.ExclusiveCriterion import ExclusiveCriterion +from clientsimulator.configuration.ConfigParser import ConfigParser +from clientsimulator.testGenerator.SubprocessLogger import SubprocessLoggerThread +from clientsimulator.testGenerator.SubprocessLogger import ScriptLoggerThread +import logging +import json +import time +import os + + +class TestLauncher: + + """ Class which interacts with the system to launch tests """ + + def __init__(self, + criterionClasses, + configParser, + consoleLogger): + """ + Here we create commands to launch thanks to the config Parser + + :param criterionClasses: runtime generated criterion classes + :type criterionClasses: list of types + :param configParser: object which allows to get config parameters + :type configParser: ConfigParser + :param consoleLogger: console log handler + :type consoleLogger: Handler + """ + self.__criterionClasses = criterionClasses + self.__configParser = configParser + + # Prepare basic commands + halCommand = ["remote-process", + "localhost", + configParser["TestPlatformPort"]] + setCriteriaCommand = halCommand + ["setCriterionState"] + testPlatformHostCommand = ["remote-process", + "localhost", + configParser["TestPlatformPort"]] + + self.__logFileName = configParser["LogFile"] + + # Commands + self.__startTestPlatformCmd = [configParser["PrefixCommand"], + "test-platform", + configParser["PfwConfFile"], + configParser["TestPlatformPort"]] + + self.__createCriterionCmd = [configParser["PrefixCommand"]] + self.__createCriterionCmd.extend(testPlatformHostCommand) + + self.__startPseudoHALCmd = [configParser["PrefixCommand"]] + self.__startPseudoHALCmd.extend(testPlatformHostCommand) + self.__startPseudoHALCmd.append("start") + + self.__setCriterionCmd = [configParser["PrefixCommand"]] + self.__setCriterionCmd.extend(setCriteriaCommand) + + self.__applyConfigurationsCmd = [configParser["PrefixCommand"]] + self.__applyConfigurationsCmd.extend(halCommand) + self.__applyConfigurationsCmd.append("applyConfigurations") + + # Command used to generate coverage + self.__coverageCmd = [ + "eval", + os.path.join(configParser["CoverageDir"], "aplog2coverage.sh"), + "-d", + configParser["PfwDomainConfFile"], + "-e.", + self.__logFileName, + "-f", + "-o", + configParser["CoverageFile"] + ] + + # Prepare script Commands + # Loading possible scripts + self.__rawScripts = {} + if configParser["ScriptsFile"]: + with open(configParser["ScriptsFile"], 'r') as scriptFile: + self.__rawScripts = json.load(scriptFile) + + self.__availableLaunchType = ["asynchronous", "synchronous"] + + self.__consoleLogger = consoleLogger + self.__logger = logging.getLogger(__name__) + self.__logger.addHandler(consoleLogger) + + @property + def scripts(self): + return self.__rawScripts.keys() + + def init(self, criterionClasses, isVerbose): + """ Initialise the Pseudo HAL """ + + self.__logger.info("Pseudo Hal Initialisation") + # Test platform is launched asynchronously and not as script + self.__call_process(self.__startTestPlatformCmd, True) + # wait Initialisation + time.sleep(1) + + for criterionClass in criterionClasses: + if ExclusiveCriterion in criterionClass.__bases__: + createSlctCriterionCmd = "createExclusiveSelectionCriterionFromStateList" + else: + createSlctCriterionCmd = "createInclusiveSelectionCriterionFromStateList" + + createCriterionArgs = [ + createSlctCriterionCmd, + criterionClass.__name__] + criterionClass.allowedValues() + + self.__call_process( + self.__createCriterionCmd + createCriterionArgs) + + self.__call_process(self.__startPseudoHALCmd) + + def executeTestVector(self, criterions): + """ Launch the Test """ + for criterion in criterions: + if ExclusiveCriterion in criterion.__class__.__bases__: + criterionValue = [criterion.currentValue] + else: + criterionValue = criterion.currentValue + # If no value given, we add "" to the command to set the default state + criterionValueArg = list(criterionValue) if list(criterionValue) else ["\"\""] + setCriterionArgs = [criterion.__class__.__name__] + criterionValueArg + self.__call_process(self.__setCriterionCmd + setCriterionArgs) + + # Applying conf + self.__call_process(self.__applyConfigurationsCmd) + + def executeScript(self, scriptName): + """ Launching desired test scripts """ + + (script, launchType) = self.__rawScripts[scriptName] + + if not launchType in self.__availableLaunchType: + errorMessage = "Launch type ({}) for script {} isn't recognized. ".format( + launchType, + scriptName) + errorMessage += "Default value ({}) has been applied.".format( + self.__availableLaunchType[0]) + + self.__logger.error(errorMessage) + launchType = self.__availableLaunchType[0] + + # Create and launch the command to use the desired script + # A script's path is absolute or relative to the "ScriptsFile" file. + self.__call_process( + ["eval", os.path.join( + os.path.dirname(self.__configParser["ScriptsFile"]), + script)], + launchType == self.__availableLaunchType[0], + True) + + def generateCoverage(self): + """ Launch Coverage Tool on generated Log and save results in dedicated file """ + self.__logger.debug("Generating coverage file") + self.__call_process(self.__coverageCmd) + + def __call_process(self, cmd, isAsynchronous=False, isScriptThread=False): + """ Private function which call a shell command """ + + if isScriptThread: + self.__logger.info("Launching script : {}".format(' '.join(cmd))) + launcher = ScriptLoggerThread(cmd, self.__consoleLogger) + else: + self.__logger.debug("Launching command : {}".format(' '.join(cmd))) + launcher = SubprocessLoggerThread(cmd, self.__consoleLogger) + + launcher.start() + + if not isAsynchronous: + # if the process is synchronous, we wait him before continuing + launcher.join() diff --git a/tools/clientSimulator/clientsimulator/testGenerator/TestVectorFactory.py b/tools/clientSimulator/clientsimulator/testGenerator/TestVectorFactory.py new file mode 100644 index 0000000..94bbf75 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/testGenerator/TestVectorFactory.py @@ -0,0 +1,78 @@ +# Copyright (c) 2014-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. + +import logging + + +class TestVectorFactory: + + """ + Factory of Test Vectors Objects + """ + + def __init__(self, criterionClasses, consoleLogger): + """ + Init function + + :param criterionClasses: available criterion types + :type criterionClasses: list of classes + :param consoleLogger: console log handler + :type consoleLogger: Handler + """ + self.__criterionClasses = criterionClasses + self.__logger = logging.getLogger(__name__) + self.__logger.addHandler(consoleLogger) + + def generateTestVector(self, rawCriterions=None): + """ + Function invoqued to generate TestVector object + + :param rawCriterions: the desired criterions state descriptions + :type rawCriterions: dictionnary + """ + + criterions = [] + + for criterionClass in self.__criterionClasses: + # Instanciate the criterion class requested + newCriterion = criterionClass() + + if rawCriterions: + try: + newCriterion.currentValue = rawCriterions[ + criterionClass.__name__] + criterions.append(newCriterion) + except KeyError as e: + self.__logger.debug( + "Missing Criterion {}, old value keeped".format( + criterionClass.__name__)) + else: + # if rawCriterions is None, we create an empty criterions lists + newCriterion.currentValue = newCriterion.noValue + criterions.append(newCriterion) + return criterions diff --git a/tools/clientSimulator/clientsimulator/testGenerator/__init__.py b/tools/clientSimulator/clientsimulator/testGenerator/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/testGenerator/__init__.py diff --git a/remote-processor/Android.mk b/tools/clientSimulator/clientsimulator/userInteraction/DynamicCallHelper.py index 124eb71..f6d56c3 100644 --- a/remote-processor/Android.mk +++ b/tools/clientSimulator/clientsimulator/userInteraction/DynamicCallHelper.py @@ -1,4 +1,4 @@ -# Copyright (c) 2011-2014, Intel Corporation +# Copyright (c) 2014-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,66 +26,49 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -LOCAL_PATH := $(call my-dir) -#################### -# Common definitions +class DynamicCallHelper: -common_src_files := \ - Socket.cpp \ - ListeningSocket.cpp \ - ConnectionSocket.cpp \ - Message.cpp \ - RequestMessage.cpp \ - AnswerMessage.cpp \ - RemoteProcessorServer.cpp \ - RemoteProcessorServerBuilder.cpp + """ + Callable object which wrap a function call. -common_module := libremote-processor -common_module_tags := optional + This simple class is designed to avoid the use of lambda + hack to capture arguments when generating function call. + Indeed, to generate a call to a function which take + parameters at runtime, we need to force the copy by capture + of the parameter by using default value such as : -common_cflags := \ - -Wall \ - -Werror \ - -Wextra \ - -Wno-unused-parameter \ + callerDict = { + a: lambda a=a : print(a) + for a in range(5) + } -############################# -# Target build + With the DynamicCallHelper you can simply use : -include $(CLEAR_VARS) + callerDict = { + DynamicCallHelper(print, a) + for a in range(5) + } + """ -LOCAL_SRC_FILES := $(common_src_files) + def __init__(self, func, *args): + """ + Init method -LOCAL_STATIC_LIBRARIES := libpfw_utility + :param func: the function that will be called when calling the object + :type func: function + :param *args: arguments destinated to func + :type *args: list + """ -LOCAL_CFLAGS := $(common_cflags) + self.__func = func + self.__args = args -LOCAL_MODULE := $(common_module) -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) + def __call__(self): + """ + Call the function __func with __args as arguments -ifeq ($(INCLUDE_STLPORT), true) -include external/stlport/libstlport.mk -endif + :return: __func return + """ -include $(BUILD_SHARED_LIBRARY) - -############################## -# Host build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_STATIC_LIBRARIES := libpfw_utility_host - -LOCAL_CFLAGS := $(common_cflags) -pthread -LOCAL_LDLIBS := -lpthread - -LOCAL_MODULE := $(common_module)_host -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - - -include $(BUILD_HOST_SHARED_LIBRARY) + return self.__func(*self.__args) diff --git a/tools/clientSimulator/clientsimulator/userInteraction/UserInteractor.py b/tools/clientSimulator/clientsimulator/userInteraction/UserInteractor.py new file mode 100644 index 0000000..d695705 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/userInteraction/UserInteractor.py @@ -0,0 +1,188 @@ +# Copyright (c) 2014-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. + +from clientsimulator.criterion.InclusiveCriterion import InclusiveCriterion +from clientsimulator.testGenerator.TestLauncher import TestLauncher +from clientsimulator.userInteraction.DynamicCallHelper import DynamicCallHelper + + +class UserInteractor: + + """ + Define all user interactions the program can have. + + Allows to run the interactive mode and dynamics menus. + """ + + def __init__(self, testLauncher, criterions): + """ + Init function of user interactor + + :param testLauncher: object which allows to run tests + :type testLauncher: TestLauncher + """ + + self.__testLauncher = testLauncher + self.__criterions = criterions + + @classmethod + def getMenu(cls, options, cancelSentence="Go Back"): + """ + Dynamic Menu Generator : + + :param options: list containing tuples of a) the invite string and + b) the function to launch + :type options: list + :param cancelSentence: title of the menu entry that will be + appended after the provided options, in order to exit the menu. For + top-level menus, it is advised to pass "Quit" as argument. + :type cancelSentence: string + """ + + while True: + print("\nPlease Make a choice : ") + for numMenu, (sentenceMenu, fonc) in enumerate(options): + print("\t{}. {}".format(numMenu, sentenceMenu)) + + # Lastly, append an option to go to the previous menu/quit + print("\t{}. {}".format(len(options), cancelSentence)) + + choice = input("Your Choice : ") + try: + choice = int(choice) + if choice == len(options): + # The user has selected the "cancel" option + break + if choice < 0: + # Negative values make no sense + raise KeyError(choice) + + options[choice][1]() + except (KeyError, ValueError) as e: + print("Invalid Choice : {}".format(e)) + + def launchInteractiveMode(self): + """ + Interactive Mode : Set up a menu which allow + users to personnalize a Test and to Launch it + """ + optionsMenu = [ + ("Edit Vector", self.__editVector), + ("Apply Configuration", self.__applyConfiguration), + ("Launch Script", self.__launchScript) + ] + + UserInteractor.getMenu(optionsMenu, "Quit") + + def __applyConfiguration(self): + """ + Apply the configuration described in the + current criterions state. + """ + + self.__testLauncher.executeTestVector(self.__criterions) + + return True + + def __launchScript(self): + """ + Display the menu which let the user choose an available + script to run. + """ + + optionScript = [ + ("Execute {}".format(script), + DynamicCallHelper(self.__testLauncher.executeScript, script)) + for script in self.__testLauncher.scripts + ] + + UserInteractor.getMenu(optionScript) + + return True + + def __setCriterion(self, criterion, value): + criterion.currentValue = value + + def __removeCriterionValue(self, criterion, value): + criterion.removeValue(value) + + def __editCriterion(self, criterion): + """ + Allow to change the value of a criterion through a menu. + + :param criterion: the criterion to edit + :type criterion: Criterion + """ + + optionEditCriterion = [] + for possibleValue in [x for x in criterion.allowedValues() + if not x in criterion.currentValue + and not x == criterion.noValue]: + optionEditCriterion.append( + ("Set {}".format(possibleValue), + DynamicCallHelper( + self.__setCriterion, + criterion, + possibleValue))) + + if InclusiveCriterion in criterion.__class__.__bases__: + # Inclusive criterion : display unset value (default when empty) + for possibleValue in criterion.currentValue: + optionEditCriterion.append( + ("Unset {}".format(possibleValue), + DynamicCallHelper( + self.__removeCriterionValue, + criterion, + possibleValue))) + else: + # Exclusive criterion : display default value + optionEditCriterion.append( + ("Set Default", + DynamicCallHelper( + self.__setCriterion, + criterion, + criterion.noValue))) + + UserInteractor.getMenu(optionEditCriterion) + + return True + + def __editVector(self): + """ + Allow to change the value of several criterions through a menu. + """ + + optionEdit = [ + ("Edit {}".format(cri.__class__.__name__), + DynamicCallHelper(self.__editCriterion, cri)) + for cri in self.__criterions + ] + + UserInteractor.getMenu(optionEdit) + + return True diff --git a/tools/clientSimulator/clientsimulator/userInteraction/__init__.py b/tools/clientSimulator/clientsimulator/userInteraction/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/clientSimulator/clientsimulator/userInteraction/__init__.py diff --git a/tools/clientSimulator/pfClientSimulator.py b/tools/clientSimulator/pfClientSimulator.py new file mode 100755 index 0000000..f58c838 --- /dev/null +++ b/tools/clientSimulator/pfClientSimulator.py @@ -0,0 +1,218 @@ +#!/usr/bin/python3 +# Copyright (c) 2014-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. + +from clientsimulator.criterion.CriterionClassFactory import CriterionClassFactory +from clientsimulator.testGenerator.TestVectorFactory import TestVectorFactory +from clientsimulator.testGenerator.TestLauncher import TestLauncher +from clientsimulator.testGenerator.SubprocessLogger import SubprocessLoggerThread +from clientsimulator.testGenerator.SubprocessLogger import ScriptLoggerThread +from clientsimulator.configuration.ConfigParser import ConfigParser +from clientsimulator.scenario.Scenario import Scenario +from clientsimulator.userInteraction.UserInteractor import UserInteractor +from clientsimulator.userInteraction.DynamicCallHelper import DynamicCallHelper +import argparse +import time +import logging +import os + + +def close(logger, testLauncher, coverage): + """ SIGINT Handler which clean up processes """ + + # Check if some scripts are running, if this is the case + # we warn the user. + if ScriptLoggerThread.getRunningInstances(): + try: + logger.info("{} \n {}".format( + "Some subprocesses are still running. The program will wait them before exiting.", + "If you really want to exit, please confirm by typing Ctrl+C again")) + + # Wait for thread to terminate + while ScriptLoggerThread.getRunningInstances(): + time.sleep(1) + except KeyboardInterrupt as e: + pass + + # Kill subprocess (at least test-platform one) + SubprocessLoggerThread.closeAll() + + if coverage: + testLauncher.generateCoverage() + + logger.info("Closing") + + exit(0) + + +def launchScenario( + logger, + consoleLogger, + actionGathererFileName, + scenarioFileName, + testFactory, + testLauncher): + + logger.info("Launching {}".format(scenarioFileName)) + + Scenario(consoleLogger, + scenarioFileName, + actionGathererFileName, + testFactory, + testLauncher).play() + + logger.info("Scenario execution complete.") + + +def main(): + + # Handle Arguments + + parser = argparse.ArgumentParser() + + parser.add_argument("test_directory", type=str, default=None, + help="precise a test directory (required).") + + parser.add_argument("-s", "--scenario", type=int, default=None, nargs='+', + help="precise one or more scenarios to launch.") + + interactiveness = parser.add_mutually_exclusive_group() + interactiveness.add_argument("--no-exit", action='store_true', + help="lets you interactively select more scenarios (This is" + " implicit if neither '--scenario' nor '--interactive' are " + " passed).") + + interactiveness.add_argument("--interactive", action='store_true', + help="run in interactive mode (lets you select actions and scripts" + " to run).") + + parser.add_argument( + "-v", + "--verbose", + action='store_true', + help="display test-platform's and scripts' log on stdout.") + + parser.add_argument("-c", "--coverage", action='store_true', + help="generate coverage file at end of script") + + args = parser.parse_args() + + # Logging Configuration + logger = logging.getLogger(__name__) + + # Decide what to write in console depending on verbose argument + consoleLogger = logging.StreamHandler() + if args.verbose: + consoleLogger.setLevel(logging.DEBUG) + else: + consoleLogger.setLevel(logging.INFO) + logger.addHandler(consoleLogger) + + # The given directory should have a conf.json file + if not os.path.isfile(os.path.join(args.test_directory, "conf.json")): + # This error will only be logged in the terminal + logger.error( + "Cannot find configuration file : conf.json in {} directory.".format( + args.test_directory)) + exit(1) + + try: + configParser = ConfigParser( + os.path.join( + args.test_directory, + "conf.json"), + args.test_directory, + consoleLogger) + except KeyError as e: + logger.error( + "Missing mandatory configuration item {} in the" + " conf.json file".format(e)) + exit(1) + + # Always write all log in the file + logging.basicConfig(level=logging.DEBUG, + format='%(name)-12s %(levelname)-8s %(message)s', + filename=configParser["LogFile"], + filemode='w') + + # Parsing criterion file and classes generation + logger.info("Criterion analysis") + classFactory = CriterionClassFactory(configParser["CriterionFile"]) + criterionClasses = classFactory.generateCriterionClasses() + + # Tests Handlers Generation + testFactory = TestVectorFactory( + criterionClasses, + consoleLogger) + + testLauncher = TestLauncher( + criterionClasses, + configParser, + consoleLogger) + + # Initialisation + testLauncher.init(criterionClasses, args.verbose) + + # Launching + try: + if args.interactive: + # Launch Interactive Mode with default criterions values + UserInteractor( + testLauncher, + testFactory.generateTestVector()).launchInteractiveMode() + else: + scenarioOptions = [ + (scenarioFileName, + DynamicCallHelper( + launchScenario, + logger, + consoleLogger, + configParser["ActionGathererFile"], + os.path.join( + configParser["ScenariosDirectory"], scenarioFileName), + testFactory, + testLauncher + )) + for scenarioFileName in sorted(os.listdir(configParser["ScenariosDirectory"])) + ] + if args.scenario is not None: + for elem in args.scenario: + scenarioOptions[elem][1]() + if (args.scenario is None) or args.no_exit: + # Let the user choose more scenarios after the ones chosen by command line + # or if none was given on the command line. + UserInteractor.getMenu(scenarioOptions, "Quit") + except KeyboardInterrupt as e: + close(logger, testLauncher, args.coverage) + else: + close(logger, testLauncher, args.coverage) + + +if __name__ == "__main__": + # Execute main if the script is running as main + main() diff --git a/tools/xmlGenerator/Android.mk b/tools/xmlGenerator/Android.mk deleted file mode 100644 index 43256ed..0000000 --- a/tools/xmlGenerator/Android.mk +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) 2011-2014, 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. - - -LOCAL_PATH := $(call my-dir) - -################################################## -# Scripts are not compiled so the prebuild mechanism is used to export them. - -include $(CLEAR_VARS) -LOCAL_MODULE := EddParser.py -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := PfwBaseTranslator.py -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := PFWScriptGenerator.py -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - PfwBaseTranslator.py \ - EddParser.py -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := hostConfig.py -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := domainGenerator.py -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -LOCAL_REQUIRED_MODULES := \ - _PyPfw_32 \ - EddParser.py \ - PfwBaseTranslator.py \ - hostConfig.py -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := portAllocator.py -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := hostDomainGenerator.sh -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_REQUIRED_MODULES := \ - PFWScriptGenerator.py \ - hostConfig.py \ - portAllocator.py \ - test-platform_host \ - remote-process_host \ - ParameterFrameworkConfiguration.xsd \ - ConfigurableDomains.xsd \ - SystemClass.xsd \ - ParameterSettings.xsd \ - FileIncluder.xsd \ - Subsystem.xsd \ - ComponentLibrary.xsd \ - ComponentTypeSet.xsd \ - W3cXmlAttributes.xsd \ - Parameter.xsd -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := lightRoutingUpdate.sh -LOCAL_MODULE_OWNER := intel -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_REQUIRED_MODULES := \ - PFWScriptGenerator.py -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_IS_HOST_MODULE := true -include $(BUILD_PREBUILT) -################################################## diff --git a/tools/xmlGenerator/CMakeLists.txt b/tools/xmlGenerator/CMakeLists.txt index 5dba835..72d1d95 100644 --- a/tools/xmlGenerator/CMakeLists.txt +++ b/tools/xmlGenerator/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2014-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,15 +26,18 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +add_executable(domainGeneratorConnector domainGeneratorConnector.cpp) +target_link_libraries(domainGeneratorConnector PRIVATE parameter pfw_utility) + +install(TARGETS domainGeneratorConnector RUNTIME DESTINATION bin) + install(PROGRAMS domainGenerator.sh domainGenerator.py hostConfig.py - hostDomainGenerator.sh lightRoutingUpdate.sh PfwBaseTranslator.py EddParser.py PFWScriptGenerator.py - portAllocator.py updateRoutageDomains.sh DESTINATION bin) diff --git a/tools/xmlGenerator/PFWScriptGenerator.py b/tools/xmlGenerator/PFWScriptGenerator.py index d1996d1..f43e317 100755 --- a/tools/xmlGenerator/PFWScriptGenerator.py +++ b/tools/xmlGenerator/PFWScriptGenerator.py @@ -44,63 +44,35 @@ class PfwScriptTranslator(PfwBaseTranslator): def getScript(self): return self._script + def _appendCommand(self, *args): + self._script.append(list(args)) + def _doCreateDomain(self, name): - self._script.append( - "{cmd} {domain}".format( - cmd="createDomain", - domain=name)) + self._appendCommand("createDomain", name) def _doSetSequenceAware(self): - self._script.append( - "{cmd} {domain} {aware}".format( - cmd="setSequenceAwareness", - domain=self._ctx_domain, - aware="true")) + self._appendCommand("setSequenceAwareness", self._ctx_domain, "true") def _doAddElement(self, path): - self._script.append( - "{cmd} {domain} {path}".format( - cmd="addElement", - domain=self._ctx_domain, - path=path)) + self._appendCommand("addElement", self._ctx_domain, path) def _doCreateConfiguration(self, name): - self._script.append( - "{cmd} {domain} {config}".format( - cmd="createConfiguration", - domain=self._ctx_domain, - config=name)) + self._appendCommand("createConfiguration", self._ctx_domain, name) def _doSetElementSequence(self, paths): - self._script.append( - "{cmd} {domain} {config} {paths}".format( - cmd="setElementSequence", - domain=self._ctx_domain, - config=self._ctx_configuration, - paths=" ".join(paths))) + self._appendCommand("setElementSequence", self._ctx_domain, self._ctx_configuration, *paths) def _doSetRule(self, rule): - self._script.append( - "{cmd} {domain} {config} {rule}".format( - cmd="setRule", - domain=self._ctx_domain, - config=self._ctx_configuration, - rule=rule)) + self._appendCommand("setRule", self._ctx_domain, self._ctx_configuration, rule) def _doSetParameter(self, path, value): - self._script.append( - "{cmd} {domain} {config} {path} '{value}'".format( - cmd="setConfigurationParameter", - domain=self._ctx_domain, - config=self._ctx_configuration, - path=path, - value=value)) + self._appendCommand("setConfigurationParameter", self._ctx_domain, self._ctx_configuration, path, value) class ArgparseArgumentParser(object) : """class that parse command line arguments with argparse library result of parsing are the class atributs""" - def __init__(self) : + def __init__(self): myArgParser = argparse.ArgumentParser(description='Process domain scripts.') diff --git a/tools/xmlGenerator/README.md b/tools/xmlGenerator/README.md index d7d8812..78c714d 100644 --- a/tools/xmlGenerator/README.md +++ b/tools/xmlGenerator/README.md @@ -202,7 +202,6 @@ It prints the resulting XML on the standard output. Its syntax is: [--add-domains XML_DOMAIN_FILE [XML_DOMAIN_FILE ...]] [--add-edds EDD_FILE [EDD_FILE ...]] [--schemas-dir SCHEMAS_DIR] - [--target-schemas-dir TARGET_SCHEMAS_DIR] [--validate] [--verbose] *Explanation:* @@ -222,10 +221,6 @@ It prints the resulting XML on the standard output. Its syntax is: - The optional `--schemas-dir` argument lets you change the directory containing the XML Schemas in the context of the XML generation only (see the `--validate` option). -- The optional `--target-schemas-dir` argument lets you change the directory - containing the XML Schemas on the target device (the one the - parameter-framework will run on) if it is using Schema validation and if - different than the default. - The optional `--validate` option check the validity of all XML files involved in the process. @@ -246,17 +241,5 @@ InclusiveCriterion Criterion2Name : Criterion2Value1 Criterion2Value2 I.e. One criterion by line, starting by its kind, then its name, followed by a semicolon and then all possible values separated by spaces. -### hostDomainGenerator.sh - -**This script is now deprecated and replaced by domainGenerator.py -(see above).** - -It prints the resulting XML on the standard output. Its syntax is: - - hostDomainGenerator.sh [--validate] <top-level configuration file> <criteria file> <EDD files...> - -See domainGenerator.py above for the explanation of the arguments. - - #### How it works TODO diff --git a/tools/xmlGenerator/domainGenerator.py b/tools/xmlGenerator/domainGenerator.py index 427c8d5..0fade85 100755 --- a/tools/xmlGenerator/domainGenerator.py +++ b/tools/xmlGenerator/domainGenerator.py @@ -1,6 +1,6 @@ #! /usr/bin/python # -# Copyright (c) 2011-2014, Intel Corporation +# Copyright (c) 2011-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -28,9 +28,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import PyPfw import EddParser -from PfwBaseTranslator import PfwBaseTranslator, PfwException +from PFWScriptGenerator import PfwScriptTranslator import hostConfig import argparse @@ -39,90 +38,12 @@ import sys import tempfile import os import logging +import subprocess -def wrap_pfw_error_semantic(func): - def wrapped(*args, **kwargs): - ok, error = func(*args, **kwargs) - if not ok: - raise PfwException(error) - - return wrapped - -class PfwTranslator(PfwBaseTranslator): - """Generates calls to the Pfw's python bindings""" - - def __init__(self, pfw_instance, error_handler): - super(PfwTranslator, self).__init__() - self._pfw = pfw_instance - self._error_handler = error_handler - - def _handleException(self, ex): - if isinstance(ex, PfwException): - # catch and handle translation errors... - self._error_handler(ex, self._getContext()) - else: - # ...but let any other error fall through - raise ex - - @wrap_pfw_error_semantic - def _doCreateDomain(self, name): - return self._pfw.createDomain(name) - - @wrap_pfw_error_semantic - def _doSetSequenceAware(self): - return self._pfw.setSequenceAwareness(self._ctx_domain, True) - - @wrap_pfw_error_semantic - def _doAddElement(self, path): - return self._pfw.addConfigurableElementToDomain(self._ctx_domain, path) - - @wrap_pfw_error_semantic - def _doCreateConfiguration(self, name): - return self._pfw.createConfiguration(self._ctx_domain, name) - - @wrap_pfw_error_semantic - def _doSetElementSequence(self, paths): - return self._pfw.setElementSequence(self._ctx_domain, self._ctx_configuration, paths) - - @wrap_pfw_error_semantic - def _doSetRule(self, rule): - return self._pfw.setApplicationRule(self._ctx_domain, self._ctx_configuration, rule) - - @wrap_pfw_error_semantic - def _doSetParameter(self, path, value): - ok, _, error = self._pfw.accessConfigurationValue( - self._ctx_domain, self._ctx_configuration, path, value, True) - - return ok, error - - -class PfwTranslationErrorHandler: - def __init__(self): - self._errors = [] - self._hasFailed = False - - def __call__(self, error, context): - sys.stderr.write("Error in context {}:\n\t{}\n".format(context, error)) - self._hasFailed = True - - def hasFailed(self): - return self._hasFailed - -class PfwLogger(PyPfw.ILogger): - def __init__(self): - super(PfwLogger, self).__init__() - self.__logger = logging.root.getChild("parameter-framework") - - def log(self, is_warning, message): - log_func = self.__logger.warning if is_warning else self.__logger.info - log_func(message) - -# If this file is directly executed -if __name__ == "__main__": - logging.root.setLevel(logging.INFO) - +def parseArgs(): argparser = argparse.ArgumentParser(description="Parameter-Framework XML \ - Settings file generator") + Settings file generator.\n\ + Exit with the number of (recoverable or not) error that occured.") argparser.add_argument('--toplevel-config', help="Top-level parameter-framework configuration file. Mandatory.", metavar="TOPLEVEL_CONFIG_FILE", @@ -137,6 +58,7 @@ if __name__ == "__main__": help="Initial XML settings file (containing a \ <ConfigurableDomains> tag", nargs='?', + default=None, metavar="XML_SETTINGS_FILE") argparser.add_argument('--add-domains', help="List of single domain files (each containing a single \ @@ -157,20 +79,17 @@ if __name__ == "__main__": validation", default=None) argparser.add_argument('--target-schemas-dir', - help="Directory of parameter-framework XML Schemas on target \ - machine (may be different than generating machine). \ - Defaults to \"Schemas\"", - default="Schemas") + help="Ignored. Kept for retro-compatibility") argparser.add_argument('--validate', help="Validate the settings against XML schemas", action='store_true') argparser.add_argument('--verbose', action='store_true') - args = argparser.parse_args() + return argparser.parse_args() - # - # Criteria file +def parseCriteria(criteriaFile): + # Parse a criteria file # # This file define one criteria per line; they should respect this format: # @@ -185,16 +104,15 @@ if __name__ == "__main__": r"(?P<name>\S+)\s*:\s*" \ r"(?P<values>.*)$") criterion_inclusiveness_table = { - 'InclusiveCriterion' : True, - 'ExclusiveCriterion' : False} - all_criteria = [] + 'InclusiveCriterion' : "inclusive", + 'ExclusiveCriterion' : "exclusive"} - # Parse the criteria file - for line_number, line in enumerate(args.criteria, 1): + all_criteria = [] + for line_number, line in enumerate(criteriaFile): match = criteria_pattern.match(line) if not match: raise ValueError("The following line is invalid: {}:{}\n{}".format( - args.criteria.name, line_number, line)) + criteriaFile.name, line_number, line)) criterion_name = match.groupdict()['name'] criterion_type = match.groupdict()['type'] @@ -207,13 +125,14 @@ if __name__ == "__main__": "inclusive" : criterion_inclusiveness, "values" : criterion_values}) - # - # EDD files (aka ".pfw" files) - # + return all_criteria + +def parseEdd(EDDFiles): parsed_edds = [] - for edd_file in args.edd_files: + + for edd_file in EDDFiles: try: - root = parser = EddParser.Parser().parse(edd_file, args.verbose) + root = EddParser.Parser().parse(edd_file) except EddParser.MySyntaxError as ex: logging.critical(str(ex)) logging.info("EXIT ON FAILURE") @@ -227,105 +146,84 @@ if __name__ == "__main__": exit(1) parsed_edds.append((edd_file.name, root)) + return parsed_edds - # We need to modify the toplevel configuration file to account for differences - # between development setup and target (installation) setup, in particular, the - # TuningMode must be enforced, regardless of what will be allowed on the target - with tempfile.NamedTemporaryFile(mode='w') as fake_toplevel_config: - install_path = os.path.dirname(os.path.realpath(args.toplevel_config)) - hostConfig.configure( - infile=args.toplevel_config, - outfile=fake_toplevel_config, - structPath=install_path) - fake_toplevel_config.flush() - - # Create a new Pfw instance - pfw = PyPfw.ParameterFramework(fake_toplevel_config.name) - +def generateDomainCommands(logging, all_criteria, initial_settings, xml_domain_files, parsed_edds): # create and inject all the criteria logging.info("Creating all criteria") for criterion in all_criteria: - criterion_type = pfw.createSelectionCriterionType(criterion['inclusive']) - - for numerical, literal in enumerate(criterion['values']): - if criterion['inclusive']: - # inclusive criteria are "bitfields" - numerical = 1 << numerical - - ok = criterion_type.addValuePair(numerical, literal) - if not ok: - logging.critical("valuepair {}/{} rejected for {}".format( - numerical, literal, criterion['name'])) - exit(1) - - # we don't need the reference to the created criterion type; ignore the - # return value - pfw.createSelectionCriterion(criterion['name'], criterion_type) - - # Set failure conditions - pfw.setFailureOnMissingSubsystem(False) - pfw.setFailureOnFailedSettingsLoad(False) - if args.validate: - pfw.setValidateSchemasOnStart(True) - if args.schemas_dir is not None: - schemas_dir = args.schemas_dir - else: - schemas_dir = os.path.join(install_path, "Schemas") - pfw.setSchemaFolderLocation(schemas_dir) - - logger = PfwLogger() - pfw.setLogger(logger) + yield ["createSelectionCriterion", criterion['inclusive'], + criterion['name']] + criterion['values'] + + yield ["start"] + + # Import initial settings file + if initial_settings: + logging.info("Importing initial settings file {}".format(initial_settings)) + yield ["importDomainsWithSettingsXML", initial_settings] + + # Import each standalone domain files + for domain_file in xml_domain_files: + logging.info("Importing single domain file {}".format(domain_file)) + yield ["importDomainWithSettingsXML", domain_file] + + # Generate the script for each EDD file + for filename, parsed_edd in parsed_edds: + logging.info("Translating and injecting EDD file {}".format(filename)) + translator = PfwScriptTranslator() + parsed_edd.translate(translator) + for command in translator.getScript(): + yield command + +def main(): + logging.root.setLevel(logging.INFO) + args = parseArgs() - # Disable the remote interface because we don't need it and it might - # get in the way (e.g. the port is already in use) - pfw.setForceNoRemoteInterface(True) + all_criteria = parseCriteria(args.criteria) - # Finally, start the Pfw - ok, error = pfw.start() - if not ok: - logging.critical("Error while starting the pfw: {}".format(error)) - exit(1) - - ok, error = pfw.setTuningMode(True) - if not ok: - logging.critical(error) - exit(1) + # + # EDD files (aka ".pfw" files) + # + parsed_edds = parseEdd(args.edd_files) - # Import initial settings file + # We need to modify the toplevel configuration file to account for differences + # between development setup and target (installation) setup, in particular, the + # TuningMwith ode must be enforced, regardless of what will be allowed on the target + fake_toplevel_config = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix=".xml", + prefix="TMPdomainGeneratorPFConfig_") + + install_path = os.path.dirname(os.path.realpath(args.toplevel_config)) + hostConfig.configure( + infile=args.toplevel_config, + outfile=fake_toplevel_config, + structPath=install_path) + fake_toplevel_config.close() + + # Create the connector. Pipe its input to us in order to write commands; + # connect its output to stdout in order to have it dump the domains + # there; connect its error output to stderr. + connector = subprocess.Popen(["domainGeneratorConnector", + fake_toplevel_config.name, + 'verbose' if args.verbose else 'no-verbose', + 'validate' if args.validate else 'no-validate', + args.schemas_dir], + stdout=sys.stdout, stdin=subprocess.PIPE, stderr=sys.stderr) + + initial_settings = None if args.initial_settings: initial_settings = os.path.realpath(args.initial_settings) - logging.info( - "Importing initial settings file {}".format(initial_settings)) - ok, error = pfw.importDomainsXml(initial_settings, True, True) - if not ok: - logging.critical(error) - exit(1) - # Import each standalone domain files - for domain_file in args.xml_domain_files: - logging.info("Importing single domain file {}".format(domain_file)) - ok, error = pfw.importSingleDomainXml(os.path.realpath(domain_file), - False, True, True) - if not ok: - logging.critical(error) - exit(1) - - # Parse and inject each EDD file - error_handler = PfwTranslationErrorHandler() - translator = PfwTranslator(pfw, error_handler) - - for filename, parsed_edd in parsed_edds: - logging.info("Translating and injecting EDD file {}".format(filename)) - parsed_edd.translate(translator) - if error_handler.hasFailed(): - logging.error("Error while importing parsed EDD files.\n") - exit(1) + for command in generateDomainCommands(logging, all_criteria, initial_settings, + args.xml_domain_files, parsed_edds): + connector.stdin.write('\0'.join(command)) + connector.stdin.write("\n") - # dirty hack: we change the schema location (right before exporting the - # domains) to their location on the target (which may be different than on - # the machine that is generating the domains) - pfw.setSchemaFolderLocation(args.target_schemas_dir) + # Closing the connector's input triggers the domain generation + connector.stdin.close() + connector.wait() + os.remove(fake_toplevel_config.name) + return connector.returncode - # Export the resulting settings to the standard output - ok, domains, error = pfw.exportDomainsXml("", True, False) - sys.stdout.write(domains) +# If this file is directly executed +if __name__ == "__main__": + exit(main()) diff --git a/tools/xmlGenerator/domainGeneratorConnector.cpp b/tools/xmlGenerator/domainGeneratorConnector.cpp new file mode 100644 index 0000000..a83822f --- /dev/null +++ b/tools/xmlGenerator/domainGeneratorConnector.cpp @@ -0,0 +1,294 @@ +/* + * 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 <ParameterMgrFullConnector.h> +#include <Tokenizer.h> +#include <Utility.h> + +#include <iostream> +#include <sstream> +#include <memory> +#include <string> +#include <limits> +#include <numeric> +#include <algorithm> +#include <stdexcept> + +using std::string; + +class MyLogger final : public CParameterMgrFullConnector::ILogger +{ +public: + void info(const std::string &log) override { std::cerr << "Info: " << log << std::endl; } + + void warning(const std::string &log) override { std::cerr << "Warning: " << log << std::endl; } +}; + +class XmlGenerator +{ +public: + using Exception = std::runtime_error; + + XmlGenerator(const string &toplevelConfig, bool validate, bool verbose, string schemasDir) + : mConnector(toplevelConfig), mCommandHandler(mConnector.createCommandHandler()) + { + if (verbose) { + mLogger.reset(new MyLogger); + mConnector.setLogger(mLogger.get()); + } + + mConnector.setSchemaUri(schemasDir); + mConnector.setValidateSchemasOnStart(validate); + + // Disable irrelevant failure conditions + mConnector.setFailureOnMissingSubsystem(false); + mConnector.setFailureOnFailedSettingsLoad(false); + + // Disable the remote interface because we don't need it and it might + // get in the way (e.g. the port is already in use) + mConnector.setForceNoRemoteInterface(true); + } + + /** Reads each line of the input stream and takes an action accordingly + * + * Returns when the input stream reaches end of file + * + * The commands are the usual PF tunning commands and some additional specials. + * Special commands: + * - `createSelectionCriterion inclusive|exclusive <name> <value> [value, ...]` + * Create a criterion with the given properties. + * - `start` start the Parameter Framework. All criteria must have been created. + * + * @param[in] input The input stream to read from + * + * @return the number of error that occurred + */ + size_t parse(std::istream &input); + + /** Check for elements belonging to several domains + * + * Prints conflicting elements, if any, on the error output. + * + * @returns true if there are conflicting elements, false otherwise + */ + bool conflictingElements(); + + /** Prints the Parameter Framework's instance configuration + * + * @param[out] output The stream to which output the configuration + */ + void exportDomains(std::ostream &output); + +private: + void addCriteria(std::vector<string> &tokens); + void start(); + + CParameterMgrFullConnector mConnector; + std::unique_ptr<MyLogger> mLogger; + std::unique_ptr<CommandHandlerInterface> mCommandHandler; +}; + +void XmlGenerator::addCriteria(std::vector<string> &tokens) +{ + if (tokens.size() < 3) { + throw Exception("Not enough arguments to criterion creation request"); + } + + auto inclusiveness = tokens.front() == "inclusive"; + tokens.erase(begin(tokens)); + + auto name = tokens.front(); + tokens.erase(begin(tokens)); + + auto criterionType = mConnector.createSelectionCriterionType(inclusiveness); + if (criterionType == nullptr) { + throw Exception("Failed to create an " + string(inclusiveness ? "inclusive" : "exclusive") + + " criterion type"); + } + + int index = 0; + for (const auto &literalValue : tokens) { + // inclusive criteria are bitfields + int numericalValue = inclusiveness ? 1 << index : index; + string error; + bool success = criterionType->addValuePair(numericalValue, literalValue, error); + + if (not success) { + std::ostringstream message; + message << "Valuepair (" << numericalValue << ", '" << literalValue + << "') rejected for " << name << ": " << error; + throw Exception(message.str()); + } + index++; + } + + // We don't need to keep a reference to the criterion - no need to store + // the returned pointer. + if (mConnector.createSelectionCriterion(name, criterionType) == nullptr) { + throw Exception("Failed to create criterion '" + name + "'"); + } +} + +size_t XmlGenerator::parse(std::istream &input) +{ + string line; + size_t errorNb = 0; + while (not input.eof()) { + std::getline(std::cin, line); + + auto tokens = Tokenizer(line, string(1, '\0'), false).split(); + if (tokens.empty()) { + continue; + } + auto command = tokens.front(); + tokens.erase(begin(tokens)); // drop the command name + + if (command == "createSelectionCriterion") { + addCriteria(tokens); + } else if (command == "start") { + start(); + } else { + string output; + if (not mCommandHandler->process(command, tokens, output)) { + errorNb++; + + std::cerr << accumulate(begin(tokens), end(tokens), + "Failed to executing command: `" + command + "'", + [](string l, string r) { return l + " `" + r + "'"; }) + << std::endl + << output << std::endl; + } + } + } + return errorNb; +} + +bool XmlGenerator::conflictingElements() +{ + string conflicting; + if (not mCommandHandler->process("listConflictingElements", {}, conflicting)) { + // Should not happen + throw Exception("Failed to list conflicting elements"); + } + + if (not conflicting.empty()) { + std::cerr << "There are conflicting elements:" << std::endl << conflicting; + return true; + } + + return false; +} + +void XmlGenerator::start() +{ + string error; + if (not mConnector.start(error)) { + throw Exception("Start failed: " + error); + } + + error.clear(); + // Switch to tunning mode as the tunning commands + // are the only commands possible with this connector. + if (not mConnector.setTuningMode(true, error)) { + throw Exception("Failed to turn tuning mode on: " + error); + } +} + +void XmlGenerator::exportDomains(std::ostream &output) +{ + string error; + string domains; + if (not mConnector.exportDomainsXml(domains, true, false, error)) { + throw Exception("Export failed: " + error); + } else { + output << domains; + } +} + +static const char *usage = + R"(Usage: domainGeneratorConnector <top-level config> <verbose> <validate> <path> + + <verbose> 'verbose': verbose, else: terse + <validate> 'validate': validate, else: don't validate + <path> path to the schemas' directory + +All arguments are mandatory. If no validation is required, +the path to the schemas can be an empty string. + +Exit with the number of (recoverable or not error) that occured. + +This program is not intended to be used standalone but rather called through +domainGenerator.py)"; + +/** On linux at least, a program can not exit with a value greater than 255. + * @return min(code, 255); + */ +template <class T> +static inline int normalizeExitCode(T code) +{ + return int(std::min<T>(code, std::numeric_limits<uint8_t>::max())); +} + +int main(int argc, char *argv[]) +{ + using std::endl; + + if (argc <= 4) { + std::cerr << usage << std::endl; + return 1; + } + + string toplevelConfig = argv[1]; + bool verbose = string(argv[2]) == "verbose"; + bool validate = string(argv[3]) == "validate"; + string schemasDir = argv[4]; + + if (verbose) { + std::cerr << "Domain generator config:" << endl + << " toplevelConfig=" << toplevelConfig << endl + << " verbose=" << verbose << endl + << " validate=" << validate << endl + << " schemasDir=" << schemasDir << endl; + } + + try { + XmlGenerator xmlGenerator(toplevelConfig, validate, verbose, schemasDir); + auto errorNb = xmlGenerator.parse(std::cin); + if (xmlGenerator.conflictingElements()) { + errorNb++; + } + xmlGenerator.exportDomains(std::cout); + + return normalizeExitCode(errorNb); + } catch (std::exception &e) { + std::cerr << e.what() << std::endl; + return 1; + } +} diff --git a/tools/xmlGenerator/hostDomainGenerator.sh b/tools/xmlGenerator/hostDomainGenerator.sh deleted file mode 100755 index 1a7d315..0000000 --- a/tools/xmlGenerator/hostDomainGenerator.sh +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2011-2014, 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. - -set -ueo pipefail - -# In order to dispatch log properly 4 output streams are available: -# - 1 info -# - 2 error -# - 3 (reserved) -# - 4 standard -# - 5 warning - -# Leave standard output unmodified -exec 4>&1 -# If the nonverbose long option is provided, do not output info log lines prefixed on stderr. -if test "$1" == --nonverbose -then - shift - exec 1>/dev/null -else - exec 1> >(sed "s/^/($$) Info: /" >&2) -fi -# Prefix all warning and error log lines and redirect them to stderr -exec 5> >(sed "s/^/($$) Warning: /" >&2) -exec 2> >(sed "s/^/($$) Error: /" >&2) - -# Get script arguments -validationEnabled="false" -if [ "$1" = "--validate" ]; then - validationEnabled="true" - shift -fi -PFWconfigurationFilePath="$1"; shift -CriterionFilePath="$1"; shift -xmlDomainFilePath="$1"; shift - -# Set constant variables -testPlatform="test-platform_host" -remoteProcess="remote-process_host" - -hostConfig="hostConfig.py" -PFWScriptGenerator="PFWScriptGenerator.py" -portAllocator="portAllocator.py" - -TPHost=127.0.0.1 -PFWHost=127.0.0.1 -TPCreated=false - -HostRoot="$ANDROID_HOST_OUT" -TargetRoot="$ANDROID_PRODUCT_OUT/system" - -# Global variables -TPSocket=5003 -PFWSocket=5000 -PFWStartTimeout=60 - -tmpDir=$(mktemp -d) -tmpFile=$(mktemp --tmpdir="$tmpDir") - -# [Workaround] -# The build system does not preserve execution right in external prebuild -for file in "$testPlatform" "$remoteProcess" "$hostConfig" "$PFWScriptGenerator" "$portAllocator" -do - chmod +x "${HostRoot}/bin/${file}" -done - -# Set environment paths -export LD_LIBRARY_PATH="$HostRoot/lib:${LD_LIBRARY_PATH:-}" - -# Setup clean trap, it will be called automatically on exit -clean_up () { - status=$? - set +e # An error should not abort clean up - - # Exit the test-platform only if it was created by this process - if $TPCreated - then - echo "Exiting test-platform listening on port $TPSocket" - $remoteProcess $TPHost $TPSocket exit - fi - - echo "Cleaning $tmpFile ..." - rm "$tmpFile" || true - - if [ "$validationEnabled" = "true" ]; then - echo "Cleaning $tmpDir/Schemas ..." - rm -r "$tmpDir/Schemas" || true - rmdir "$tmpDir" || true - fi - - echo "Cleaning status: $status ..." - return $status -} - -trap clean_up SIGHUP SIGINT SIGTERM EXIT - -# Create a symlink link to rename a library. -# Eg: /lib/ contains the lib mylib_host.so but it must be found under the name -# mylib.so. linkLibrary mylib_host.so mylib.so will create a symlink in mylib_host.so's folder -# called mylib.so, pointing to mylib_host.so -linkLibrary () { - local src="$1" - local dest="$2" - local path=$(find $HostRoot/lib -name "$src") - - # Check that both names are different, otherwise there is an error - if ! test "$(basename "$path")" != "$dest" - then - echo "Cannot link $dest to $src !" - return 1 - fi - - # Check that destination file does not already exist - if ! test -f "$(dirname "$path")/$dest" - then - # Create the symlink. Do not force if it has been created after the previous - # test, in this case simply ignore the error - ln -s "$src" "$(dirname "$path")/$dest" || true - fi - return 0 -} - -# The retry function will execute the provided command nbRety times util success. -# It also sleep sleepTime second between each retry. -retry() { - local command=$1 - local nbRetry=$2 - local sleepTime=$3 - local retry=0 - while ! $command 2>/dev/null >&2 - do - (($retry < $nbRetry)) || return 1 - retry=$(($retry + 1)) - sleep $sleepTime - done - return 0; -} - -# Configure the PFW main config file for simulation -formatConfigFile () { - "$hostConfig" $PFWSocket "$(readlink -f "$(dirname "$1")")" <"$1" -} - -# The initTestPlatform starts a testPlatform instance with the config file given in argument. -# It will also set the PFWSocket global variable to the PFW remote processor listening socket. -initTestPlatform () { - # Format the PFW config file - formatConfigFile "$1" >"$tmpFile" - - # Start test platform - echo "Starting test-platform on port $TPSocket ..." - $testPlatform -d "$tmpFile" $TPSocket 2>&5 - - res=$? - if test $res -ne 0 - then - echo "Unable to launch the simulation platform (using socket $TPSocket)" >&5 - return 4 - fi - - echo "Test platform successfuly loaded!" - return 0 -} - -# Execute a command for each input line, stopping in case of error -forEachLine () { - xargs -I@ sh -c "echo \> $1;$1 || exit 255" -} - -# Configure test platform (mainly criterion) and start the PFW -launchTestPlatform () { - local TPSendCommand="$remoteProcess $TPHost $TPSocket" - sed -e 's/InclusiveCriterion/createInclusiveSelectionCriterionFromStateList/' \ - -e 's/ExclusiveCriterion/createExclusiveSelectionCriterionFromStateList/' \ - -e 's/[[:space:]]:[[:space:]]/ /g' "$CriterionFilePath" | - forEachLine "$TPSendCommand @" - - $TPSendCommand setFailureOnMissingSubsystem false - $TPSendCommand setFailureOnFailedSettingsLoad false - $TPSendCommand setValidateSchemasOnStart $validationEnabled - - echo "Asking test-platform (port $TPSocket) to start a new PFW instance (listening on port $PFWSocket) ..." - $TPSendCommand start - res=$? - if test $res -ne 0 - then - echo "Unable to launch the parameter framework (using port $PFWSocket)" >&5 - return 5 - fi - - echo "Parameter framework successfully started!" - return 0 -} - -startPFW () { - # Init the test-platform - initTestPlatform "$PFWconfigurationFilePath" || return 1 - TPCreated=true - - # Ask the test-platform to start the PFW - if ! launchTestPlatform "$CriterionFilePath" - then - # If PFW didn't start, exit the current test-platform, and return failure in - # order to choose new socket ports - echo "Exiting test-platform listening on port $TPSocket" - $remoteProcess $TPHost $TPSocket exit - TPCreated=false - return 1 - fi -} - -# Get a new pair of available ports for TP and PFW sockets -changeSocketsPorts() { - TPSocket=$($portAllocator) || return 1 - PFWSocket=$($portAllocator) || return 1 -} - -# Start the pfw using different socket if it fails -safeStartPFW () { - local retry=0 - local nbRetry=1000 # Workaround to avoid build failure, it very very rarely fail this many time - - # Choose a new pair of socket ports - changeSocketsPorts - echo "Trying to start test-platform and PFW, with socket $TPSocket and $PFWSocket" - - while ! startPFW - do - (($retry < $nbRetry)) || return 1 - retry=$(($retry + 1)) - - # Choose a new pair of socket ports - changeSocketsPorts || continue - - echo "Unable to start PFW, try again with socket $TPSocket and $PFWSocket" - done -} - -deleteEscapedNewLines () { - sed -r ':a;/\\$/{N;s/\\\n//;ba}' -} - -copySchemaFiles() { - cp -r "$HostRoot"/etc/parameter-framework/Schemas "$tmpDir/Schemas" -} - -# Copy the schema files needed for validation -if [ "$validationEnabled" = "true" ]; then - copySchemaFiles -fi - -# The PFW looks for a libremote-processor.so library, not a libremote-processor_host.so -linkLibrary libremote-processor_host.so libremote-processor.so - -# Start test platform and the PFW -# Start the pfw using different socket if it fails -safeStartPFW - -PFWSendCommand="$remoteProcess $PFWHost $PFWSocket" - -$PFWSendCommand setTuningMode on - -# Send the xml domain tunning file -if test -s "$xmlDomainFilePath" -then - echo "Import the xml domain tunning file: $(readlink -e $xmlDomainFilePath)" - $PFWSendCommand importDomainsWithSettingsXML "$(readlink -e $xmlDomainFilePath)" -fi - -# Send the extended domain description routing files converted to pfw commands -m4 "$@" | - "$PFWScriptGenerator" --output-kind pfw | - deleteEscapedNewLines | - forEachLine "$PFWSendCommand @" | sed '/^Done$/d' - -# Export the global xml domains description -$PFWSendCommand getDomainsWithSettingsXML | - # Delete trailing carriage return and format absolute paths - sed -r -e 's/\r$//' \ - -e 's@(xsi:noNamespaceSchemaLocation=")'"$tmpDir"'/?@\1@' >&4 - diff --git a/tools/xmlValidator/CMakeLists.txt b/tools/xmlValidator/CMakeLists.txt index 0405fb7..f44fed0 100644 --- a/tools/xmlValidator/CMakeLists.txt +++ b/tools/xmlValidator/CMakeLists.txt @@ -26,4 +26,4 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -INSTALL(PROGRAMS xmlValidator.py DESTINATION bin) +install(PROGRAMS xmlValidator.py DESTINATION bin) diff --git a/tools/xmlValidator/README.md b/tools/xmlValidator/README.md index c50f33e..5b92c6d 100644 --- a/tools/xmlValidator/README.md +++ b/tools/xmlValidator/README.md @@ -28,7 +28,7 @@ where: In the example, we have the following files: |-- ParameterFrameworkConfiguration.xml - |-- Schemas + |-- schemas | |-- ComponentLibrary.xsd | |-- ComponentTypeSet.xsd | |-- ConfigurableDomains.xsd @@ -50,12 +50,12 @@ In the example, we have the following files: We are in the directory which contains the structure detailed previously. To check the validity, we just run: - ../../tools/xmlValidator/xmlValidator.py . Schemas + ../../tools/xmlValidator/xmlValidator.py . schemas ### Results And we will get the following output on the commandline: - [*] Validate xml files in /home/lab/MusicLibrary/ with /home/lab/MusicLibrary/Schemas + [*] Validate xml files in /home/lab/MusicLibrary/ with /home/lab/MusicLibrary/schemas Attempt to validate ParameterFrameworkConfiguration.xml with ParameterFrameworkConfiguration.xsd ParameterFrameworkConfiguration.xml is valid Attempt to validate my_music.xml with Subsystem.xsd diff --git a/utility/AlwaysAssert.hpp b/utility/AlwaysAssert.hpp new file mode 100644 index 0000000..25f6d8b --- /dev/null +++ b/utility/AlwaysAssert.hpp @@ -0,0 +1,49 @@ +/* +* 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. +*/ +#pragma once + +#include <iostream> + +#ifdef NDEBUG +#include <exception> +#define ALWAYS_ASSERT_FAILURE(cond) std::terminate() +#else +#include <cassert> +#define ALWAYS_ASSERT_FAILURE(cond) assert(cond) +#endif + +#define ALWAYS_ASSERT(cond, iostr) \ + do { \ + if (!(cond)) { \ + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ \ + << ": Assert '" #cond "' failed: " << iostr << std::endl; \ + ALWAYS_ASSERT_FAILURE(cond); \ + } \ + } while (0) diff --git a/utility/FullIo.cpp b/utility/BinaryCopy.hpp index 59765b5..ada6a18 100644 --- a/utility/FullIo.cpp +++ b/utility/BinaryCopy.hpp @@ -28,53 +28,45 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "FullIo.hpp" - -#include <cerrno> -#include <unistd.h> +#include <algorithm> +#include <type_traits> +#include "Iterator.hpp" +#include <cassert> namespace utility { -/** Workaround c++ `void *` arithmetic interdiction. */ -template <class Ptr> -Ptr *add(Ptr *ptr, size_t count) { - return (char *)ptr + count; -} - -template <class Buff> -static bool fullAccess(ssize_t (&accessor)(int, Buff, size_t), - bool (&accessFailed)(ssize_t), - int fd, Buff buf, size_t count) { - size_t done = 0; // Bytes already access in previous iterations - while (done < count) { - ssize_t accessed = accessor(fd, add(buf, done), count - done); - if (accessFailed(accessed)) { - return false; - } - done += accessed; - } - return true; -} +/** + * Raw copy of one variable to another of the same size + * + * This can be regarder as a reinterpret_cast but does a copy and does not + * break strict-aliasing rules. + * + * The source and the destination must have the same storage size (e.g. copying + * a uint8_t into a uint32_t won't compile) + * + * @tparam Source The source type + * @tparam Destination the destination type (even if it is a reference, this + * function returns by copy) + * @param source Source variable + * @returns the source, reinterpreted as the destination type + */ +template <class Destination, class Source> +typename std::remove_reference<Destination>::type binaryCopy(const Source source) +{ + static_assert(sizeof(Source) == sizeof(Destination), + "Source and Destination must have the same size"); -static bool accessFailed(ssize_t accessRes) { - return accessRes == -1 and errno != EAGAIN and errno != EINTR; -} + using Destination_ = decltype(binaryCopy<Destination>(source)); -bool fullWrite(int fd, const void *buf, size_t count) { - return fullAccess(::write, accessFailed, fd, buf, count); -} + union + { + Source source; + Destination_ destination; + } hack; -static bool readFailed(ssize_t readRes) { - if (readRes == 0) { // read should not return 0 (EOF) - errno = 0; - return true; - } - return accessFailed(readRes); -} -bool fullRead(int fd, void *buf, size_t count) { - return fullAccess(::read, readFailed, fd, buf, count); + hack.source = source; + return hack.destination; } } // namespace utility - diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt index 5386f5b..49e01e2 100644 --- a/utility/CMakeLists.txt +++ b/utility/CMakeLists.txt @@ -26,11 +26,35 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +if (WIN32) + set(UTILITY_OS_SPECIFIC_FILES windows/DynamicLibrary.cpp) +else () + set(UTILITY_OS_SPECIFIC_FILES posix/DynamicLibrary.cpp) +endif () + add_library(pfw_utility STATIC + ${UTILITY_OS_SPECIFIC_FILES} Tokenizer.cpp Utility.cpp - FullIo.cpp - NaiveTokenizer.cpp) + DynamicLibrary.cpp) + +target_include_directories(pfw_utility PUBLIC .) + +# Needed for linking against shared libraries on Linux (no-op on Windows) +set_target_properties(pfw_utility PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + +install(FILES + NonCopyable.hpp + ErrorContext.hpp + Utility.h + convert.hpp + DESTINATION "include/utility") + +if(BUILD_TESTING) + # Add unit test + add_executable(utilityUnitTest test/utility.cpp) -# '-fPIC' needed for linking against shared libraries (e.g. libparameter) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + target_link_libraries(utilityUnitTest pfw_utility catch) + add_test(NAME utilityUnitTest + COMMAND utilityUnitTest) +endif() diff --git a/utility/DynamicLibrary.cpp b/utility/DynamicLibrary.cpp new file mode 100644 index 0000000..40ffecb --- /dev/null +++ b/utility/DynamicLibrary.cpp @@ -0,0 +1,43 @@ +/* + * 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 <DynamicLibrary.hpp> + +std::string DynamicLibrary::osSanitizePathName(const std::string &path) +{ + if (path.rfind(_osLibrarySuffix) == (path.length() - _osLibrarySuffix.length())) { + + return path; + } + + std::string sanitizedPath = _osLibraryPrefix + path + _osLibrarySuffix; + + return sanitizedPath; +} diff --git a/utility/DynamicLibrary.hpp b/utility/DynamicLibrary.hpp new file mode 100644 index 0000000..8c5f461 --- /dev/null +++ b/utility/DynamicLibrary.hpp @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2014-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. +*/ +#pragma once + +#include "NonCopyable.hpp" + +#include <string> + +class DynamicLibrary : private utility::NonCopyable +{ +public: + /** + * @param[in] path the library path which can be provided either in absolute path or + * or OS agnostic (ie. generic) name. + * Note: + * If generic name provided, OS specific prefix, suffix are added automatically + */ + DynamicLibrary(const std::string &path); + ~DynamicLibrary(); + + /** + * Get a symbol from library + * + * @param[in] symbol the symbol name + * @return a symbol's address in the library if it exists, NULL otherwise + */ + template <typename SymbolType> + SymbolType getSymbol(const std::string &symbol) const + { + return reinterpret_cast<SymbolType>(osGetSymbol(symbol)); + } + +private: + /** + * OS secific helper to get a symbol from library + * + * @param[in] symbol the symbol name + * @return symbol's address in the library if it exists, NULL otherwise + */ + void *osGetSymbol(const std::string &symbol) const; + + /** + * Sanitize library path + * + * @param[in] path library stripped path (eg. no prefix, no suffix) + * @return OS specific library path including prefix and suffix + */ + static std::string osSanitizePathName(const std::string &path); + + /** + * Opaque object for library handling + */ + void *_handle; + + /** + * Path to the library + */ + const std::string _path; + + /** + * OS Specific library name patterns + * @{ + */ + static const std::string _osLibraryPrefix; + static const std::string _osLibrarySuffix; + /** @}*/ +}; diff --git a/utility/ErrorContext.hpp b/utility/ErrorContext.hpp new file mode 100644 index 0000000..d963097 --- /dev/null +++ b/utility/ErrorContext.hpp @@ -0,0 +1,54 @@ +/* + * 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. + */ +#pragma once + +#include <string> +#include <NonCopyable.hpp> + +namespace utility +{ + +class ErrorContext : private NonCopyable +{ +public: + ErrorContext(std::string &error) : mError(error) {} + + void setError(const std::string &error) { mError = error; } + + void appendToError(const std::string &append) { mError += append; } + + void prependToError(const std::string &prepend) { mError = prepend + mError; } + +private: + // Error reference + std::string &mError; +}; + +} // namespace utility diff --git a/utility/Iterator.hpp b/utility/Iterator.hpp new file mode 100644 index 0000000..49b4e3f --- /dev/null +++ b/utility/Iterator.hpp @@ -0,0 +1,46 @@ +/* + * 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 <iterator> + +#ifdef _MSC_VER +#include <iterator> +/** Visual studio raises a warning if the check iterator feature is activated + * but a raw pointer is used as iterator (as it can not check it's bounds). + * As it is a safety feature, do not silent the warning, but use the + * microsoft specific `make_check_array_iterator` that take a pointer + * and the size of the underline buffer. + * For other compiler, use the raw pointer. + */ +#define MAKE_ARRAY_ITERATOR(begin, size) stdext::make_checked_array_iterator(begin, size) +#else +/** By default an array iterator is a pointer to the first element. */ +#define MAKE_ARRAY_ITERATOR(begin, size) begin +#endif diff --git a/utility/Memory.hpp b/utility/Memory.hpp new file mode 100644 index 0000000..90019d1 --- /dev/null +++ b/utility/Memory.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011-2014, 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 <memory> + +namespace utility +{ + +/** Implementation of C++14's std::make_unique. + * + * TODO: Specialisation for array types is not implemented. + */ +template <class T, class... Args> +std::unique_ptr<T> make_unique(Args &&... args) +{ + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +} + +} // namespace utility diff --git a/utility/NaiveTokenizer.cpp b/utility/NaiveTokenizer.cpp deleted file mode 100644 index 320fec0..0000000 --- a/utility/NaiveTokenizer.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2011-2014, 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 "NaiveTokenizer.h" -#include <cstring> - -char* NaiveTokenizer::getNextToken(char** line) -{ - const char *quotes = "'\""; // single or double quotes - char separator[2] = " "; - char first[2]; - - if (*line == NULL || (*line)[0] == '\0') { - return NULL; - } - - // Copy the first character into its own new string - first[0] = (*line)[0]; - first[1] = '\0'; - - // Check if the first character is a quote - if (strstr(quotes, first) != NULL) { - // If so, move forward and set the separator to that quote - (*line)++; - strncpy(separator, first, sizeof(separator)); - } - // If it is not, get the next space-delimited token - // First, move the cursor forward if the first character is a space - // This effectively ignores multiple spaces in a row - else if (strstr(separator, first) != NULL) { - (*line)++; - return NaiveTokenizer::getNextToken(line); - } - - return strsep(line, separator); -} diff --git a/utility/NonCopyable.hpp b/utility/NonCopyable.hpp new file mode 100644 index 0000000..bee1da8 --- /dev/null +++ b/utility/NonCopyable.hpp @@ -0,0 +1,56 @@ +/* + * 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. + */ +#pragma once + +namespace utility +{ + +/** Base class for private inheritance to make the derived class non copyable. + * + * Sometime implementing copy/move semantic is complicated or not useful. + * The traditional way is to declare the relevant methods private in c++ < 11 + * or deleted in c++ > 11. + * + * It is easier and self documented to derive from this class. + * + * For more documentation see: + * http://www.boost.org/doc/libs/release/libs/utility/utility.htm#Class_noncopyable + * */ +class NonCopyable +{ +public: + NonCopyable() = default; + NonCopyable(const NonCopyable &) = delete; + NonCopyable(NonCopyable &&) = delete; + NonCopyable &operator=(const NonCopyable &) = delete; + NonCopyable &operator=(NonCopyable &&) = delete; +}; + +} // namespace utility diff --git a/utility/Tokenizer.cpp b/utility/Tokenizer.cpp index a4cfcf0..13f4319 100644 --- a/utility/Tokenizer.cpp +++ b/utility/Tokenizer.cpp @@ -34,42 +34,45 @@ using std::vector; const string Tokenizer::defaultDelimiters = " \n\r\t\v\f"; -Tokenizer::Tokenizer(const string &input, const string &delimiters) - : _input(input), _delimiters(delimiters), _position(0) +Tokenizer::Tokenizer(const string &input, const string &delimiters, bool mergeDelimiters) + : _input(input), _delimiters(delimiters), _mergeDelimiters(mergeDelimiters) { } -string Tokenizer::next() -{ - string token; - - // Skip all leading delimiters - string::size_type tokenStart = _input.find_first_not_of(_delimiters, _position); - - // Special case if there isn't any token anymore (string::substr's - // throws when pos==npos) - if (tokenStart == string::npos) { - return ""; - } - - // Starting from the token's start, find the first delimiter - string::size_type tokenEnd = _input.find_first_of(_delimiters, tokenStart); - - _position = tokenEnd; - - return _input.substr(tokenStart, tokenEnd - tokenStart); -} - vector<string> Tokenizer::split() { vector<string> result; string token; + bool leftover = false; + + for (const auto character : _input) { + if (_delimiters.find(character) != string::npos) { + if (_mergeDelimiters) { + leftover = false; + if (token.empty()) { + // skip consecutive delimiters + continue; + } + } else { + // We've encountered a delimiter, which means that there is a + // left-hand token and a right-side token. We are going to add + // the left-hand one but must not forget that there is a + // right-hand one (possibly empty) + leftover = true; + } - while (true) { - token = next(); - if (token.empty()) { - return result; + result.push_back(token); + token.clear(); + continue; } + token += character; + leftover = true; + } + + // push any leftover token: + if (leftover) { result.push_back(token); } + + return result; } diff --git a/utility/Tokenizer.h b/utility/Tokenizer.h index c48747a..1974041 100644 --- a/utility/Tokenizer.h +++ b/utility/Tokenizer.h @@ -29,6 +29,8 @@ */ #pragma once +#include "NonCopyable.hpp" + #include <string> #include <vector> @@ -36,11 +38,8 @@ * * Must be initialized with a string to be tokenized and, optionally, a string * of delimiters (@see Tokenizer::defaultDelimiters). - * - * Multiple consecutive delimiters (even if different) are considered as a - * single one. As a result, there can't be empty tokens. */ -class Tokenizer +class Tokenizer : private utility::NonCopyable { public: /** Constructs a Tokenizer @@ -48,17 +47,13 @@ public: * @param[in] input The string to be tokenized * @param[in] delimiters A string containing all the token delimiters * (hence, each delimiter can only be a single character) + * @param[in] mergeDelimiters If true, consecutive delimiters are considered + * as one; leading and trailing delimiters are also ignored. + * If false, consecutive delimiters produce empty tokens */ - Tokenizer(const std::string &input, const std::string &delimiters=defaultDelimiters); - ~Tokenizer() {}; - - /** Return the next token or an empty string if no more token - * - * Multiple consecutive delimiters are considered as a single one - i.e. - * "a bc d " will be tokenized as ("a", "bc", "d") if the delimiter - * is ' '. - */ - std::string next(); + Tokenizer(const std::string &input, const std::string &delimiters = defaultDelimiters, + bool mergeDelimiters = true); + ~Tokenizer(){}; /** Return a vector of all tokens */ @@ -68,8 +63,7 @@ public: static const std::string defaultDelimiters; private: - const std::string _input; //< string to be tokenized + const std::string _input; //< string to be tokenized const std::string _delimiters; //< token delimiters - - std::string::size_type _position; //< end of the last returned token + const bool _mergeDelimiters; //< whether subsequent delimiters should be merged }; diff --git a/utility/Utility.cpp b/utility/Utility.cpp index e5f689a..bf94422 100644 --- a/utility/Utility.cpp +++ b/utility/Utility.cpp @@ -32,56 +32,42 @@ #include <sstream> #include <iterator> -#include <stdint.h> +#include <algorithm> using std::string; -// Format string list -void CUtility::asString(const std::list<std::string>& lstr, - std::string& strOutput, - const std::string& strSeparator) +namespace utility { - std::ostringstream ostrFormatedList; - - std::copy(lstr.begin(), lstr.end(), - std::ostream_iterator<std::string>(ostrFormatedList, strSeparator.c_str())); - - strOutput = ostrFormatedList.str(); - - // Remove last separator - if (strOutput.size() > strSeparator.size()) { - strOutput.erase(strOutput.size() - strSeparator.size()); - } +// Format string list +std::string asString(const std::list<std::string> &lstr, const std::string &strSeparator) +{ + return join<std::string>(begin(lstr), end(lstr), [strSeparator](string acc, string right) { + return acc + strSeparator + right; + }); } // Format string map -void CUtility::asString(const std::map<std::string, std::string>& mapStr, - std::string& strOutput, - const std::string& strItemSeparator, - const std::string& strKeyValueSeparator) +std::string asString(const std::map<std::string, std::string> &mapStr, + const std::string &strItemSeparator, const std::string &strKeyValueSeparator) { std::list<std::string> listKeysValues; - std::map<std::string, std::string>::const_iterator iter; - - for(iter = mapStr.begin(); iter != mapStr.end(); ++iter) { - - listKeysValues.push_back(iter->first + strKeyValueSeparator + iter->second); + for (const auto &item : mapStr) { + listKeysValues.emplace_back(item.first + strKeyValueSeparator + item.second); } - CUtility::asString(listKeysValues, strOutput, strItemSeparator); + return asString(listKeysValues, strItemSeparator); } -void CUtility::appendTitle(string& strTo, const string& strTitle) +void appendTitle(string &strTo, const string &strTitle) { - strTo += "\n" + strTitle + "\n"; - - uint32_t uiLength = strTitle.size(); - - while (uiLength--) { + strTo += "\n" + strTitle + "\n" + string(strTitle.size(), '=') + "\n"; +} - strTo += "="; - } - strTo += "\n"; +bool isHexadecimal(const string &strValue) +{ + return (strValue.compare(0, 2, "0x") == 0) or (strValue.compare(0, 2, "0X") == 0); } + +} // namespace utility diff --git a/utility/Utility.h b/utility/Utility.h index 93acd82..c32095a 100644 --- a/utility/Utility.h +++ b/utility/Utility.h @@ -34,50 +34,69 @@ #include <list> #include <map> #include <sstream> +#include <numeric> -class CUtility +namespace utility { -public: - /** - * Format the items of a map into a string as a list of key-value pairs. The map must be - * composed of pairs of strings. - * - * @param[in] mapStr A map of strings - * @param[out] strOutput The output string - * @param[in] separator The separator to use between each item - */ - static void asString(const std::list<std::string>& lstr, - std::string& strOutput, - const std::string& separator = "\n"); - /** - * Format the items of a map into a string as a list of key-value pairs. The map must be - * composed of pairs of strings. - * - * @param[in] mapStr A map of strings - * @param[out] strOutput The output string - * @param[in] strItemSeparator The separator to use between each item (key-value pair) - * @param[in] strKeyValueSeparator The separator to use between key and value - */ - static void asString(const std::map<std::string, std::string>& mapStr, - std::string& strOutput, - const std::string& strItemSeparator = ", ", - const std::string& strKeyValueSeparator = ":"); +/** Join all elements in [first, last[ with op. + * + * If their is no element to join, return empty. + * + * Example (joining strings): + * @verbatim + * let op = [](auto l, auto r){ return l + "|" + r; } + * let [first, last[ = list<string>{"1", "2", "3"} + * then join(first, last, op) == "1|2|3" + * @endverbatim + */ +template <class T, class InputIt, class BinaryOperation> +T join(InputIt first, InputIt last, BinaryOperation op, T empty = T{}) +{ + if (first == last) { + return empty; + } + auto init = *first++; - /** Utility to easily convert a builtin type into string - * - * FIXME: Should be replaced by std::to_string after C++11 introduction - */ - template <class T> - static std::string toString(T uiValue) - { - std::ostringstream ostr; + return std::accumulate(first, last, init, op); +} - ostr << uiValue; +/** +* Format the items of a map into a string as a list of key-value pairs. The map must be +* composed of pairs of strings. +* +* @param[in] lstr A list of strings +* @param[in] separator The separator to use between each item +* +* @return the concatenated elements. +*/ +std::string asString(const std::list<std::string> &lstr, const std::string &separator = "\n"); - return ostr.str(); - } +/** + * Format the items of a map into a string as a list of key-value pairs. The map must be + * composed of pairs of strings. + * + * @param[in] mapStr A map of strings + * @param[in] strItemSeparator The separator to use between each item (key-value pair) + * @param[in] strKeyValueSeparator The separator to use between key and value + * + * @returns the pretty-printed map + */ +std::string asString(const std::map<std::string, std::string> &mapStr, + const std::string &strItemSeparator = ", ", + const std::string &strKeyValueSeparator = ":"); + +/** Utility to underline */ +void appendTitle(std::string &strTo, const std::string &strTitle); + +/** + * Checks if a string has the written representation of an hexadecimal + * number (Which is the prefix "0x" or "0X" in C++). + * + * @param[in] strValue value as string + * + * @return true if the string is written as hexa, false otherwise. + */ +bool isHexadecimal(const std::string &strValue); - /** Utility to underline */ - static void appendTitle(std::string& strTo, const std::string& strTitle); -}; +} // utility diff --git a/utility/convert.hpp b/utility/convert.hpp index 55146f7..fcf8e03 100644 --- a/utility/convert.hpp +++ b/utility/convert.hpp @@ -35,34 +35,92 @@ #include <string> #include <stdint.h> #include <cmath> +#include <type_traits> /* details namespace is here to hide implementation details to header end user. It * is NOT intended to be used outside. */ namespace details { -/** Helper class to limit instantiation of templates */ -template<typename T> -struct ConvertionAllowed; - /* List of allowed types for conversion */ -template<> struct ConvertionAllowed<bool> {}; -template<> struct ConvertionAllowed<uint64_t> {}; -template<> struct ConvertionAllowed<int64_t> {}; -template<> struct ConvertionAllowed<uint32_t> {}; -template<> struct ConvertionAllowed<int32_t> {}; -template<> struct ConvertionAllowed<uint16_t> {}; -template<> struct ConvertionAllowed<int16_t> {}; -template<> struct ConvertionAllowed<float> {}; -template<> struct ConvertionAllowed<double> {}; - -template<typename T> +template <typename T> +struct ConvertionAllowed : std::false_type +{ +}; +template <> +struct ConvertionAllowed<bool> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<long long> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<unsigned long long> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<long> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<unsigned long> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<int> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<unsigned int> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<short> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<unsigned short> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<unsigned char> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<signed char> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<float> : std::true_type +{ +}; +template <> +struct ConvertionAllowed<double> : std::true_type +{ +}; + +/* Allow chars and unsigned chars to be converted via integers */ +template <typename T, typename Via> +struct ConvertionAllowedVia : std::false_type +{ +}; +template <> +struct ConvertionAllowedVia<unsigned char, unsigned int> : std::true_type +{ +}; +template <> +struct ConvertionAllowedVia<signed char, int> : std::true_type +{ +}; + +template <typename T> static inline bool convertTo(const std::string &str, T &result) { /* Check that conversion to that type is allowed. * If this fails, this means that this template was not intended to be used * with this type, thus that the result is undefined. */ - ConvertionAllowed<T>(); + static_assert(ConvertionAllowed<T>::value, "convertTo does not support this conversion"); if (str.find_first_of(std::string("\r\n\t\v ")) != std::string::npos) { return false; @@ -71,8 +129,7 @@ static inline bool convertTo(const std::string &str, T &result) /* Check for a '-' in string. If type is unsigned and a - is found, the * parsing fails. This is made necessary because "-1" is read as 65535 for * uint16_t, for example */ - if (str.find("-") != std::string::npos - && !std::numeric_limits<T>::is_signed) { + if (str.find("-") != std::string::npos && !std::numeric_limits<T>::is_signed) { return false; } @@ -83,8 +140,7 @@ static inline bool convertTo(const std::string &str, T &result) if (str.substr(0, 2) == "0x") { if (std::numeric_limits<T>::is_integer) { ss >> std::hex >> result; - } - else { + } else { /* Conversion undefined for non integers */ return false; } @@ -94,6 +150,31 @@ static inline bool convertTo(const std::string &str, T &result) return ss.eof() && !ss.fail() && !ss.bad(); } + +template <typename T, typename Via> +static inline bool convertToVia(const std::string &str, T &result) +{ + /* Check that conversion to that type is allowed. + * If this fails, this means that this template was not intended to be used + * with this type, thus that the result is undefined. */ + static_assert(ConvertionAllowedVia<T, Via>::value, + "convertToVia does not support this conversion"); + + /* We want to override the behaviour of convertTo<T> with that of + * convertTo<Via> and then safely cast the result into a T. */ + Via res; + + if (!convertTo<Via>(str, res)) { + return false; + } + + if ((res > std::numeric_limits<T>::max()) or (res < std::numeric_limits<T>::min())) { + return false; + } + + result = static_cast<T>(res); + return true; +} } // namespace details /** @@ -112,43 +193,44 @@ static inline bool convertTo(const std::string &str, T &result) * * @return true if conversion was successful, false otherwise. */ -template<typename T> +template <typename T> static inline bool convertTo(const std::string &str, T &result) { return details::convertTo<T>(str, result); } -/** - * Specialization for int16_t of convertTo template function. +/** Specialization for unsigned char of convertTo template function. * * This function follows the same paradigm than it's generic version. * - * The specific implementation is made necessary because the stlport version of - * string streams is bugged and does not fail when giving overflowed values. - * This specialisation can be safely removed when stlport behaviour is fixed. + * The generic version was converting char as it was a character + * (unsigned char is an alias to unsigned char on most compiler). + * Thus converting "1" would return 49 ie '1'. + * As convertTo is thought as an _numerical_ convertion tool + * (contrary to boost::lexical_cast for example), + * forbid considering the input as a character and consider unsigned char + * (aka unsigned char) as a number exclusively. * * @param[in] str the string to parse. * @param[out] result reference to object where to store the result. * * @return true if conversion was successful, false otherwise. */ -template<> -inline bool convertTo<int16_t>(const std::string &str, int16_t &result) +template <> +inline bool convertTo<unsigned char>(const std::string &str, unsigned char &result) { - int64_t res; - - if (!convertTo<int64_t>(str, res)) { - return false; - } - - if (res > std::numeric_limits<int16_t>::max() || res < std::numeric_limits<int16_t>::min()) { - return false; - } - - result = static_cast<int16_t>(res); - return true; + return details::convertToVia<unsigned char, unsigned int>(str, result); } +/** Specialization for signed char of convertTo template function. + * + * @see convertTo<unsigned char> + */ +template <> +inline bool convertTo<signed char>(const std::string &str, signed char &result) +{ + return details::convertToVia<signed char, int>(str, result); +} /** * Specialization for float of convertTo template function. * @@ -164,15 +246,14 @@ inline bool convertTo<int16_t>(const std::string &str, int16_t &result) * * @return true if conversion was successful, false otherwise. */ -template<> +template <> inline bool convertTo<float>(const std::string &str, float &result) { if (!details::convertTo(str, result)) { return false; } - if (std::abs(result) == std::numeric_limits<float>::infinity() || - result == std::numeric_limits<float>::quiet_NaN()) { + if (!std::isfinite(result)) { return false; } @@ -194,15 +275,14 @@ inline bool convertTo<float>(const std::string &str, float &result) * * @return true if conversion was successful, false otherwise. */ -template<> +template <> inline bool convertTo<double>(const std::string &str, double &result) { if (!details::convertTo(str, result)) { return false; } - if (std::abs(result) == std::numeric_limits<double>::infinity() || - result == std::numeric_limits<double>::quiet_NaN()) { + if (!std::isfinite(result)) { return false; } @@ -226,7 +306,7 @@ inline bool convertTo<double>(const std::string &str, double &result) * * @return true if conversion was successful, false otherwise. */ -template<> +template <> inline bool convertTo<bool>(const std::string &str, bool &result) { if (str == "0" || str == "FALSE" || str == "false") { diff --git a/utility/posix/DynamicLibrary.cpp b/utility/posix/DynamicLibrary.cpp new file mode 100644 index 0000000..1a3af60 --- /dev/null +++ b/utility/posix/DynamicLibrary.cpp @@ -0,0 +1,67 @@ +/* + * 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 <DynamicLibrary.hpp> + +#include <dlfcn.h> + +#include <stdexcept> + +const std::string DynamicLibrary::_osLibraryPrefix = "lib"; +const std::string DynamicLibrary::_osLibrarySuffix = ".so"; + +DynamicLibrary::DynamicLibrary(const std::string &path) : _path(osSanitizePathName(path)) +{ + _handle = dlopen(_path.c_str(), RTLD_LAZY); + + if (_handle == nullptr) { + + const char *dlError = dlerror(); + throw std::runtime_error((dlError != NULL) ? dlError : "unknown dlopen error"); + } +} + +DynamicLibrary::~DynamicLibrary(void) +{ + dlclose(_handle); +} + +void *DynamicLibrary::osGetSymbol(const std::string &symbol) const +{ + void *sym = dlsym(_handle, symbol.c_str()); + + if (sym == nullptr) { + + const char *dlError = dlerror(); + throw std::runtime_error((dlError != NULL) ? dlError : "unknown dlsym error"); + } + + return sym; +} diff --git a/utility/test/utility.cpp b/utility/test/utility.cpp new file mode 100644 index 0000000..26be9e1 --- /dev/null +++ b/utility/test/utility.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2011-2014, 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 "Utility.h" +#include "BinaryCopy.hpp" + +#include <catch.hpp> +#include <functional> +#include <map> + +using std::list; +using std::string; + +namespace utility +{ + +SCENARIO("join<int>") +{ + struct Test + { + list<int> input; + std::function<int(int, int)> binaryOpt; + int empty; + int result; + int resultNoEmpty; + }; + const list<Test> tests = {{{}, nullptr, 21, 21, 0}, + {{5}, nullptr, -1, 5, 5}, + {{5, 2}, [](int, int) { return 73; }, -1, 73, 73}, + {{2, 3, 7}, [](int l, int r) { return l * r; }, -1, 42, 42}, + {{1, 10, 100}, [](int l, int r) { return l + r; }, -1, 111, 111}}; + for (auto &test : tests) { + CAPTURE(Catch::toString(test.input)); + const auto &first = begin(test.input); + const auto &last = end(test.input); + REQUIRE(join(first, last, test.binaryOpt, test.empty) == test.result); + REQUIRE(join<int>(first, last, test.binaryOpt) == test.resultNoEmpty); + } +} + +SCENARIO("asString(list)") +{ + struct Test + { + string title; + list<string> input; + string separator; + string result; + string resultNoSep; + }; + const list<Test> tests = { + {"Empty list", {}, "aa", "", ""}, + {"One element", {"a"}, "<>", "a", "a"}, + {"Three elem list", {"1", "2", "3"}, "**", "1**2**3", "1\n2\n3"}, + {"No separator", {"12", "ab", "+-"}, "", "12ab+-", "12\nab\n+-"}, + {"empty elem list", {"a", "b", "", "d"}, "|", "a|b||d", "a\nb\n\nd"}, + }; + for (auto &test : tests) { + CAPTURE(Catch::toString(test.input)); + WHEN ("Separator, " + test.title) { + CAPTURE(test.separator); + REQUIRE(asString(test.input, test.separator) == test.result); + } + THEN ("No separator, " + test.title) { + REQUIRE(asString(test.input) == test.resultNoSep); + } + } +} + +SCENARIO("asString(map)") +{ + using std::map; + + using Map = map<string, string>; + struct Test + { + Map input; + string itemSep; + string keyValueSep; + string result; + string resultNoKeyValueSep; + string resultNoSep; + }; + const list<Test> tests = {{{}, "itemSep", "keyValueSep", "", "", ""}, + { + Map{{"a", "b"}, {"c", "d"}, {"e", "f"}}, // input + " - ", "\n", // item & keyValue sep + "a - b\nc - d\ne - f", // result + "a:b\nc:d\ne:f", // resultNoKeyValueSep + "a:b, c:d, e:f" // resultNoSep + }}; + for (const auto &test : tests) { + CAPTURE(Catch::toString(test.input)); + CAPTURE(test.keyValueSep); + CAPTURE(test.itemSep); + REQUIRE(asString(test.input, test.keyValueSep, test.itemSep) == test.result); + REQUIRE(asString(test.input, test.keyValueSep) == test.resultNoKeyValueSep); + REQUIRE(asString(test.input) == test.resultNoSep); + } +} + +SCENARIO("appendTitle") +{ + struct Test + { + string initial; + string title; + string result; + }; + const list<Test> tests = {{"", "abc", "\nabc\n===\n"}, + {"start", "title", "start\ntitle\n=====\n"}}; + for (auto &test : tests) { + auto quote = [](std::string toQuote) { return '"' + toQuote + '"'; }; + + GIVEN ("A title: " + quote(test.title)) { + CAPTURE(test.initial); + CAPTURE(test.title); + + WHEN ("Appending to: " + quote(test.initial)) { + string output = test.initial; + THEN ("Result should be:\n" + quote(test.result)) { + appendTitle(output, test.title); + CHECK(output == test.result); + } + } + } + } +} + +SCENARIO("isNotHexadecimal") +{ + for (auto &str : {"a", "0", "012", "13", "ABC", "Oxa"}) { + CAPTURE(str); + CHECK(not isHexadecimal(str)); + } +} + +SCENARIO("isHexadecimal") +{ + for (auto str : {"0xa", "0X0", "0x012", "0x13", "0xConsider as hexa as starting with 0x"}) { + CAPTURE(str); + CHECK(isHexadecimal(str)); + } +} + +template <class T1, class T2> +void checkBinaryEqual(T1 v1, T2 v2) +{ + // For some yet-unknown reason, GCC 4.8 complains about + // CHECK(a == b); + // and suggests that parentheses should be added. This is related to catch + // internals but such construcuts have been used without problem in lots of + // other places... + // Besides, GCC 4.9 does not seem to have a problem with that either. + // As a workaround, captures variables and parenthesize the expressions. + + auto v2AsT1 = utility::binaryCopy<T1>(v2); + CAPTURE(v1); + CAPTURE(v2AsT1); + CHECK((v1 == v2AsT1)); + + auto v1AsT2 = utility::binaryCopy<T2>(v1); + CAPTURE(v2); + CAPTURE(v1AsT2); + CHECK((v2 == v1AsT2)); +} + +SCENARIO("binaryCopy bit exactness") +{ + GIVEN ("Integer representations computed using http://babbage.cs.qc.cuny.edu/IEEE-754/") { + + THEN ("Floats should be coded on 32bits and fulfill IEEE-754." + " That assumption is made in the Parameter Framework.") { + REQUIRE(sizeof(float) == sizeof(uint32_t)); + REQUIRE(std::numeric_limits<float>::is_iec559); + } + WHEN ("Testing float <=> uint32_t conversion") { + checkBinaryEqual<float, uint32_t>(1.23456f, 0x3f9e0610); + } + + THEN ("Doubles should be coded on 64bits and fulfill IEEE-754." + " That assumption is made in the Parameter Framework.") { + REQUIRE(sizeof(double) == sizeof(uint64_t)); + REQUIRE(std::numeric_limits<double>::is_iec559); + } + WHEN ("Testing double <=> uint64_t conversion") { + checkBinaryEqual<double, uint64_t>(987.65432109876, 0x408edd3c0cb3420e); + } + } + + WHEN ("Testing int8_t <=> uint8_t conversion") { + checkBinaryEqual<int8_t, uint8_t>(-1, 0xff); + } +} + +} // namespace utility diff --git a/utility/FullIo.hpp b/utility/windows/DynamicLibrary.cpp index 353551d..7901367 100644 --- a/utility/FullIo.hpp +++ b/utility/windows/DynamicLibrary.cpp @@ -28,41 +28,46 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma once +#include <DynamicLibrary.hpp> -#include <cstddef> +#include "windows.h" -namespace utility +#include <stdexcept> + +const std::string DynamicLibrary::_osLibraryPrefix = ""; +const std::string DynamicLibrary::_osLibrarySuffix = ".dll"; + +DynamicLibrary::DynamicLibrary(const std::string &path) : _path(osSanitizePathName(path)) { + static_assert(sizeof(void *) == sizeof(HMODULE), "Incompatible object size"); -/** Write *completely* a buffer in a file descriptor. - * - * A wrapper around unistd::write that resumes write on incomplete access - * and EAGAIN/EINTR error. - * - * @see man 2 write for the parameters. - * - * @return true if the buffer could be completely written, - * false on failure (see write's man errno section). - */ -bool fullWrite(int fd, const void *buf, size_t count); + HMODULE module = LoadLibrary(_path.c_str()); -/** Fill a buffer from a file descriptor. - * - * A wrapper around unistd::read that resumes read on incomplete access - * and EAGAIN/EINTR error. - * - * @see man 2 read for the parameters. - * - * @return true if the buffer could be completely fill, - * false on failure (see read's man errno section). - * - * If the buffer could not be filled due to an EOF, return false but set - * errno to 0. - * @TODO Add a custom strerror to prevent logging "success" (`sterror(0)`) on - * EOF errors ? - */ -bool fullRead(int fd, void *buf, size_t count); + _handle = reinterpret_cast<void *>(module); + + if (_handle == nullptr) { + + throw std::runtime_error(_path + ": cannot open shared object file."); + } +} + +DynamicLibrary::~DynamicLibrary() +{ + HMODULE module = reinterpret_cast<HMODULE>(_handle); + + FreeLibrary(module); +} + +void *DynamicLibrary::osGetSymbol(const std::string &symbol) const +{ + HMODULE module = reinterpret_cast<HMODULE>(_handle); + + void *sym = reinterpret_cast<void *>(GetProcAddress(module, symbol.c_str())); + + if (sym == nullptr) { -} // namespace utility + throw std::runtime_error(_path + ": undefined symbol: " + symbol); + } + return sym; +} diff --git a/xmlserializer/Android.mk b/xmlserializer/Android.mk deleted file mode 100644 index 2c66caf..0000000 --- a/xmlserializer/Android.mk +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright (c) 2011-2014, 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. - -LOCAL_PATH := $(call my-dir) - -#################### -# Common definitions - -common_src_files := \ - XmlElement.cpp \ - XmlSerializingContext.cpp \ - XmlDocSource.cpp \ - XmlMemoryDocSink.cpp \ - XmlMemoryDocSource.cpp \ - XmlStreamDocSink.cpp \ - -common_module := libxmlserializer - -common_module_tags := optional - -# Do not use the '-Werror' flag because of a compilation issue in libxml -common_cflags := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter - -common_c_includes := \ - external/libxml2/include \ - external/icu/icu4c/source/common \ - -common_shared_libraries := libicuuc -common_static_libraries := libxml2 - -############################# -# Target build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -LOCAL_MODULE := $(common_module) -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_CFLAGS := $(common_cflags) - -LOCAL_C_INCLUDES := $(common_c_includes) - -LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) -LOCAL_STATIC_LIBRARIES := $(common_static_libraries) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -ifeq ($(INCLUDE_STLPORT), true) - include external/stlport/libstlport.mk -endif - -include $(BUILD_SHARED_LIBRARY) - -############################## -# Host build - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(common_src_files) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -LOCAL_MODULE := $(common_module)_host -LOCAL_MODULE_OWNER := intel -LOCAL_MODULE_TAGS := $(common_module_tags) - -LOCAL_CFLAGS := $(common_cflags) - -LOCAL_C_INCLUDES += $(common_c_includes) - -LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)-host -LOCAL_STATIC_LIBRARIES := libxml2 - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) - -include $(BUILD_HOST_SHARED_LIBRARY) - diff --git a/xmlserializer/CMakeLists.txt b/xmlserializer/CMakeLists.txt index be068c9..067a00e 100644 --- a/xmlserializer/CMakeLists.txt +++ b/xmlserializer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2014-2015, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,36 +26,47 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_library(xmlserializer SHARED +add_library(xmlserializer STATIC XmlElement.cpp XmlSerializingContext.cpp XmlDocSource.cpp XmlMemoryDocSink.cpp XmlMemoryDocSource.cpp - XmlStreamDocSink.cpp) + XmlStreamDocSink.cpp + XmlUtil.cpp) -include(FindLibXml2) -if(NOT LIBXML2_FOUND) - message(SEND_ERROR " - libxml2 NOT found. The parameter-framework wont compile. - Please install the development package (e.g. libxml2-dev on debian-based - Linux distributions).") -else(NOT LIBXML2_FOUND) - # libxml2 has been found, but does it support XInclude ? - include(CheckLibraryExists) - check_library_exists(xml2 xmlXIncludeProcess "" XML2_XINCLUDE_SUPPORT) - if(NOT XML2_XINCLUDE_SUPPORT) - message(SEND_ERROR " - libxml2 has not been built with support for XInclude. xmlserializer needs - that feature; please install a version of libxml2 supporting it.") - endif(NOT XML2_XINCLUDE_SUPPORT) -endif(NOT LIBXML2_FOUND) +set_target_properties(xmlserializer PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + +find_package(LibXml2 REQUIRED) + +# libxml2 has been found, but does it support XInclude ? +include(CMakePushCheckState) +# Save the previous state of CMAKE_REQUIRED_* variables and empty them +cmake_push_check_state() +cmake_reset_check_state() +include(CheckSymbolExists) +set(CMAKE_REQUIRED_DEFINITIONS ${LIBXML2_DEFINITIONS}) +set(CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIR}) +# Check that the LIBXML_XINCLUDE_ENABLED macro is defined +# This is the safest check, as it does not involve linking against anything +# (which might fail for another reason than the lack of XInclude support) +check_symbol_exists(LIBXML_XINCLUDE_ENABLED libxml/xmlversion.h XML2_XINCLUDE_SUPPORT) +# Restore the previous state +cmake_pop_check_state() +if(NOT XML2_XINCLUDE_SUPPORT) + message(SEND_ERROR + "libxml2 has not been built with support for XInclude." + "xmlserializer needs that feature;" + "please install a version of libxml2 supporting it.") +endif() + +target_include_directories(xmlserializer PUBLIC .) + +target_link_libraries(xmlserializer + PUBLIC pfw_utility # For NonCopyable and ErrorContext + PRIVATE LibXml2::libxml2) -include_directories(${LIBXML2_INCLUDE_DIR}) -target_link_libraries(xmlserializer ${LIBXML2_LIBRARIES}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBXML2_DEFINITIONS}") -install(TARGETS xmlserializer LIBRARY DESTINATION lib) install(FILES XmlSink.h XmlSource.h diff --git a/xmlserializer/XmlDocSink.h b/xmlserializer/XmlDocSink.h index f7a87b9..9c215f3 100644 --- a/xmlserializer/XmlDocSink.h +++ b/xmlserializer/XmlDocSink.h @@ -32,6 +32,8 @@ #include "XmlDocSource.h" #include "XmlSerializingContext.h" +#include "NonCopyable.hpp" + /** * The CXmlDocSink class defines how to use a CXmlDocSource. * The interaction between the xml source and xml sink is defined @@ -39,7 +41,7 @@ * for different purpose by implementing the doProcess method and then * use it with any existing implementation of CXmlDocSource. */ -class CXmlDocSink +class CXmlDocSink : private utility::NonCopyable { public: /** @@ -52,7 +54,7 @@ public: * * @return true is there was no error during the processing of xmlDocSource */ - bool process(CXmlDocSource& xmlDocSource, CXmlSerializingContext& serializingContext) + bool process(CXmlDocSource &xmlDocSource, CXmlSerializingContext &serializingContext) { if (!xmlDocSource.populate(serializingContext)) { return false; @@ -73,5 +75,6 @@ private: * * @return true is there was no error during the processing of xmlDocSource */ - virtual bool doProcess(CXmlDocSource& xmlDocSource, CXmlSerializingContext& serializingContext) = 0; + virtual bool doProcess(CXmlDocSource &xmlDocSource, + CXmlSerializingContext &serializingContext) = 0; }; diff --git a/xmlserializer/XmlDocSource.cpp b/xmlserializer/XmlDocSource.cpp index 90a30ac..ed366bf 100644 --- a/xmlserializer/XmlDocSource.cpp +++ b/xmlserializer/XmlDocSource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,45 +29,31 @@ */ #include "XmlDocSource.h" +#include "AlwaysAssert.hpp" #include <libxml/tree.h> #include <libxml/xmlschemas.h> #include <libxml/parser.h> #include <libxml/xinclude.h> -#include <libxml/xmlerror.h> -#include <stdlib.h> +#include <libxml/uri.h> +#include <memory> +#include <stdexcept> using std::string; +using xml_unique_ptr = std::unique_ptr<xmlChar, decltype(xmlFree)>; -// Schedule for libxml2 library -bool CXmlDocSource::_bLibXml2CleanupScheduled; - -CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema, - _xmlNode *pRootNode) : - _pDoc(pDoc), - _pRootNode(pRootNode), - _strXmlSchemaFile(""), - _strRootElementType(""), - _strRootElementName(""), - _strNameAttributeName(""), - _bValidateWithSchema(bValidateWithSchema) +CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema, _xmlNode *pRootNode) + : _pDoc(pDoc), _pRootNode(pRootNode), _strRootElementType(""), _strRootElementName(""), + _strNameAttributeName(""), _bValidateWithSchema(bValidateWithSchema) { - init(); } CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema, - const string& strXmlSchemaFile, - const string& strRootElementType, - const string& strRootElementName, - const string& strNameAttributeName) : - _pDoc(pDoc), - _pRootNode(xmlDocGetRootElement(pDoc)), - _strXmlSchemaFile(strXmlSchemaFile), - _strRootElementType(strRootElementType), - _strRootElementName(strRootElementName), - _strNameAttributeName(strNameAttributeName), - _bValidateWithSchema(bValidateWithSchema) + const string &strRootElementType, const string &strRootElementName, + const string &strNameAttributeName) + : _pDoc(pDoc), _pRootNode(xmlDocGetRootElement(pDoc)), _strRootElementType(strRootElementType), + _strRootElementName(strRootElementName), _strNameAttributeName(strNameAttributeName), + _bValidateWithSchema(bValidateWithSchema) { - init(); } CXmlDocSource::~CXmlDocSource() @@ -79,41 +65,55 @@ CXmlDocSource::~CXmlDocSource() } } -void CXmlDocSource::getRootElement(CXmlElement& xmlRootElement) const +void CXmlDocSource::getRootElement(CXmlElement &xmlRootElement) const { xmlRootElement.setXmlElement(_pRootNode); } string CXmlDocSource::getRootElementName() const { - return (const char*)_pRootNode->name; + return (const char *)_pRootNode->name; } -string CXmlDocSource::getRootElementAttributeString(const string& strAttributeName) const +string CXmlDocSource::getRootElementAttributeString(const string &strAttributeName) const { CXmlElement topMostElement(_pRootNode); - return topMostElement.getAttributeString(strAttributeName); + string attribute; + topMostElement.getAttribute(strAttributeName, attribute); + return attribute; } -_xmlDoc* CXmlDocSource::getDoc() const +void CXmlDocSource::setSchemaBaseUri(const string &uri) { - return _pDoc; + _schemaBaseUri = uri; } -bool CXmlDocSource::isParsable() const +string CXmlDocSource::getSchemaBaseUri() { - // Check that the doc has been created - return _pDoc != NULL; + return _schemaBaseUri; } -bool CXmlDocSource::populate(CXmlSerializingContext& serializingContext) +string CXmlDocSource::getSchemaUri() const { - return validate(serializingContext); + // Adding a trailing '/' is a bit dirty but works fine on both Linux and + // Windows in order to make sure that libxml2's URI handling methods + // interpret the base URI as a folder. + return mkUri(_schemaBaseUri + "/", getRootElementName() + ".xsd"); +} +_xmlDoc *CXmlDocSource::getDoc() const +{ + return _pDoc; } -bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext) +bool CXmlDocSource::isParsable() const +{ + // Check that the doc has been created + return _pDoc != NULL; +} + +bool CXmlDocSource::populate(CXmlSerializingContext &serializingContext) { // Check that the doc has been created if (!_pDoc) { @@ -124,8 +124,7 @@ bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext) } // Validate if necessary - if (_bValidateWithSchema) - { + if (_bValidateWithSchema) { if (!isInstanceDocumentValid()) { serializingContext.setError("Document is not valid"); @@ -138,8 +137,8 @@ bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext) if (getRootElementName() != _strRootElementType) { serializingContext.setError("Error: Wrong XML structure document "); - serializingContext.appendLineToError("Root Element " + getRootElementName() - + " mismatches expected type " + _strRootElementType); + serializingContext.appendLineToError("Root Element " + getRootElementName() + + " mismatches expected type " + _strRootElementType); return false; } @@ -152,10 +151,9 @@ bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext) if (!_strRootElementName.empty() && strRootElementNameCheck != _strRootElementName) { serializingContext.setError("Error: Wrong XML structure document "); - serializingContext.appendLineToError(_strRootElementType + " element " - + _strRootElementName + " mismatches expected " - + _strRootElementType + " type " - + strRootElementNameCheck); + serializingContext.appendLineToError( + _strRootElementType + " element " + _strRootElementName + " mismatches expected " + + _strRootElementType + " type " + strRootElementNameCheck); return false; } @@ -164,21 +162,12 @@ bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext) return true; } -void CXmlDocSource::init() -{ - if (!_bLibXml2CleanupScheduled) { - - // Schedule cleanup - atexit(xmlCleanupParser); - - _bLibXml2CleanupScheduled = true; - } -} - bool CXmlDocSource::isInstanceDocumentValid() { #ifdef LIBXML_SCHEMAS_ENABLED - xmlDocPtr pSchemaDoc = xmlReadFile(_strXmlSchemaFile.c_str(), NULL, XML_PARSE_NONET); + string schemaUri = getSchemaUri(); + + xmlDocPtr pSchemaDoc = xmlReadFile(schemaUri.c_str(), NULL, XML_PARSE_NONET); if (!pSchemaDoc) { // Unable to load Schema @@ -215,8 +204,6 @@ bool CXmlDocSource::isInstanceDocumentValid() return false; } - xmlSetStructuredErrorFunc(this, schemaValidityStructuredErrorFunc); - bool isDocValid = xmlSchemaValidateDoc(pValidationCtxt, _pDoc) == 0; xmlSchemaFreeValidCtxt(pValidationCtxt); @@ -230,19 +217,23 @@ bool CXmlDocSource::isInstanceDocumentValid() #endif } -void CXmlDocSource::schemaValidityStructuredErrorFunc(void* pUserData, _xmlError* pError) +std::string CXmlDocSource::mkUri(const std::string &base, const std::string &relative) { - (void)pUserData; + xml_unique_ptr baseUri(xmlPathToURI((const xmlChar *)base.c_str()), xmlFree); + xml_unique_ptr relativeUri(xmlPathToURI((const xmlChar *)relative.c_str()), xmlFree); + /* return null pointer if baseUri or relativeUri are null pointer */ + xml_unique_ptr xmlUri(xmlBuildURI(relativeUri.get(), baseUri.get()), xmlFree); -#ifdef LIBXML_SCHEMAS_ENABLED - // Display message - puts(pError->message); -#endif + ALWAYS_ASSERT(xmlUri != nullptr, "unable to make URI from: \"" << base << "\" and \"" + << relative << "\""); + + return (const char *)xmlUri.get(); } -_xmlDoc* CXmlDocSource::mkXmlDoc(const string& source, bool fromFile, bool xincludes, string& errorMsg) +_xmlDoc *CXmlDocSource::mkXmlDoc(const string &source, bool fromFile, bool xincludes, + CXmlSerializingContext &serializingContext) { - _xmlDoc* doc = NULL; + _xmlDoc *doc = NULL; if (fromFile) { doc = xmlReadFile(source.c_str(), NULL, 0); } else { @@ -250,25 +241,17 @@ _xmlDoc* CXmlDocSource::mkXmlDoc(const string& source, bool fromFile, bool xincl } if (doc == NULL) { - errorMsg = "libxml failed to read"; + string errorMsg = "libxml failed to read"; if (fromFile) { errorMsg += " \"" + source + "\""; } - - xmlError* details = xmlGetLastError(); - if (details != NULL) { - errorMsg += ": " + string(details->message); - } + serializingContext.appendLineToError(errorMsg); return NULL; } if (xincludes and (xmlXIncludeProcess(doc) < 0)) { - errorMsg = "libxml failed to resolve XIncludes"; - xmlError* details = xmlGetLastError(); - if (details != NULL) { - errorMsg += ": " + string(details->message); - } + serializingContext.appendLineToError("libxml failed to resolve XIncludes"); xmlFreeDoc(doc); doc = NULL; diff --git a/xmlserializer/XmlDocSource.h b/xmlserializer/XmlDocSource.h index e41923e..85b4114 100644 --- a/xmlserializer/XmlDocSource.h +++ b/xmlserializer/XmlDocSource.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,6 +31,9 @@ #pragma once #include "XmlElement.h" #include "XmlSerializingContext.h" + +#include "NonCopyable.hpp" + #include <string> struct _xmlDoc; @@ -44,7 +47,7 @@ struct _xmlError; * for different purposes by implementing the populate method and then * use it with any existing implementation of CXmlDocSink. */ -class CXmlDocSource +class CXmlDocSource : private utility::NonCopyable { public: /** @@ -54,23 +57,21 @@ public: * @param[in] pRootNode a pointer to the root element of the document. * @param[in] bValidateWithSchema a boolean that toggles schema validation */ - CXmlDocSource(_xmlDoc* pDoc, bool bValidateWithSchema = false, _xmlNode* pRootNode = NULL); + CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema = false, _xmlNode *pRootNode = NULL); /** * Constructor * * @param[out] pDoc a pointer to the xml document that will be filled by the class - * @param[in] strXmlSchemaFile a string containing the path to the schema file * @param[in] strRootElementType a string containing the root element type * @param[in] strRootElementName a string containing the root element name * @param[in] strNameAttributeName a string containing the name of the root name attribute * @param[in] bValidateWithSchema a boolean that toggles schema validation */ - CXmlDocSource(_xmlDoc* pDoc, bool bValidateWithSchema, - const std::string& strXmlSchemaFile = "", - const std::string& strRootElementType = "", - const std::string& strRootElementName = "", - const std::string& strNameAttributeName = ""); + CXmlDocSource(_xmlDoc *pDoc, bool bValidateWithSchema, + const std::string &strRootElementType = "", + const std::string &strRootElementName = "", + const std::string &strNameAttributeName = ""); /** * Destructor @@ -84,14 +85,14 @@ public: * * @return false if there are any error */ - virtual bool populate(CXmlSerializingContext& serializingContext); + virtual bool populate(CXmlSerializingContext &serializingContext); /** * Method that returns the root element of the Xml tree. * * @param[out] xmlRootElement a reference to the CXmleElement destination */ - void getRootElement(CXmlElement& xmlRootElement) const; + void getRootElement(CXmlElement &xmlRootElement) const; /** * Getter method. @@ -100,6 +101,19 @@ public: */ std::string getRootElementName() const; + /** Get the Schemas' base (folder) URI + */ + std::string getSchemaBaseUri(); + + /** Set the Schema's base (folder) URI + * + * The schema for validating the XML document will be searched for in that + * folder. + * + * @param[in] uri The Schemas' base URI + */ + void setSchemaBaseUri(const std::string &uri); + /** * Getter method. * Method that returns the root element's attribute with name matching strAttributeName. @@ -108,7 +122,7 @@ public: * * @return the value of the root's attribute named as strAttributeName */ - std::string getRootElementAttributeString(const std::string& strAttributeName) const; + std::string getRootElementAttributeString(const std::string &strAttributeName) const; /** * Getter method. @@ -117,16 +131,7 @@ public: * * @return the document _pDoc */ - _xmlDoc* getDoc() const; - - /** - * Method that validates the Xml doc contained in pDoc - * - * @param[out] serializingContext is used as error output - * - * @return false if any error occurs - */ - virtual bool validate(CXmlSerializingContext& serializingContext); + _xmlDoc *getDoc() const; /** * Method that checks that the xml document has been correctly parsed. @@ -136,6 +141,23 @@ public: virtual bool isParsable() const; /** + * Helper method to build final URI from base and relative uri/path + * + * base = "/path/to/file.xml" + * - uri - returned value + * . /path/to/ + * file.xsd /path/to/file.xsd + * ../from/file.xsd /path/from/file.xsd + * /path2/file.xsd /path2/file.xsd + * + * @param[in] base uri, if base is directory, it must contains separator last + * @param[in] relative uri + * + * @return new made URI if succeeded relative input otherwise + */ + static std::string mkUri(const std::string &base, const std::string &relative); + + /** * Helper method for creating an xml document from either a file or a * string. * @@ -143,51 +165,29 @@ public: * @param[in] fromFile true if source is a filename, false if source is an xml * represents an xml document * @param[in] xincludes if true, process xincludes tags - * @param[out] errorMsg used as error output + * @param[in] serializingContext will receive any serialization error */ - static _xmlDoc* mkXmlDoc(const std::string& source, bool fromFile, bool xincludes, std::string& errorMsg); + static _xmlDoc *mkXmlDoc(const std::string &source, bool fromFile, bool xincludes, + CXmlSerializingContext &serializingContext); protected: - /** * Doc */ - _xmlDoc* _pDoc; + _xmlDoc *_pDoc; /** * Root node */ - _xmlNode* _pRootNode; - - /** - * libxml2 library cleanup - */ - static bool _bLibXml2CleanupScheduled; + _xmlNode *_pRootNode; private: - - /** - * Method that initializes class internal attributes in constructor - */ - void init(); - /** Method that check the validity of the document with the xsd file. * * @return true if document is valid, false if any error occures */ bool isInstanceDocumentValid(); - - /** Validity error display method - * - * @param[in] pUserData pointer to the data to validate - * @param[out] pError is the xml error output - */ - static void schemaValidityStructuredErrorFunc(void* pUserData, _xmlError* pError); - - /** - * Schema file - */ - std::string _strXmlSchemaFile; + std::string getSchemaUri() const; /** * Element type info @@ -208,4 +208,6 @@ private: * Boolean that enables the validation via xsd files */ bool _bValidateWithSchema; + + std::string _schemaBaseUri; }; diff --git a/xmlserializer/XmlElement.cpp b/xmlserializer/XmlElement.cpp index 425e041..902d0d9 100644 --- a/xmlserializer/XmlElement.cpp +++ b/xmlserializer/XmlElement.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -29,13 +29,12 @@ */ #include "XmlElement.h" #include <libxml/tree.h> +#include "convert.hpp" #include <stdlib.h> -#include <sstream> using std::string; -using std::ostringstream; -CXmlElement::CXmlElement(_xmlNode* pXmlElement) : _pXmlElement(pXmlElement) +CXmlElement::CXmlElement(_xmlNode *pXmlElement) : _pXmlElement(pXmlElement) { } @@ -43,14 +42,14 @@ CXmlElement::CXmlElement() : _pXmlElement(NULL) { } -void CXmlElement::setXmlElement(_xmlNode* pXmlElement) +void CXmlElement::setXmlElement(_xmlNode *pXmlElement) { _pXmlElement = pXmlElement; } string CXmlElement::getType() const { - return (const char*)_pXmlElement->name; + return (const char *)_pXmlElement->name; } string CXmlElement::getPath() const @@ -72,82 +71,71 @@ string CXmlElement::getPath() const return strPathElement; } -string CXmlElement::getNameAttribute() const -{ - return getAttributeString("Name"); -} - -bool CXmlElement::hasAttribute(const string& strAttributeName) const +bool CXmlElement::hasAttribute(const string &strAttributeName) const { - return xmlHasProp(_pXmlElement, (const xmlChar*)strAttributeName.c_str()) != NULL; + return xmlHasProp(_pXmlElement, (const xmlChar *)strAttributeName.c_str()) != NULL; } -string CXmlElement::getAttributeString(const string &strAttributeName) const +template <> +bool CXmlElement::getAttribute<std::string>(const string &name, string &value) const { - if (!hasAttribute(strAttributeName)) { - - return ""; + if (!hasAttribute(name)) { + return false; } - xmlChar* pucXmlValue = xmlGetProp((xmlNode*)_pXmlElement, (const xmlChar*)strAttributeName.c_str()); + + string backup = value; + xmlChar *pucXmlValue = xmlGetProp((xmlNode *)_pXmlElement, (const xmlChar *)name.c_str()); if (pucXmlValue == NULL) { - return ""; + value = backup; + return false; } - string strValue((const char*)pucXmlValue); + value = (const char *)pucXmlValue; xmlFree(pucXmlValue); - return strValue; -} - -bool CXmlElement::getAttributeBoolean(const string& strAttributeName, const string& strTrueValue) const -{ - return getAttributeString(strAttributeName) == strTrueValue; + return true; } -bool CXmlElement::getAttributeBoolean(const string& strAttributeName) const +template <typename T> +bool CXmlElement::getAttribute(const std::string &name, T &value) const { - string strAttributeValue(getAttributeString(strAttributeName)); - - return strAttributeValue == "true" || strAttributeValue == "1"; -} - -uint32_t CXmlElement::getAttributeInteger(const string &strAttributeName) const -{ - string strAttributeValue(getAttributeString(strAttributeName)); - - return strtoul(strAttributeValue.c_str(), NULL, 0); -} + std::string rawValue; + if (!getAttribute(name, rawValue)) { + return false; + } -int32_t CXmlElement::getAttributeSignedInteger(const string &strAttributeName) const -{ - string strAttributeValue(getAttributeString(strAttributeName)); + T backup = value; + if (!convertTo<T>(rawValue, value)) { + value = backup; + return false; + } - return strtol(strAttributeValue.c_str(), NULL, 0); + return true; } -double CXmlElement::getAttributeDouble(const string &strAttributeName) const +string CXmlElement::getNameAttribute() const { - string strAttributeValue(getAttributeString(strAttributeName)); - - return strtod(strAttributeValue.c_str(), NULL); + string attribute; + getAttribute("Name", attribute); + return attribute; } string CXmlElement::getTextContent() const { - xmlChar* pucXmlContent = xmlNodeGetContent(_pXmlElement); + xmlChar *pucXmlContent = xmlNodeGetContent(_pXmlElement); if (pucXmlContent == NULL) { return ""; } - string strContent((const char*)pucXmlContent); + string strContent((const char *)pucXmlContent); xmlFree(pucXmlContent); return strContent; } -bool CXmlElement::getChildElement(const string& strType, CXmlElement& childElement) const +bool CXmlElement::getChildElement(const string &strType, CXmlElement &childElement) const { CChildIterator childIterator(*this); @@ -161,13 +149,15 @@ bool CXmlElement::getChildElement(const string& strType, CXmlElement& childEleme return false; } -bool CXmlElement::getChildElement(const string& strType, const string& strNameAttribute, CXmlElement& childElement) const +bool CXmlElement::getChildElement(const string &strType, const string &strNameAttribute, + CXmlElement &childElement) const { CChildIterator childIterator(*this); while (childIterator.next(childElement)) { - if ((childElement.getType() == strType) && (childElement.getNameAttribute() == strNameAttribute)) { + if ((childElement.getType() == strType) && + (childElement.getNameAttribute() == strNameAttribute)) { return true; } @@ -189,9 +179,9 @@ size_t CXmlElement::getNbChildElements() const return uiNbChildren; } -bool CXmlElement::getParentElement(CXmlElement& parentElement) const +bool CXmlElement::getParentElement(CXmlElement &parentElement) const { - _xmlNode* pXmlNode = _pXmlElement->parent; + _xmlNode *pXmlNode = _pXmlElement->parent; if (pXmlNode->type == XML_ELEMENT_NODE) { @@ -202,44 +192,46 @@ bool CXmlElement::getParentElement(CXmlElement& parentElement) const return false; } -// Setters -void CXmlElement::setAttributeBoolean(const string& strAttributeName, bool bValue) +template <> +void CXmlElement::setAttribute<bool>(const string &name, const bool &value) { - setAttributeString(strAttributeName, bValue ? "true" : "false"); + setAttribute(name, value ? "true" : "false"); } - -void CXmlElement::setAttributeString(const string& strAttributeName, const string& strValue) +template <> +void CXmlElement::setAttribute<std::string>(const string &name, const string &value) { - xmlNewProp(_pXmlElement, BAD_CAST strAttributeName.c_str(), BAD_CAST strValue.c_str()); + setAttribute(name, value.c_str()); } -void CXmlElement::setAttributeInteger(const string& strAttributeName, uint32_t uiValue) +// This method exists for 2 reasons: +// - at link time, all calls to setAttribute(const string&, const char [N]) +// for any value of N will all resolve to this method; this prevents the +// need for one template instance per value of N. +// - the libxml2 API takes a C-style string anyway. +void CXmlElement::setAttribute(const string &name, const char *value) { - ostringstream strStream; - strStream << uiValue; - setAttributeString(strAttributeName, strStream.str()); + xmlNewProp(_pXmlElement, BAD_CAST name.c_str(), BAD_CAST value); } -void CXmlElement::setAttributeSignedInteger(const string& strAttributeName, int32_t iValue) +template <typename T> +void CXmlElement::setAttribute(const std::string &name, const T &value) { - ostringstream strStream; - strStream << iValue; - setAttributeString(strAttributeName, strStream.str()); + setAttribute(name, std::to_string(value).c_str()); } -void CXmlElement::setNameAttribute(const string& strValue) +void CXmlElement::setNameAttribute(const string &strValue) { - setAttributeString("Name", strValue); + setAttribute("Name", strValue); } -void CXmlElement::setTextContent(const string& strContent) +void CXmlElement::setTextContent(const string &strContent) { xmlAddChild(_pXmlElement, xmlNewText(BAD_CAST strContent.c_str())); } // Child creation -void CXmlElement::createChild(CXmlElement& childElement, const string& strType) +void CXmlElement::createChild(CXmlElement &childElement, const string &strType) { #ifdef LIBXML_TREE_ENABLED xmlNodePtr pChildNode = xmlNewChild(_pXmlElement, NULL, BAD_CAST strType.c_str(), NULL); @@ -249,11 +241,12 @@ void CXmlElement::createChild(CXmlElement& childElement, const string& strType) } // Child iteration -CXmlElement::CChildIterator::CChildIterator(const CXmlElement& xmlElement) : _pCurNode(xmlElement._pXmlElement->children) +CXmlElement::CChildIterator::CChildIterator(const CXmlElement &xmlElement) + : _pCurNode(xmlElement._pXmlElement->children) { } -bool CXmlElement::CChildIterator::next(CXmlElement& xmlChildElement) +bool CXmlElement::CChildIterator::next(CXmlElement &xmlChildElement) { while (_pCurNode) { @@ -271,3 +264,28 @@ bool CXmlElement::CChildIterator::next(CXmlElement& xmlChildElement) return false; } +template bool CXmlElement::getAttribute(const std::string &name, std::string &value) const; +template bool CXmlElement::getAttribute(const std::string &name, bool &value) const; +template bool CXmlElement::getAttribute(const std::string &name, short &value) const; +template bool CXmlElement::getAttribute(const std::string &name, unsigned short &value) const; +template bool CXmlElement::getAttribute(const std::string &name, int &value) const; +template bool CXmlElement::getAttribute(const std::string &name, unsigned int &value) const; +template bool CXmlElement::getAttribute(const std::string &name, long &value) const; +template bool CXmlElement::getAttribute(const std::string &name, unsigned long &value) const; +template bool CXmlElement::getAttribute(const std::string &name, long long &value) const; +template bool CXmlElement::getAttribute(const std::string &name, unsigned long long &value) const; +template bool CXmlElement::getAttribute(const std::string &name, float &value) const; +template bool CXmlElement::getAttribute(const std::string &name, double &value) const; + +template void CXmlElement::setAttribute(const std::string &name, const std::string &value); +template void CXmlElement::setAttribute(const std::string &name, const bool &value); +template void CXmlElement::setAttribute(const std::string &name, const short &value); +template void CXmlElement::setAttribute(const std::string &name, const unsigned short &value); +template void CXmlElement::setAttribute(const std::string &name, const int &value); +template void CXmlElement::setAttribute(const std::string &name, const unsigned int &value); +template void CXmlElement::setAttribute(const std::string &name, const long &value); +template void CXmlElement::setAttribute(const std::string &name, const unsigned long &value); +template void CXmlElement::setAttribute(const std::string &name, const long long &value); +template void CXmlElement::setAttribute(const std::string &name, const unsigned long long &value); +template void CXmlElement::setAttribute(const std::string &name, const float &value); +template void CXmlElement::setAttribute(const std::string &name, const double &value); diff --git a/xmlserializer/XmlElement.h b/xmlserializer/XmlElement.h index afa8438..f34863d 100644 --- a/xmlserializer/XmlElement.h +++ b/xmlserializer/XmlElement.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -38,63 +38,80 @@ struct _xmlDoc; class CXmlElement { friend class CChildIterator; + public: - CXmlElement(_xmlNode* pXmlElement); + CXmlElement(_xmlNode *pXmlElement); CXmlElement(); // Xml element - void setXmlElement(_xmlNode* pXmlElement); + void setXmlElement(_xmlNode *pXmlElement); // Getters std::string getType() const; std::string getPath() const; std::string getNameAttribute() const; - bool hasAttribute(const std::string& strAttributeName) const; - bool getAttributeBoolean(const std::string& strAttributeName, const std::string& strTrueValue) const; - bool getAttributeBoolean(const std::string& strAttributeName) const; - std::string getAttributeString(const std::string& strAttributeName) const; - uint32_t getAttributeInteger(const std::string& strAttributeName) const; - int32_t getAttributeSignedInteger(const std::string& strAttributeName) const; - double getAttributeDouble(const std::string& strAttributeName) const; + bool hasAttribute(const std::string &strAttributeName) const; + + /** Get attribute + * + * If the attribute does not exists or there is a libxml2 error while + * reading it or conversion from string to T fails, false is returned. In + * case of failure, the content of value is the same as before calling + * this method. + * + * Note: if T==string, no conversion takes place. + * + * @tparam T the type of the value to retrieve + * @param[in] name The attribute name + * @param[out] value The attribute value + * @return true if success, false otherwise + */ + template <typename T> + bool getAttribute(const std::string &name, T &value) const; + std::string getTextContent() const; // Navigation - bool getChildElement(const std::string& strType, CXmlElement& childElement) const; - bool getChildElement(const std::string& strType, const std::string& strNameAttribute, CXmlElement& childElement) const; + bool getChildElement(const std::string &strType, CXmlElement &childElement) const; + bool getChildElement(const std::string &strType, const std::string &strNameAttribute, + CXmlElement &childElement) const; size_t getNbChildElements() const; - bool getParentElement(CXmlElement& parentElement) const; - - // Setters - void setAttributeBoolean(const std::string& strAttributeName, bool bValue); - void setAttributeString(const std::string& strAttributeName, const std::string& strValue); - void setNameAttribute(const std::string& strValue); - void setTextContent(const std::string& strContent); - void setAttributeInteger(const std::string& strAttributeName, uint32_t uiValue); - /** - * Set attribute with signed integer - * - * @param[in] strAttributeName The attribute name - * @param[in] iValue The attribute value - * - */ - void setAttributeSignedInteger(const std::string& strAttributeName, int32_t iValue); + bool getParentElement(CXmlElement &parentElement) const; + + /** Set attribute + * + * @tparam T the type of the value to retrieve + * @param[in] name The attribute name + * @param[in] value The attribute value + */ + template <typename T> + void setAttribute(const std::string &name, const T &value); + /** Set attribute - special case for C-style strings + * + * @param[in] name The attribute name + * @param[in] value The attribute value + */ + void setAttribute(const std::string &name, const char *value); + + void setNameAttribute(const std::string &strValue); + void setTextContent(const std::string &strContent); // Child creation - void createChild(CXmlElement& childElement, const std::string& strType); + void createChild(CXmlElement &childElement, const std::string &strType); public: // Child iteration class CChildIterator { public: - CChildIterator(const CXmlElement& xmlElement); + CChildIterator(const CXmlElement &xmlElement); + + bool next(CXmlElement &xmlChildElement); - bool next(CXmlElement& xmlChildElement); private: - _xmlNode* _pCurNode; + _xmlNode *_pCurNode; }; private: - _xmlNode* _pXmlElement; + _xmlNode *_pXmlElement; }; - diff --git a/xmlserializer/XmlMemoryDocSink.cpp b/xmlserializer/XmlMemoryDocSink.cpp index b966455..500ee3c 100644 --- a/xmlserializer/XmlMemoryDocSink.cpp +++ b/xmlserializer/XmlMemoryDocSink.cpp @@ -32,13 +32,12 @@ #define base CXmlDocSink -CXmlMemoryDocSink::CXmlMemoryDocSink(IXmlSink* pXmlSink): - _pXmlSink(pXmlSink) +CXmlMemoryDocSink::CXmlMemoryDocSink(IXmlSink *pXmlSink) : _pXmlSink(pXmlSink) { } -bool CXmlMemoryDocSink::doProcess(CXmlDocSource& xmlDocSource, - CXmlSerializingContext& serializingContext) +bool CXmlMemoryDocSink::doProcess(CXmlDocSource &xmlDocSource, + CXmlSerializingContext &serializingContext) { CXmlElement docElement; diff --git a/xmlserializer/XmlMemoryDocSink.h b/xmlserializer/XmlMemoryDocSink.h index 665477a..b91c2aa 100644 --- a/xmlserializer/XmlMemoryDocSink.h +++ b/xmlserializer/XmlMemoryDocSink.h @@ -44,7 +44,7 @@ public: * @param[out] pXmlSink a pointer to a parameter-framework structure that can parse an xml * description to instanciate itself */ - CXmlMemoryDocSink(IXmlSink* pXmlSink); + CXmlMemoryDocSink(IXmlSink *pXmlSink); private: /** @@ -57,8 +57,8 @@ private: * * @return false if any error occurs */ - virtual bool doProcess(CXmlDocSource& xmlDocSource, CXmlSerializingContext& serializingContext); + virtual bool doProcess(CXmlDocSource &xmlDocSource, CXmlSerializingContext &serializingContext); // Xml Sink - IXmlSink* _pXmlSink; + IXmlSink *_pXmlSink; }; diff --git a/xmlserializer/XmlMemoryDocSource.cpp b/xmlserializer/XmlMemoryDocSource.cpp index 2929b79..41b5ef2 100644 --- a/xmlserializer/XmlMemoryDocSource.cpp +++ b/xmlserializer/XmlMemoryDocSource.cpp @@ -34,17 +34,13 @@ #define base CXmlDocSource -CXmlMemoryDocSource::CXmlMemoryDocSource(const IXmlSource* pXmlSource, bool bValidateWithSchema, - const std::string& strRootElementType, - const std::string& strXmlSchemaFile, - const std::string& strProduct, - const std::string& strVersion): - base(xmlNewDoc(BAD_CAST "1.0"), bValidateWithSchema, - xmlNewNode(NULL, BAD_CAST strRootElementType.c_str())), - _pXmlSource(pXmlSource), - _strXmlSchemaFile(strXmlSchemaFile), - _strProduct(strProduct), - _strVersion(strVersion) +CXmlMemoryDocSource::CXmlMemoryDocSource(const IXmlSource *pXmlSource, bool bValidateWithSchema, + const std::string &strRootElementType, + const std::string &strProduct, + const std::string &strVersion) + : base(xmlNewDoc(BAD_CAST "1.0"), bValidateWithSchema, + xmlNewNode(NULL, BAD_CAST strRootElementType.c_str())), + _pXmlSource(pXmlSource), _strProduct(strProduct), _strVersion(strVersion) { init(); } @@ -58,7 +54,7 @@ void CXmlMemoryDocSource::init() #endif } -bool CXmlMemoryDocSource::populate(CXmlSerializingContext& serializingContext) +bool CXmlMemoryDocSource::populate(CXmlSerializingContext &serializingContext) { #ifndef LIBXML_TREE_ENABLED serializingContext.setError("XML file exporting feature unsupported on this image. " + @@ -69,16 +65,7 @@ bool CXmlMemoryDocSource::populate(CXmlSerializingContext& serializingContext) #endif // Create Xml element with the Doc - CXmlElement docElement(_pRootNode); - - if (!_strXmlSchemaFile.empty()) { - - // Schema namespace - docElement.setAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - - // Schema location - docElement.setAttributeString("xsi:noNamespaceSchemaLocation", _strXmlSchemaFile); - } + CXmlElement docElement(_pRootNode); // Compose the xml document _pXmlSource->toXml(docElement, serializingContext); diff --git a/xmlserializer/XmlMemoryDocSource.h b/xmlserializer/XmlMemoryDocSource.h index bc5fdb5..c8a0d55 100644 --- a/xmlserializer/XmlMemoryDocSource.h +++ b/xmlserializer/XmlMemoryDocSource.h @@ -45,16 +45,13 @@ public: * @param[in] pXmlSource a pointer to a parameter-framework structure that can generate * an xml description of itself * @param[in] strRootElementType a string containing the root element type - * @param[in] strXmlSchemaFile a string containing the path to the schema file * @param[in] strProduct a string containing the product name * @param[in] strVersion a string containing the version number * @param[in] bValidateWithSchema a boolean that toggles schema validation */ - CXmlMemoryDocSource(const IXmlSource* pXmlSource, bool bValidateWithSchema, - const std::string& strRootElementType, - const std::string& strXmlSchemaFile = "", - const std::string& strProduct = "", - const std::string& strVersion = ""); + CXmlMemoryDocSource(const IXmlSource *pXmlSource, bool bValidateWithSchema, + const std::string &strRootElementType, const std::string &strProduct = "", + const std::string &strVersion = ""); /** * Implementation of CXmlDocSource::populate() method. @@ -64,9 +61,9 @@ public: * * @return false if any error occurs */ - virtual bool populate(CXmlSerializingContext& serializingContext); -private: + virtual bool populate(CXmlSerializingContext &serializingContext); +private: /** * Initialize root element */ @@ -75,7 +72,7 @@ private: /** * Xml Source */ - const IXmlSource* _pXmlSource; + const IXmlSource *_pXmlSource; /** * Schema file diff --git a/xmlserializer/XmlSerializingContext.cpp b/xmlserializer/XmlSerializingContext.cpp index 9adef31..4666c54 100644 --- a/xmlserializer/XmlSerializingContext.cpp +++ b/xmlserializer/XmlSerializingContext.cpp @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2014, Intel Corporation +/* + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -28,23 +28,39 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "XmlSerializingContext.h" +#include <libxml/xmlerror.h> +#include <cstdio> -CXmlSerializingContext::CXmlSerializingContext(std::string& strError) : _strError(strError) +CXmlSerializingContext::CXmlSerializingContext(std::string &strError) + : utility::ErrorContext(strError) { + xmlSetStructuredErrorFunc(this, structuredErrorHandler); } -// Error -void CXmlSerializingContext::setError(const std::string& strError) +CXmlSerializingContext::~CXmlSerializingContext() { - _strError = strError; + // TODO: restore the previous handler + xmlSetStructuredErrorFunc(NULL, NULL); + prependToError(_strXmlError); } -void CXmlSerializingContext::appendLineToError(const std::string& strAppend) +void CXmlSerializingContext::appendLineToError(const std::string &strAppend) { - _strError += "\n" + strAppend; + appendToError("\n" + strAppend); } -const std::string& CXmlSerializingContext::getError() const +/** XML error handler + * + * @param[in] userData pointer to the serializing context + * @param[in] error the xml error + * + */ +void CXmlSerializingContext::structuredErrorHandler(void *userData, xmlErrorPtr error) { - return _strError; + CXmlSerializingContext *self = static_cast<CXmlSerializingContext *>(userData); + + std::string filename = (error->file != NULL) ? error->file : "(user input)"; + // xmlErrorPtr->int2 contains the column; see xmlerror.h + self->_strXmlError += filename + ":" + std::to_string(error->line) + ":" + + std::to_string(error->int2) + ": " + error->message; } diff --git a/xmlserializer/XmlSerializingContext.h b/xmlserializer/XmlSerializingContext.h index b72e5d1..fefa9d0 100644 --- a/xmlserializer/XmlSerializingContext.h +++ b/xmlserializer/XmlSerializingContext.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2011-2014, Intel Corporation +/* + * Copyright (c) 2011-2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -29,18 +29,40 @@ */ #pragma once +#include "ErrorContext.hpp" + #include <string> -class CXmlSerializingContext +/** Forward declare libxml2 handler structure. */ +struct _xmlError; + +/** Class that gather errors during serialization. + * + * Provided with an initial empty buffer (strError), an instance of this class + * can describe an error. + * + * This error will be accessible formated in the aforementioned buffer + * _after_ destruction. + * Ie. the provided buffer (strError) is in an undefined state between + * construction and destruction and should not be accessed in between. + */ +class CXmlSerializingContext : public utility::ErrorContext { public: - CXmlSerializingContext(std::string& strError); + CXmlSerializingContext(std::string &strError); + ~CXmlSerializingContext(); // Error - void setError(const std::string& strError); - void appendLineToError(const std::string& strAppend); - const std::string& getError() const; + void appendLineToError(const std::string &strAppend); + + /** XML error handler + * + * @param[in] userData pointer to the serializing context + * @param[in] error the xml error output format + * + */ + static void structuredErrorHandler(void *userData, _xmlError *error); private: - std::string& _strError; + std::string _strXmlError; }; diff --git a/xmlserializer/XmlSink.h b/xmlserializer/XmlSink.h index 4e7ae64..20b20aa 100644 --- a/xmlserializer/XmlSink.h +++ b/xmlserializer/XmlSink.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -35,7 +35,8 @@ class IXmlSink { public: - virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) = 0; + virtual bool fromXml(const CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) = 0; protected: virtual ~IXmlSink() {} diff --git a/xmlserializer/XmlSource.h b/xmlserializer/XmlSource.h index a56ee15..4bafd32 100644 --- a/xmlserializer/XmlSource.h +++ b/xmlserializer/XmlSource.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * @@ -35,7 +35,8 @@ class IXmlSource { public: - virtual void toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const = 0; + virtual void toXml(CXmlElement &xmlElement, + CXmlSerializingContext &serializingContext) const = 0; protected: virtual ~IXmlSource() {} diff --git a/xmlserializer/XmlStreamDocSink.cpp b/xmlserializer/XmlStreamDocSink.cpp index f1a2524..4acd089 100644 --- a/xmlserializer/XmlStreamDocSink.cpp +++ b/xmlserializer/XmlStreamDocSink.cpp @@ -32,15 +32,14 @@ #define base CXmlDocSink -CXmlStreamDocSink::CXmlStreamDocSink(std::ostream& output): - _output(output) +CXmlStreamDocSink::CXmlStreamDocSink(std::ostream &output) : _output(output) { } -bool CXmlStreamDocSink::doProcess(CXmlDocSource& xmlDocSource, - CXmlSerializingContext& serializingContext) +bool CXmlStreamDocSink::doProcess(CXmlDocSource &xmlDocSource, + CXmlSerializingContext &serializingContext) { - xmlChar* dumpedDoc = NULL; + xmlChar *dumpedDoc = NULL; int iSize; xmlDocDumpFormatMemoryEnc(xmlDocSource.getDoc(), &dumpedDoc, &iSize, "UTF-8", 1); @@ -52,7 +51,7 @@ bool CXmlStreamDocSink::doProcess(CXmlDocSource& xmlDocSource, return false; } - _output << static_cast<unsigned char*>(dumpedDoc); + _output << static_cast<unsigned char *>(dumpedDoc); xmlFree(dumpedDoc); diff --git a/xmlserializer/XmlStreamDocSink.h b/xmlserializer/XmlStreamDocSink.h index 08b81cb..368505d 100644 --- a/xmlserializer/XmlStreamDocSink.h +++ b/xmlserializer/XmlStreamDocSink.h @@ -44,7 +44,7 @@ public: * * @param[out] output a reference to a ostream that will be filled by the doProcess method */ - CXmlStreamDocSink(std::ostream& output); + CXmlStreamDocSink(std::ostream &output); private: /** Implementation of CXmlDocSink::doProcess() @@ -55,11 +55,10 @@ private: * * @return false if any error occurs */ - virtual bool doProcess(CXmlDocSource& xmlDocSource, CXmlSerializingContext& serializingContext); + virtual bool doProcess(CXmlDocSource &xmlDocSource, CXmlSerializingContext &serializingContext); /** * Result ostream containing the XML informations */ - std::ostream& _output; + std::ostream &_output; }; - diff --git a/parameter/AutoLog.h b/xmlserializer/XmlUtil.cpp index 0454514..86513fa 100644 --- a/parameter/AutoLog.h +++ b/xmlserializer/XmlUtil.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, Intel Corporation + * Copyright (c) 2015, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -27,26 +27,23 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma once -#include "Element.h" +#include <libxml/parser.h> +#include <cstdlib> -#include <string> - -class CAutoLog +/* Provides miscellaneous utility functions */ +class CXmlUtil { public: - CAutoLog(const CElement* pElement, const std::string& strContext, bool bLogOn = true); - ~CAutoLog(); - -private: - CAutoLog(const CAutoLog&); - CAutoLog& operator=(const CAutoLog&); - // Logger element - const CElement* _pElement; - // Context - std::string _strContext; - // Log on - bool _bLogOn; + /* xmlInitParser must be called in the main thread if multithreading is required + * @see http://xmlsoft.org/threads.html + * @see http://www.programmershare.com/1669782/ + */ + CXmlUtil() + { + xmlInitParser(); + atexit(xmlCleanupParser); + } }; +static CXmlUtil xml_init; |
