/** * \file rmf/hdf5_types.h * \brief Handle read/write of Model data from/to files. * * Copyright 2007-2011 IMP Inventors. All rights reserved. * */ #ifndef RMF_HDF_5_TYPES_H #define RMF_HDF_5_TYPES_H #include "NodeID.h" #include #include #include #include #include "exception.h" #include #ifdef SWIG typedef int hid_t; #endif namespace rmf { typedef std::vector Ints; typedef std::vector Floats; typedef std::vector Strings; /** Call a function and throw an exception if the return values is bad */ #define RMF_HDF5_CALL(v) if((v)<0) { \ RMF_THROW("Error calling "<< (#v), ValueException); \ } /** \name Traits classes The traits class for mapping between C++ types and HDF5 types. It defines - static hid_t get_hdf5_type() - static void write_value_dataset(hid_t d, hid_t is, hid_t s, double v) - static double read_value_dataset(hid_t d, hid_t is, hid_t sp) - static std::vector read_values_attribute(hid_t a, unsigned int size) - static void write_values_attribute(hid_t a, const std::vector &v) - static const double& get_null_value() - static std::string get_name() - static unsigned int get_index() @{ */ /** */ struct RMFEXPORT FloatTraits { typedef double Type; static hid_t get_hdf5_type(); static void write_value_dataset(hid_t d, hid_t is, hid_t s, double v); static double read_value_dataset(hid_t d, hid_t is, hid_t sp); static std::vector read_values_attribute(hid_t a, unsigned int size); static void write_values_attribute(hid_t a, const std::vector &v); static const double& get_null_value(); static const double& get_fill_value(); static bool get_is_null_value(const double& f) { return (f >= std::numeric_limits::max()); } static std::string get_name(); static unsigned int get_index() { return 1; } }; /** */ struct RMFEXPORT IntTraits { typedef int Type; static hid_t get_hdf5_type(); static void write_value_dataset(hid_t d, hid_t is, hid_t s, int v); static int read_value_dataset(hid_t d, hid_t is, hid_t sp); static std::vector read_values_attribute(hid_t a, unsigned int size); static void write_values_attribute(hid_t a, const std::vector &v); static const int& get_fill_value(); static const int& get_null_value(); static bool get_is_null_value(int i) { return i== std::numeric_limits::max(); } static std::string get_name(); static unsigned int get_index() { return 0; } }; /** A non-negative index.*/ struct RMFEXPORT IndexTraits: IntTraits { static const int& get_null_value(); static const int& get_fill_value(); static bool get_is_null_value(int i) { return i==-1; } static std::string get_name(); static unsigned int get_index() { return 2; } }; /** A string */ struct RMFEXPORT StringTraits { typedef std::string Type; static hid_t get_hdf5_type(); static void write_value_dataset(hid_t d, hid_t is, hid_t s, std::string v); static std::string read_value_dataset(hid_t d, hid_t is, hid_t sp); static std::vector read_values_attribute(hid_t a, unsigned int size); static void write_values_attribute(hid_t a, const std::vector &v); static const char*& get_null_value(); static const char& get_fill_value(); static bool get_is_null_value(std::string s) { return s.empty(); } static std::string get_name(); static unsigned int get_index() { return 3; } }; /** Store the Node for other nodes in the hierarchy. */ struct RMFEXPORT NodeIDTraits { typedef NodeID Type; static hid_t get_hdf5_type(); static void write_value_dataset(hid_t d, hid_t is, hid_t s, NodeID v); static NodeID read_value_dataset(hid_t d, hid_t is, hid_t sp); static std::vector read_values_attribute(hid_t a, unsigned int size); static void write_values_attribute(hid_t a, const std::vector &v); static const NodeID& get_null_value(); static const NodeID& get_fill_value(); static bool get_is_null_value(NodeID s) { return s== NodeID(); } static std::string get_name(); static unsigned int get_index() { return 4; } }; /** An HDF5 data set. Currently, the type of data stored in the data set must be known implicitly. The path to the HDF5 data set relative to the node containing the data is passed.*/ struct RMFEXPORT DataSetTraits: public StringTraits { static std::string get_name(); static unsigned int get_index() { return 5; } }; /** @} */ #ifndef SWIG #ifndef IMP_DOXYGEN //! The signature for the HDF5 close functions typedef herr_t (*HDF5CloseFunction)(hid_t) ; #endif //! Make sure an HDF5 handle is released /** CloseFunction should be an appropriate close function for the handle type, eg H5Aclose. */ class RMFEXPORT HDF5Handle { hid_t h_; HDF5CloseFunction f_; public: HDF5Handle(hid_t h, HDF5CloseFunction f): h_(h), f_(f) { if (h_<0) { RMF_THROW("Invalid handle returned", ValueException); } } hid_t get_hid() const { return h_; } #ifndef SWIG operator hid_t() const { return h_; } #endif bool get_is_open() const { return h_ != -1; } void open(hid_t h, HDF5CloseFunction f) { if (get_is_open()) { close(); } h_=h; RMF_USAGE_CHECK(h_>=0, "Invalid handle returned"); f_=f; } void close() { if (h_ != -1) { RMF_HDF5_CALL(f_(h_)); } h_=-1; } ~HDF5Handle() { close(); } }; #endif } #endif /* RMF_HDF_5_TYPES_H */