[ismrmrd] 260/281: Added ISMRMRD meta data structures to xml library

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Jan 14 20:01:22 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to annotated tag ismrmrd0.5
in repository ismrmrd.

commit aabea9a7aba8c18c46db995a8e3e28b1e97aed05
Author: Michael S. Hansen <michael.hansen at nih.gov>
Date:   Fri Aug 15 13:49:32 2014 -0400

    Added ISMRMRD meta data structures to xml library
---
 xml/CMakeLists.txt   |   9 ++
 xml/ismrmrd_meta.cpp |  54 +++++++++++
 xml/ismrmrd_meta.h   | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++
 xml/ismrmrd_xml.h    |  39 ++------
 xml/test_meta.cpp    |  33 +++++++
 5 files changed, 349 insertions(+), 33 deletions(-)

diff --git a/xml/CMakeLists.txt b/xml/CMakeLists.txt
index c7555df..40c9c0c 100644
--- a/xml/CMakeLists.txt
+++ b/xml/CMakeLists.txt
@@ -1,6 +1,8 @@
 add_library(ismrmrd_xml SHARED 
   ismrmrd_xml.h
   ismrmrd_xml.cpp
+  ismrmrd_meta.h
+  ismrmrd_meta.cpp
   pugixml.cpp
   )
 
@@ -9,9 +11,16 @@ add_executable(test_ismrmrd_xml
   pugixml.cpp
 )
 
+add_executable(test_meta 
+  test_meta.cpp
+)
+
 target_link_libraries(test_ismrmrd_xml
   ismrmrd_xml)
 
+target_link_libraries(test_meta
+  ismrmrd_xml)
+
 install (FILES ismrmrd_xml.h ismrmrd_xml_export.h
   DESTINATION ${ISMRMRD_INSTALL_INCLUDE_DIR})
 
