changeset 2863:da12ba232119

serialization of DicomMap
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 05 Oct 2018 17:49:05 +0200
parents 8b00e4cb4a6b
children 7cac2bc1986e
files Core/DicomFormat/DicomMap.cpp Core/DicomFormat/DicomMap.h Core/DicomFormat/DicomValue.cpp Core/DicomFormat/DicomValue.h UnitTestsSources/DicomMapTests.cpp
diffstat 5 files changed, 174 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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<DicomValue> value(new DicomValue);
+      value->Unserialize(source[tags[i]]);
+
+      map_[tag] = value.release();
+    }
+  }
 }
--- 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);
   };
 }
--- 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 <boost/lexical_cast.hpp>
@@ -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);
+    }
+  }
 }
--- 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 <stdint.h>
 #include <string>
 #include <boost/noncopyable.hpp>
+#include <json/value.h>
 
 #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);
   };
 }
--- 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);
+  }
+}