Mercurial > hg > orthanc
changeset 2410:3590c936e56f
parsing numbers in DicomValue
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 29 Sep 2017 10:13:52 +0200 |
parents | e4045b3c9772 |
children | 82d5e305fbd9 |
files | Core/DicomFormat/DicomValue.cpp Core/DicomFormat/DicomValue.h UnitTestsSources/DicomMapTests.cpp |
diffstat | 3 files changed, 217 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/DicomFormat/DicomValue.cpp Wed Sep 27 17:36:13 2017 +0200 +++ b/Core/DicomFormat/DicomValue.cpp Fri Sep 29 10:13:52 2017 +0200 @@ -37,6 +37,8 @@ #include "../OrthancException.h" #include "../Toolbox.h" +#include <boost/lexical_cast.hpp> + namespace Orthanc { DicomValue::DicomValue(const DicomValue& other) : @@ -91,4 +93,86 @@ } #endif + + template <typename T, + bool allowSigned> + static bool ParseValue(T& result, + const DicomValue& source) + { + if (source.IsBinary() || + source.IsNull()) + { + return false; + } + + try + { + std::string value = Toolbox::StripSpaces(source.GetContent()); + if (value.empty()) + { + return false; + } + + if (!allowSigned && + value[0] == '-') + { + return false; + } + + result = boost::lexical_cast<T>(value); + return true; + } + catch (boost::bad_lexical_cast&) + { + return false; + } + } + + bool DicomValue::ParseInteger32(int32_t& result) const + { + int64_t tmp; + if (ParseValue<int64_t, true>(tmp, *this)) + { + result = static_cast<int32_t>(tmp); + return (tmp == static_cast<int64_t>(result)); // Check no overflow occurs + } + else + { + return false; + } + } + + bool DicomValue::ParseInteger64(int64_t& result) const + { + return ParseValue<int64_t, true>(result, *this); + } + + bool DicomValue::ParseUnsignedInteger32(uint32_t& result) const + { + uint64_t tmp; + if (ParseValue<uint64_t, false>(tmp, *this)) + { + result = static_cast<uint32_t>(tmp); + return (tmp == static_cast<uint64_t>(result)); // Check no overflow occurs + } + else + { + return false; + } + } + + bool DicomValue::ParseUnsignedInteger64(uint64_t& result) const + { + return ParseValue<uint64_t, false>(result, *this); + } + + bool DicomValue::ParseFloat(float& result) const + { + return ParseValue<float, true>(result, *this); + } + + bool DicomValue::ParseDouble(double& result) const + { + return ParseValue<double, true>(result, *this); + } }
--- a/Core/DicomFormat/DicomValue.h Wed Sep 27 17:36:13 2017 +0200 +++ b/Core/DicomFormat/DicomValue.h Fri Sep 29 10:13:52 2017 +0200 @@ -93,5 +93,17 @@ FormatDataUriScheme(target, "application/octet-stream"); } #endif + + bool ParseInteger32(int32_t& result) const; + + bool ParseInteger64(int64_t& result) const; + + bool ParseUnsignedInteger32(uint32_t& result) const; + + bool ParseUnsignedInteger64(uint64_t& result) const; + + bool ParseFloat(float& result) const; + + bool ParseDouble(double& result) const; }; }
--- a/UnitTestsSources/DicomMapTests.cpp Wed Sep 27 17:36:13 2017 +0200 +++ b/UnitTestsSources/DicomMapTests.cpp Fri Sep 29 10:13:52 2017 +0200 @@ -220,3 +220,124 @@ TestModule(ResourceType_Series, DicomModule_Series); // TODO TestModule(ResourceType_Instance, DicomModule_Instance); } + + +TEST(DicomMap, Parse) +{ + DicomMap m; + float f; + double d; + int32_t i; + int64_t j; + uint32_t k; + uint64_t l; + + m.SetValue(DICOM_TAG_PATIENT_NAME, " ", false); // Empty value + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + + m.SetValue(DICOM_TAG_PATIENT_NAME, "0", true); // Binary value + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + + // 2**31-1 + m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483647", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(2147483647.0f, f); + ASSERT_DOUBLE_EQ(2147483647.0, d); + ASSERT_EQ(2147483647, i); + ASSERT_EQ(2147483647, j); + ASSERT_EQ(2147483647u, k); + ASSERT_EQ(2147483647u, l); + + // 2**31 + m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483648", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(2147483648.0f, f); + ASSERT_DOUBLE_EQ(2147483648.0, d); + ASSERT_EQ(2147483648, j); + ASSERT_EQ(2147483648u, k); + ASSERT_EQ(2147483648u, l); + + // 2**32-1 + m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967295", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(4294967295.0f, f); + ASSERT_DOUBLE_EQ(4294967295.0, d); + ASSERT_EQ(4294967295, j); + ASSERT_EQ(4294967295u, k); + ASSERT_EQ(4294967295u, l); + + // 2**32 + m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967296", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(4294967296.0f, f); + ASSERT_DOUBLE_EQ(4294967296.0, d); + ASSERT_EQ(4294967296, j); + ASSERT_EQ(4294967296u, l); + + m.SetValue(DICOM_TAG_PATIENT_NAME, "-1", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(-1.0f, f); + ASSERT_DOUBLE_EQ(-1.0, d); + ASSERT_EQ(-1, i); + ASSERT_EQ(-1, j); + + // -2**31 + m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483648", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(-2147483648.0f, f); + ASSERT_DOUBLE_EQ(-2147483648.0, d); + ASSERT_EQ(-2147483648, i); + ASSERT_EQ(-2147483648, j); + + // -2**31 - 1 + m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483649", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i)); + ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); + ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); + ASSERT_FLOAT_EQ(-2147483649.0f, f); + ASSERT_DOUBLE_EQ(-2147483649.0, d); + ASSERT_EQ(-2147483649, j); +}