diff --git a/xml/ismrmrd_meta.cpp b/xml/ismrmrd_meta.cpp
new file mode 100644
index 0000000..37b080c
--- /dev/null
+++ b/xml/ismrmrd_meta.cpp
@@ -0,0 +1,54 @@
+#include "ismrmrd_meta.h"
+#include "pugixml.hpp"
+
+
+namespace ISMRMRD
+{
+  void deserialize(const char* xml, MetaContainer& h)
+  {
+    pugi::xml_document doc;
+    pugi::xml_parse_result result = doc.load(xml);
+    pugi::xml_node root = doc.child("ismrmrdMeta");
+
+    if (!root) {
+      throw std::runtime_error("ismrmrdMeta tag not found in meta data header");
+    }
+    
+    pugi::xml_node meta = root.child("meta");
+    while (meta) {
+      pugi::xml_node name = meta.child("name");
+      pugi::xml_node value = meta.child("value");
+
+      if (!name || !value) {
+	std::runtime_error("Malformed metadata value");
+      }
+
+      while (value) {
+	h.append(name.child_value(),value.child_value());
+	value = value.next_sibling("value");
+      }
+
+      meta = meta.next_sibling("meta");
+    }
+  }
+
+  void serialize(MetaContainer& h, std::ostream& o)
+  {
+    pugi::xml_document doc;
+    pugi::xml_node root = doc.append_child("ismrmrdMeta");
+    
+    MetaContainer::map_t::iterator it = h.map_.begin();
+    while (it != h.map_.end()) {
+      pugi::xml_node meta = root.append_child("meta");
+      pugi::xml_node name = meta.append_child("name");
+      name.append_child(pugi::node_pcdata).set_value(it->first.c_str());
+      for (unsigned int i = 0; i < it->second.size(); i++) {
+	pugi::xml_node name = meta.append_child("value");
+	name.append_child(pugi::node_pcdata).set_value(it->second[i].as_str());
+      }
+      it++;
+    }
+    doc.save(o);
+  }
+
+}
diff --git a/xml/ismrmrd_meta.h b/xml/ismrmrd_meta.h
new file mode 100644
index 0000000..0cb55f5
--- /dev/null
+++ b/xml/ismrmrd_meta.h
@@ -0,0 +1,247 @@
+#ifndef ISMRMRDMETA_H
+#define ISMRMRDMETA_H
+
+#include "ismrmrd_xml_export.h"
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <stdexcept>
+
+namespace ISMRMRD
+{
+  /*
+    The serialized version of the structues would look like this
+    
+    <?xml version="1.0"?>
+    <ismrmrdMeta>
+       <!-- String value type -->
+       <meta>
+          <name>parameter1</name>
+	  <value>value_string</value>
+       </meta>
+
+       <!-- Integer value type -->
+       <meta>
+          <name>parameter1</name>
+	  <value>677797</value>
+       </meta>
+
+       <!-- Arrays can have mixed value types -->
+       <meta>
+          <name>parameter1</name>
+	  <value>1.456</value>
+	  <value>66797</value>
+	  <value>hsjdhaks</value>
+       </meta>
+    </ismrmrdMeta>
+   */
+
+
+  /**
+     This class can represent a meta data value of any
+     type and it guarantees that any value will have a
+     representation as any type.
+
+     The class uses std::string internally to store the 
+     string representation of the value but this std::string
+     is never exposed on the class interface and so it should not 
+     need to be exported in Windows. For now, this class can be header only.
+   */
+  class MetaValue
+  {
+
+  public:
+    /**
+       Default construtor
+     */
+    MetaValue()
+    {
+      set(0L);
+    }
+
+    ///Null terminated string constructor
+    MetaValue(const char* s)
+    {
+      set(s);
+    }
+
+    ///Long constructor
+    MetaValue(long l)
+    {
+      set(l);
+    }
+
+    ///Long constructor
+    MetaValue(double d)
+    {
+      set(d);
+    }
+
+
+    ///Assignment operator for string
+    MetaValue& operator=(const char * s) 
+    {
+      set(s);
+    }
+
+    ///Assignment operator for long
+    MetaValue& operator=(long l) 
+    {
+      set(l);
+    }
+
+    ///Assignment operator for double
+    MetaValue& operator=(double d) 
+    {
+      set(d);
+    }
+
+    ///Get the ingeter representation of the value
+    long as_long() const
+    {
+      return l_;
+    }
+
+    ///Get the floating point representation of the value
+    double as_double() const
+    {
+      return d_;
+    }
+    
+    ///get the C string representation of the value
+    const char* as_str() const
+    {
+      return s_.c_str();
+    }
+
+
+  protected:
+    long l_;
+    double d_;
+    std::string s_;
+
+    void set(const char* s)
+    {
+      s_ = std::string(s);
+      sscanf(s_.c_str(),"%ld",&l_);
+      sscanf(s_.c_str(),"%lf",&d_);      
+    }
+
+    void set(long l)
+    {
+      l_ = l;
+      d_ = static_cast<double>(l_);
+      std::stringstream strstream;
+      strstream << l_;
+      strstream >> s_;
+    }
+
+    void set(double d)
+    {
+      d_ = d;
+      l_ = static_cast<long>(d_);
+      std::stringstream strstream;
+      strstream << d_;
+      strstream >> s_;
+    }
+  };
+
+  class MetaContainer
+  {
+    typedef std::map< std::string, std::vector<MetaValue> > map_t;
+
+    friend void serialize(MetaContainer& h, std::ostream& o);
+
+  public:
+    MetaContainer()
+    {
+
+    }
+
+    /**
+       This function sets the parameter with name @name to 
+       value @value. The set function assumes the parameter
+       will have a single value and wipes out any array that might be there.
+       
+       There is an @append function for appending to an existing array.
+     */
+    template <class T> void set(const char* name, T value)
+    {
+      MetaValue v(value);
+      map_[std::string(name)] = std::vector<MetaValue>(1,value);
+    }
+
+   
+    template <class T> void append(const char* name, T value)
+    {
+      map_t::iterator it = map_.find(std::string(name));      
+      if (it == map_.end()) {
+	set(name, value);
+      } else {
+	MetaValue v(value);
+	it->second.push_back(v);
+      }
+    }
+
+    ///Return number of values of a particular parameter
+    size_t length(const char* name)
+    {
+      map_t::iterator it = map_.find(std::string(name));
+      if (it != map_.end()) {
+	return it->second.size();
+      }
+      return 0;
+    }
+
+    ///Return value number @index of the parameter @name as long
+    long as_long(const char* name, size_t index = 0)
+    {
+      return value(name,index).as_long();
+    }
+
+    ///Return value number @index of the parameter @name as double
+    double as_double(const char* name, size_t index = 0)
+    {
+      return value(name,index).as_double();
+    }
+    
+    ///Return value number @index of the parameter @name as string
+    const char* as_str(const char* name, size_t index = 0)
+    {
+      return value(name,index).as_str();
+    }
+
+    const MetaValue& value(const char* name, size_t index = 0)
+    {
+      map_t::iterator it = map_.find(std::string(name));
+      if (it == map_.end()) {
+	throw std::runtime_error("Attempting to access unkown parameter");
+      }
+      if (index >= it->second.size()) {
+	throw std::runtime_error("Attempting to access indexed value out of bounds");
+      }
+      return it->second[index];
+    }
+    
+  protected:
+    map_t map_; 
+  };
+
+  //Template function instanciations
+  /*
+  template void MetaContainer::set<const char*>(const char* name, const char* value);
+  template void MetaContainer::set<long>(const char* name, long value);
+  template void MetaContainer::set<double>(const char* name, double);
+  template void MetaContainer::append<const char*>(const char* name, const char* value);
+  template void MetaContainer::append<long>(const char* name, long value);
+  template void MetaContainer::append<double>(const char* name, double);
+  */
+
+  EXPORTISMRMRDXML void deserialize(const char* xml, MetaContainer& h);
+  EXPORTISMRMRDXML void serialize(MetaContainer& h, std::ostream& o);
+
+}
+
+#endif //ISMRMRDMETA_H
diff --git a/xml/ismrmrd_xml.h b/xml/ismrmrd_xml.h
index 6a9f729..0cc1365 100644
--- a/xml/ismrmrd_xml.h
+++ b/xml/ismrmrd_xml.h
@@ -1,3 +1,6 @@
+#ifndef ISMRMRDXML_H
+#define ISMRMRDXML_H
+
 #include "ismrmrd_xml_export.h"
 
 
