diff options
author | David Wagner <david.wagner@intel.com> | 2014-02-17 16:38:29 +0100 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2014-02-17 16:43:03 +0100 |
commit | 4ff62d67aaf128546af2b4a4ec728a1c731998d0 (patch) | |
tree | 7f4e72bc0f39cddb180ee7acc65a7e652036e1c1 /utility | |
parent | 34e90ae1c744e1de6547e014326ef54f516439c8 (diff) | |
download | external_parameter-framework-4ff62d67aaf128546af2b4a4ec728a1c731998d0.zip external_parameter-framework-4ff62d67aaf128546af2b4a4ec728a1c731998d0.tar.gz external_parameter-framework-4ff62d67aaf128546af2b4a4ec728a1c731998d0.tar.bz2 |
Import convert util templates
Import an external dependency: a template-based conversion toolkit.
Signed-off-by: David Wagner <david.wagner@intel.com>
Diffstat (limited to 'utility')
-rwxr-xr-x | utility/convert.hpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/utility/convert.hpp b/utility/convert.hpp new file mode 100755 index 0000000..273abd5 --- /dev/null +++ b/utility/convert.hpp @@ -0,0 +1,176 @@ +/* + * 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. + */ + +#pragma once + +#include <limits> +#include <sstream> +#include <string> +#include <stdint.h> + +/* 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> {}; + +} // namespace details + +/** + * Convert a string to a given type. + * + * This template function read the value of the type T in the given string. + * The function does not allow to have white spaces around the value to parse + * and tries to parse the whole string, which means that if some bytes were not + * read in the string, the function fails. + * Hexadecimal representation (ie numbers starting with 0x) is supported only + * for integral types conversions. + * Result may be modified, even in case of failure. + * + * @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<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. */ + details::ConvertionAllowed<T>(); + + if (str.find_first_of(std::string("\r\n\t\v ")) != std::string::npos) { + return false; + } + + /* 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) { + return false; + } + + std::stringstream ss(str); + + /* Sadly, the stream conversion does not handle hexadecimal format, thus + * check is done manually */ + if (str.substr(0, 2) == "0x") { + if (std::numeric_limits<T>::is_integer) { + ss >> std::hex >> result; + } + else { + /* Conversion undefined for non integers */ + return false; + } + } else { + ss >> result; + } + + return ss.eof() && !ss.fail() && !ss.bad(); +} + +/** + * Specialization for int16_t 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. + * + * @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) +{ + 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; +} + +/** + * Specialization for boolean of convertTo template function. + * + * This function follows the same paradigm than it's generic version. + * This function accepts to parse boolean as "0/1" or "false/true" or + * "FALSE/TRUE". + * The specific implementation is made necessary because the behaviour of + * string streams when parsing boolean values is not sufficient to fit our + * requirements. Indeed, parsing "true" will correctly parse the value, but the + * end of stream is not reached which makes the ss.eof() fails in the generic + * implementation. + * + * @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<bool>(const std::string &str, bool &result) +{ + if (str == "0" || str == "FALSE" || str == "false") { + result = false; + return true; + } + + if (str == "1" || str == "TRUE" || str == "true") { + result = true; + return true; + } + + return false; +} |