# HG changeset patch # User Sebastien Jodogne # Date 1538754545 -7200 # Node ID da12ba2321190b25127dadce615414140234e5ff # Parent 8b00e4cb4a6be6d0ef1234b40c9c8c2c58dd0524 serialization of DicomMap diff -r 8b00e4cb4a6b -r da12ba232119 Core/DicomFormat/DicomMap.cpp --- a/Core/DicomFormat/DicomMap.cpp Fri Oct 05 16:07:34 2018 +0200 +++ b/Core/DicomFormat/DicomMap.cpp Fri Oct 05 17:49:05 2018 +0200 @@ -179,12 +179,11 @@ } - - void DicomMap::Clear() { for (Map::iterator it = map_.begin(); it != map_.end(); ++it) { + assert(it->second != NULL); delete it->second; } @@ -981,4 +980,51 @@ return value->ParseDouble(result); } } + + + void DicomMap::Serialize(Json::Value& target) const + { + target = Json::objectValue; + + for (Map::const_iterator it = map_.begin(); it != map_.end(); ++it) + { + assert(it->second != NULL); + + std::string tag = it->first.Format(); + + Json::Value value; + it->second->Serialize(value); + + target[tag] = value; + } + } + + + void DicomMap::Unserialize(const Json::Value& source) + { + Clear(); + + if (source.type() != Json::objectValue) + { + throw OrthancException(ErrorCode_BadFileFormat); + } + + Json::Value::Members tags = source.getMemberNames(); + + for (size_t i = 0; i < tags.size(); i++) + { + DicomTag tag(0, 0); + + if (!DicomTag::ParseHexadecimal(tag, tags[i].c_str()) || + map_.find(tag) != map_.end()) + { + throw OrthancException(ErrorCode_BadFileFormat); + } + + std::auto_ptr value(new DicomValue); + value->Unserialize(source[tags[i]]); + + map_[tag] = value.release(); + } + } } diff -r 8b00e4cb4a6b -r da12ba232119 Core/DicomFormat/DicomMap.h --- a/Core/DicomFormat/DicomMap.h Fri Oct 05 16:07:34 2018 +0200 +++ b/Core/DicomFormat/DicomMap.h Fri Oct 05 17:49:05 2018 +0200 @@ -89,6 +89,17 @@ void Clear(); + void SetNullValue(uint16_t group, + uint16_t element) + { + SetValue(group, element, new DicomValue); + } + + void SetNullValue(const DicomTag& tag) + { + SetValue(tag, new DicomValue); + } + void SetValue(uint16_t group, uint16_t element, const DicomValue& value) @@ -198,12 +209,16 @@ const DicomTag& tag) const; bool ParseUnsignedInteger64(uint64_t& result, - const DicomTag& tag) const; + const DicomTag& tag) const; bool ParseFloat(float& result, - const DicomTag& tag) const; + const DicomTag& tag) const; bool ParseDouble(double& result, - const DicomTag& tag) const; + const DicomTag& tag) const; + + void Serialize(Json::Value& target) const; + + void Unserialize(const Json::Value& source); }; } diff -r 8b00e4cb4a6b -r da12ba232119 Core/DicomFormat/DicomValue.cpp --- a/Core/DicomFormat/DicomValue.cpp Fri Oct 05 16:07:34 2018 +0200 +++ b/Core/DicomFormat/DicomValue.cpp Fri Oct 05 17:49:05 2018 +0200 @@ -35,6 +35,7 @@ #include "DicomValue.h" #include "../OrthancException.h" +#include "../SerializationToolbox.h" #include "../Toolbox.h" #include @@ -193,4 +194,65 @@ return true; } } + + + static const char* KEY_TYPE = "Type"; + static const char* KEY_CONTENT = "Content"; + + void DicomValue::Serialize(Json::Value& target) const + { + target = Json::objectValue; + + switch (type_) + { + case Type_Null: + target[KEY_TYPE] = "Null"; + break; + + case Type_String: + target[KEY_TYPE] = "String"; + target[KEY_CONTENT] = content_; + break; + + case Type_Binary: + { + target[KEY_TYPE] = "Binary"; + + std::string base64; + Toolbox::EncodeBase64(base64, content_); + target[KEY_CONTENT] = base64; + break; + } + + default: + throw OrthancException(ErrorCode_InternalError); + } + } + + void DicomValue::Unserialize(const Json::Value& source) + { + std::string type = SerializationToolbox::ReadString(source, KEY_TYPE); + + if (type == "Null") + { + type_ = Type_Null; + content_.clear(); + } + else if (type == "String") + { + type_ = Type_String; + content_ = SerializationToolbox::ReadString(source, KEY_CONTENT); + } + else if (type == "Binary") + { + type_ = Type_Binary; + + const std::string base64 =SerializationToolbox::ReadString(source, KEY_CONTENT); + Toolbox::DecodeBase64(content_, base64); + } + else + { + throw OrthancException(ErrorCode_BadFileFormat); + } + } } diff -r 8b00e4cb4a6b -r da12ba232119 Core/DicomFormat/DicomValue.h --- a/Core/DicomFormat/DicomValue.h Fri Oct 05 16:07:34 2018 +0200 +++ b/Core/DicomFormat/DicomValue.h Fri Oct 05 17:49:05 2018 +0200 @@ -36,6 +36,7 @@ #include #include #include +#include #if !defined(ORTHANC_ENABLE_BASE64) # error The macro ORTHANC_ENABLE_BASE64 must be defined @@ -108,6 +109,10 @@ bool ParseFloat(float& result) const; - bool ParseDouble(double& result) const; + bool ParseDouble(double& result) const; + + void Serialize(Json::Value& target) const; + + void Unserialize(const Json::Value& source); }; } diff -r 8b00e4cb4a6b -r da12ba232119 UnitTestsSources/DicomMapTests.cpp --- a/UnitTestsSources/DicomMapTests.cpp Fri Oct 05 16:07:34 2018 +0200 +++ b/UnitTestsSources/DicomMapTests.cpp Fri Oct 05 17:49:05 2018 +0200 @@ -369,3 +369,43 @@ ASSERT_DOUBLE_EQ(-2147483649.0, d); ASSERT_EQ(-2147483649ll, j); } + + +TEST(DicomMap, Serialize) +{ + Json::Value s; + + { + DicomMap m; + m.SetValue(DICOM_TAG_PATIENT_NAME, "Hello", false); + m.SetValue(DICOM_TAG_STUDY_DESCRIPTION, "Binary", true); + m.SetNullValue(DICOM_TAG_SERIES_DESCRIPTION); + m.Serialize(s); + } + + { + DicomMap m; + m.Unserialize(s); + + const DicomValue* v = m.TestAndGetValue(DICOM_TAG_ACCESSION_NUMBER); + ASSERT_TRUE(v == NULL); + + v = m.TestAndGetValue(DICOM_TAG_PATIENT_NAME); + ASSERT_TRUE(v != NULL); + ASSERT_FALSE(v->IsNull()); + ASSERT_FALSE(v->IsBinary()); + ASSERT_EQ("Hello", v->GetContent()); + + v = m.TestAndGetValue(DICOM_TAG_STUDY_DESCRIPTION); + ASSERT_TRUE(v != NULL); + ASSERT_FALSE(v->IsNull()); + ASSERT_TRUE(v->IsBinary()); + ASSERT_EQ("Binary", v->GetContent()); + + v = m.TestAndGetValue(DICOM_TAG_SERIES_DESCRIPTION); + ASSERT_TRUE(v != NULL); + ASSERT_TRUE(v->IsNull()); + ASSERT_FALSE(v->IsBinary()); + ASSERT_THROW(v->GetContent(), OrthancException); + } +}