00001 /* 00002 * The information in this file is 00003 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation 00004 * and is subject to the terms and conditions of the 00005 * GNU Lesser General Public License Version 2.1 00006 * The license text is available from 00007 * http://www.gnu.org/licenses/lgpl.html 00008 */ 00009 00010 #ifndef HDF5CUSTOMREADER_H 00011 #define HDF5CUSTOMREADER_H 00012 00013 #include "Hdf5Resource.h" 00014 00015 #include <hdf5.h> 00016 00017 #include <vector> 00018 00019 /** 00020 * This interface should be implemented to allow a custom 00021 * type to be read by the HdfPlugInLib. In addition 00022 * to implementing this custom interface, a template 00023 * specialization of createHdf5CustomReader() needs 00024 * to be created for the given type. This class 00025 * has a highly defined calling order for the functions 00026 * which is defined below: 00027 * - An Hdf5CustomReader instance is created by 00028 * invoking createHdf5CustomReader(). 00029 * - Hdf5CustomReader::isValid() is called and 00030 * if the return value is false, the Hdf5CustomReader 00031 * instance is deleted. 00032 * - Hdf5CustomReader::getSupportedDimensionality() is called 00033 * and if the return value does not match the dimensionality 00034 * required to read the data in, the Hdf5CustomReader 00035 * instance is deleted. 00036 * - Hdf5CustomReader::setReadDataSpace() is called and 00037 * if the return value is false, the Hdf5CustomReader 00038 * instance is deleted.. 00039 * - Hdf5CustomReader::getReadMemoryType() is called. 00040 * - Hdf5CustomReader::getReadBuffer() is called. 00041 * - Hdf5CustomReader::getValue() is called. 00042 * - The Hdf5CustomReader instance is deleted. 00043 */ 00044 class Hdf5CustomReader 00045 { 00046 public: 00047 /** 00048 * Destroys the reader object. 00049 */ 00050 virtual ~Hdf5CustomReader() {} 00051 00052 /** 00053 * Determines whether the reader is valid 00054 * for the given HDF5 datatype 00055 * provided to the createHdf5CustomReader() 00056 * function. If false is returned, this 00057 * instance is immediately deleted and 00058 * the read operation is stopped. If true 00059 * is returned the read operation continues. 00060 * 00061 * @return Return false in your implementation 00062 * if the given HDF5 datatype 00063 * is NOT supported by this 00064 * reader class, otherwise return true. 00065 */ 00066 virtual bool isValid() const = 0; 00067 00068 /** 00069 * Returns the HDF5 dimensionality or rank 00070 * supported by this Hdf5CustomReader interface. 00071 * 00072 * @return Returns the HDF5 dimensionality or rank 00073 * supported by this Hdf5CustomReader. 00074 */ 00075 virtual unsigned int getSupportedDimensionality() const = 0; 00076 00077 /** 00078 * Return the HDF5 datatype, ie. hid_t that 00079 * represents the in-memory type. The type 00080 * returned should be compatible with the 00081 * void* buffer returned from getReadBuffer(). 00082 * This type will be provided as the memory datatype 00083 * to either a H5Aread() or H5Dread() call in 00084 * the HDF5 library depending on whether data 00085 * is being read from an HDF5 attribute or an 00086 * HDF5 dataset. The hid_t returned from 00087 * this function will be properly closed 00088 * by the Hdf5TypeResource object when 00089 * the read operation is complete. 00090 * 00091 * @return Returns the HDF5 datatype that 00092 * represents the in-memory type. If 00093 * appropriate you can simly return 00094 * a H5Tcopy() of the type provided 00095 * to createHdf5CustomReader(). 00096 */ 00097 virtual Hdf5TypeResource getReadMemoryType() const = 0; 00098 00099 /** 00100 * Sets the dimensions of the data that will 00101 * be read in from the given dataspace. 00102 * 00103 * @param dataSpace 00104 * The dimensions and size of each dimension for 00105 * the data that will be read in. An empty 00106 * vector indicates scalar data will be read 00107 * in, ie. a single value. 00108 * 00109 * @return Return true if the provided dimensions are 00110 * supported by this reader, false otherwise. 00111 */ 00112 virtual bool setReadDataSpace(const std::vector<hsize_t>& dataSpace) = 0; 00113 00114 /** 00115 * Returns a buffer suitable to pass to the H5Aread() 00116 * or H5Dread() calls in the HDF5 library. The type 00117 * and layout of the buffer are dependent on the HDF5 00118 * datatype returned from getReadMemoryType(). The 00119 * size of the buffer is dependent on the value 00120 * provided to setReadDataSpace. This 00121 * pointer should be owned by the Hdf5CustomReader 00122 * and deleted in the destructor. 00123 * 00124 * @return Returns a buffer suitable to pass to 00125 * the HDF5 library calls of H5Aread() 00126 * or H5Dread(). 00127 */ 00128 virtual void* getReadBuffer() const = 0; 00129 00130 /** 00131 * Returns a pointer to data which can 00132 * be safely cast to T*, where T is the 00133 * template specialization of 00134 * createHdf5CustomReader. The returned 00135 * data should NOT be owned by the 00136 * Hdf5CustomReader and will be owned 00137 * by the caller of this function. The 00138 * T* returned should be populated from 00139 * the data that was pushed into the 00140 * getReadBuffer() by the H5Aread() 00141 * or H5Dread() calls. 00142 * 00143 * @return Returns a pointer to data 00144 * which can be safely cast to T* 00145 * by the caller, where T is 00146 * template specialization of createHdf5CustomReader(). 00147 */ 00148 virtual void* getValue() const = 0; 00149 00150 00151 }; 00152 00153 /** 00154 * This function should be specialized for any custom types 00155 * that need to be read using the Hdf5Data::readData() function 00156 * which is provided for both Hdf5Dataset and Hdf5Attribute. 00157 * An example is shown below: 00158 * \code 00159 * struct mySampleType 00160 * { 00161 * int foo; 00162 * int bar; 00163 * }; 00164 * 00165 * class mySampleTypeReader; //assume this is declared elsewhere as class mySampleTypeReader : public Hdf5CustomReader 00166 * //Want to read mySampleType using Hdf5Data::readData function 00167 * template<> 00168 * Hdf5CustomReader* createHdf5CustomReader<mySampleType>(hid_t dataType) 00169 * { 00170 * return new mySampleTypeReader(dataType); 00171 * } 00172 * 00173 * //now to read the data, assume pData is a pointer of type Hdf5Data, ie. Hdf5Dataset or Hdf5Attribute 00174 * mySampleType* pSampleData = pData->readData<mySampleType>(); 00175 * //the read call above will use your createHdf5CustomReader specialization and your subclass 00176 * //of Hdf5CustomReader to perform the read from the Hdf5 file and conversion to mySampleType. 00177 * \endcode 00178 * 00179 * 00180 * @param dataType 00181 * This is the HDF5 datatype of the data that will be read. 00182 * 00183 * @return Returns an Hdf5CustomReader implementation that is suitable 00184 * for reading the given type from a HDF5 file. If the given 00185 * dataType is unsupported by the reader either 00186 * NULL can be returned from this method or the Hdf5CustomReader 00187 * instance returned from this method can return false 00188 * from Hdf5CustomReader::isValid(). 00189 */ 00190 template<typename T> 00191 Hdf5CustomReader* createHdf5CustomReader(hid_t dataType); 00192 00193 #endif