Mercurial > hg > orthanc
diff OrthancFramework/Sources/SerializationToolbox.cpp @ 4775:add0337b928a
refactoring parsing of numbers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 30 Aug 2021 10:24:36 +0200 |
parents | f4dbdb2dcba6 |
children | 7053502fbf97 |
line wrap: on
line diff
--- a/OrthancFramework/Sources/SerializationToolbox.cpp Wed Aug 25 17:20:21 2021 +0200 +++ b/OrthancFramework/Sources/SerializationToolbox.cpp Mon Aug 30 10:24:36 2021 +0200 @@ -24,11 +24,15 @@ #include "SerializationToolbox.h" #include "OrthancException.h" +#include "Toolbox.h" #if ORTHANC_ENABLE_DCMTK == 1 # include "DicomParsing/FromDcmtkBridge.h" #endif +#include <boost/lexical_cast.hpp> + + namespace Orthanc { static bool ParseTagInternal(DicomTag& tag, @@ -445,4 +449,202 @@ value[it->first.Format()] = it->second; } } + + + template <typename T, + bool allowSigned> + static bool ParseValue(T& target, + const std::string& source) + { + try + { + std::string value = Toolbox::StripSpaces(source); + if (value.empty()) + { + return false; + } + else if (!allowSigned && + value[0] == '-') + { + return false; + } + else + { + target = boost::lexical_cast<T>(value); + return true; + } + } + catch (boost::bad_lexical_cast&) + { + return false; + } + } + + + bool SerializationToolbox::ParseInteger32(int32_t& target, + const std::string& source) + { + int64_t tmp; + if (ParseValue<int64_t, true>(tmp, source)) + { + target = static_cast<int32_t>(tmp); + return (tmp == static_cast<int64_t>(target)); // Check no overflow occurs + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseInteger64(int64_t& target, + const std::string& source) + { + return ParseValue<int64_t, true>(target, source); + } + + + bool SerializationToolbox::ParseUnsignedInteger32(uint32_t& target, + const std::string& source) + { + uint64_t tmp; + if (ParseValue<uint64_t, false>(tmp, source)) + { + target = static_cast<uint32_t>(tmp); + return (tmp == static_cast<uint64_t>(target)); // Check no overflow occurs + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseUnsignedInteger64(uint64_t& target, + const std::string& source) + { + return ParseValue<uint64_t, false>(target, source); + } + + + bool SerializationToolbox::ParseFloat(float& target, + const std::string& source) + { + return ParseValue<float, true>(target, source); + } + + + bool SerializationToolbox::ParseDouble(double& target, + const std::string& source) + { + return ParseValue<double, true>(target, source); + } + + + static bool GetFirstItem(std::string& target, + const std::string& source) + { + std::vector<std::string> tokens; + Toolbox::TokenizeString(tokens, source, '\\'); + + if (tokens.empty()) + { + return false; + } + else + { + target = tokens[0]; + return true; + } + } + + + bool SerializationToolbox::ParseFirstInteger32(int32_t& target, + const std::string& source) + { + std::string first; + if (GetFirstItem(first, source)) + { + return ParseInteger32(target, first); + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseFirstInteger64(int64_t& target, + const std::string& source) + { + std::string first; + if (GetFirstItem(first, source)) + { + return ParseInteger64(target, first); + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseFirstUnsignedInteger32(uint32_t& target, + const std::string& source) + { + std::string first; + if (GetFirstItem(first, source)) + { + return ParseUnsignedInteger32(target, first); + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseFirstUnsignedInteger64(uint64_t& target, + const std::string& source) + { + std::string first; + if (GetFirstItem(first, source)) + { + return ParseUnsignedInteger64(target, first); + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseFirstFloat(float& target, + const std::string& source) + { + std::string first; + if (GetFirstItem(first, source)) + { + return ParseFloat(target, first); + } + else + { + return false; + } + } + + + bool SerializationToolbox::ParseFirstDouble(double& target, + const std::string& source) + { + std::string first; + if (GetFirstItem(first, source)) + { + return ParseDouble(target, first); + } + else + { + return false; + } + } }