@@ -39,6 +42,7 @@ namespace ISMRMRD
     const Optional& operator=(const T& v) {
       present_ = true;
       value_ = v;
+      return *this;
     }
 
     const T* operator->() const {
@@ -304,37 +308,6 @@ namespace ISMRMRD
 
   EXPORTISMRMRDXML void deserialize(const char* xml, IsmrmrdHeader& h);
   EXPORTISMRMRDXML void serialize(const IsmrmrdHeader& h, std::ostream& o);
-
-
-  /*
-  class IsmrmrdHeaderProxy 
-  {
-
-  public:
-
-    //Constructors
-    IsmrmrdHeaderProxy(const char* xml);
-    IsmrmrdHeaderProxy(const std::string& xml);
-    IsmrmrdHeaderProxy(); //Minimal Header
-
-    //Copy constructor
-    IsmrmrdHeaderProxy(const IsmrmrdHeader& h);
-    
-    //Assignment operator
-    IsmrmrdHeaderProxy& operator=(const IsmrmrdHeader& h);
-
-    void deserialize(const char* xml);
-
-    void serialize(std::ostream& o);
-
-    IsmrmrdHeader& h() {
-      return h_;
-    }
-
-  protected:
-    IsmrmrdHeader h_;
-  };
-  */
-
-
 }
+
+#endif //ISMRMRDXML_H
diff --git a/xml/test_meta.cpp b/xml/test_meta.cpp
new file mode 100644
index 0000000..59bacdd
--- /dev/null
+++ b/xml/test_meta.cpp
@@ -0,0 +1,33 @@
+#include <iostream>
+#include <sstream>
+#include "ismrmrd_meta.h"
+
+
+int main(int argc, char** argv)
+{
+  std::cout << "Test routine for ISMRMRD meta data structures" << std::endl << std::endl;
+
+  ISMRMRD::MetaContainer h;
+
+  h.set("my_para","this is one value");
+  h.append("my_para",77887L);
+  h.append("my_para",1.66754);
+  h.append("my_para","Blah Blah");  
+  h.set("my_para_2",4L);
+  h.set("my_para_3",4.778);
+
+  std::stringstream str;
+  ISMRMRD::serialize(h,str);
+
+  std::cout << "Serialized version of header: " << std::endl;
+  std::cout << str.str() << std::endl;
+
+  ISMRMRD::MetaContainer h2;
+  std::string xml = str.str();
+  deserialize(xml.c_str(),h2);
+
+  std::cout << "Header after deserialization and serialization" << std::endl;
+  serialize(h2, std::cout);
+
+  return 0;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ismrmrd.git



More information about the debian-science-commits mailing list