# HG changeset patch # User Sebastien Jodogne # Date 1506672832 -7200 # Node ID 3590c936e56f204b7fcac3d15cdaaa196d0e0310 # Parent e4045b3c9772c155f97307519d2d57585449fbf8 parsing numbers in DicomValue diff -r e4045b3c9772 -r 3590c936e56f Core/DicomFormat/DicomValue.cpp --- 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 + namespace Orthanc { DicomValue::DicomValue(const DicomValue& other) : @@ -91,4 +93,86 @@ } #endif + + template + 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(value); + return true; + } + catch (boost::bad_lexical_cast&) + { + return false; + } + } + + bool DicomValue::ParseInteger32(int32_t& result) const + { + int64_t tmp; + if (ParseValue(tmp, *this)) + { + result = static_cast(tmp); + return (tmp == static_cast(result)); // Check no overflow occurs + } + else + { + return false; + } + } + + bool DicomValue::ParseInteger64(int64_t& result) const + { + return ParseValue(result, *this); + } + + bool DicomValue::ParseUnsignedInteger32(uint32_t& result) const + { + uint64_t tmp; + if (ParseValue(tmp, *this)) + { + result = static_cast(tmp); + return (tmp == static_cast(result)); // Check no overflow occurs + } + else + { + return false; + } + } + + bool DicomValue::ParseUnsignedInteger64(uint64_t& result) const + { + return ParseValue(result, *this); + } + + bool DicomValue::ParseFloat(float& result) const + { + return ParseValue(result, *this); + } + + bool DicomValue::ParseDouble(double& result) const + { + return ParseValue(result, *this); + } } diff -r e4045b3c9772 -r 3590c936e56f Core/DicomFormat/DicomValue.h --- 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; }; } diff -r e4045b3c9772 -r 3590c936e56f UnitTestsSources/DicomMapTests.cpp --- 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); +}