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 HDF5INCREMENTALREADER_H 00011 #define HDF5INCREMENTALREADER_H 00012 00013 #include "Hdf5CustomReader.h" 00014 00015 #include <memory> 00016 #include <string> 00017 #include <vector> 00018 00019 #include <hdf5.h> 00020 00021 /** 00022 * This class provides the ability to incrementally read 00023 * values from a HDF5 dataset without having to read the 00024 * entire dataset into memory at once as Hdf5Dataset::readData() 00025 * requires. 00026 */ 00027 class Hdf5IncrementalReader 00028 { 00029 public: 00030 /** 00031 * Construct an instance of this reader to read data 00032 * from the provided HDF5 dataset. 00033 * 00034 * @param dataSet 00035 * A HDF5 dataset handle to an already open HDF5 dataset. 00036 * This dataset handle will not be closed by the reader. 00037 */ 00038 Hdf5IncrementalReader(hid_t dataSet); 00039 00040 /** 00041 * Destroys the Hdf5IncrementalReader. The HDF5 dataset 00042 * handle provided in the constructor is NOT closed. 00043 */ 00044 virtual ~Hdf5IncrementalReader(); 00045 00046 /** 00047 * Selects points in the dataset that will be read when calling 00048 * readSelecteData(). This method is a wrapper for 00049 * H5Sselect_hyperslab(). Please reference the 00050 * documentation in the HDF5 library for more details. 00051 * 00052 * @param operation 00053 * Please see H5Sselect_hyperslab() documentation. 00054 * @param pStart 00055 * Please see H5Sselect_hyperslab() documentation. 00056 * @param pStride 00057 * Please see H5Sselect_hyperslab() documentation. 00058 * @param pCount 00059 * Please see H5Sselect_hyperslab() documentation. 00060 * @param pBlock 00061 * Please see H5Sselect_hyperslab() documentation. 00062 * 00063 * @return Returns false if an invalid HDF5 dataset was provided or 00064 * H5Sselect_hyperslab() returns a negative value. 00065 */ 00066 bool selectHyperslab(H5S_seloper_t operation, 00067 const hsize_t* pStart, 00068 const hsize_t* pStride, 00069 const hsize_t* pCount, 00070 const hsize_t* pBlock); 00071 00072 /** 00073 * Selects points in the dataset that will be read when calling 00074 * readSelecteData(). This method is a wrapper for 00075 * H5Sselect_elements(). Please reference the 00076 * documentation in the HDF5 library for more details. 00077 * 00078 * @param operation 00079 * Please see H5Sselect_elements() documentation. 00080 * @param num_elements 00081 * Please see H5Sselect_elements() documentation. 00082 * @param pCoord 00083 * Please see H5Sselect_elements() documentation. 00084 * 00085 * @return Returns false if an invalid HDF5 dataset was provided or 00086 * H5Sselect_elements() returns a negative value. 00087 */ 00088 bool selectElements(H5S_seloper_t operation, const size_t num_elements, const hsize_t * pCoord); 00089 00090 /** 00091 * Selects all points in the dataset, so that they 00092 * will be read when calling readSelectedData(). This 00093 * method is a wrapper for 00094 * H5Sselect_all(). Please reference the 00095 * documentation in the HDF5 library for more details. 00096 * 00097 * @return Returns false if an invalid HDF5 dataset was provided or 00098 * H5Sselect_all() returns a negative value. 00099 */ 00100 bool selectAll(); 00101 00102 /** 00103 * Selects no points in the dataset, so that nothing 00104 * will be read when calling readSelectedData(). This 00105 * method is a wrapper for 00106 * H5Sselect_none(). Please reference the 00107 * documentation in the HDF5 library for more details. 00108 * 00109 * @return Returns false if an invalid HDF5 dataset was provided or 00110 * H5Sselect_none() returns a negative value. 00111 */ 00112 bool selectNone(); 00113 00114 /** 00115 * Returns true if the current selection is valid 00116 * for the dataset. This method is a wrapper for 00117 * H5Sselect_valid(). 00118 * 00119 * @return Returns false if an invalid HDF5 dataset was provided 00120 * or H5Sselect_valid() returns a value of 0 or less. 00121 */ 00122 bool isSelectionValid() const; 00123 00124 /** 00125 * Returns a handle to the HDF5 dataset that was provided in 00126 * the constructor. 00127 * 00128 * @return Returns a handle to the HDF5 dataset being read this 00129 * reader. 00130 */ 00131 hid_t getDataSet() const; 00132 00133 /** 00134 * Returns a handle to the HDF5 dataspace that will be used 00135 * as the selection when reading data out of the HDF5 dataset. 00136 * 00137 * @return Returns a handle to the HDF5 dataspace that defines 00138 * the selected data. 00139 */ 00140 hid_t getSelectionDataSpace() const; 00141 00142 /** 00143 * Returns a count of the number of points that are selected 00144 * in the HDF5 dataset for reading. This method is a wrapper 00145 * for H5Sget_select_npoints() using the dataspace handle 00146 * returned from getSelectionDataSpace(). 00147 * 00148 * @returns Returns -1 if an invalid HDF5 dataset was provided, 00149 * otherwise the return value of H5Sget_select_npoints(). 00150 */ 00151 hssize_t getNumberOfSelectedPoints() const; 00152 00153 /** 00154 * Reads the selected data from the HDF dataset as the given 00155 * type. The caller of this function 00156 * is responsible for deleting the returned memory. 00157 * 00158 * @return Returns the parsed value. 00159 * If the data could not be parsed by the Hdf5CustomReader instance 00160 * then NULL will be returned. 00161 */ 00162 template<typename T> 00163 T* readSelectedData() const 00164 { 00165 DO_IF(mDataset < 0, return NULL); 00166 DO_IF(mDataspace < 0, return NULL); 00167 Hdf5TypeResource type(H5Dget_type(mDataset)); 00168 DO_IF(*type < 0, return NULL); 00169 std::auto_ptr<Hdf5CustomReader> pReader(createHdf5CustomReader<T>(*type)); 00170 DO_IF(pReader.get() == NULL || !pReader->isValid(), return NULL); 00171 00172 hssize_t numberOfPoints = getNumberOfSelectedPoints(); 00173 DO_IF(numberOfPoints <= 0, return NULL); 00174 bool supported = false; 00175 std::vector<hsize_t> dimensions; 00176 if (pReader->getSupportedDimensionality() == 1) 00177 { 00178 dimensions.push_back(numberOfPoints); 00179 supported = true; 00180 } 00181 else if (pReader->getSupportedDimensionality() == 0 && numberOfPoints == 1) 00182 { 00183 supported = true; 00184 } 00185 DO_IF(!supported, return NULL); 00186 DO_IF(!pReader->setReadDataSpace(dimensions), return NULL); 00187 void* pData = pReader->getReadBuffer(); 00188 Hdf5TypeResource memType(pReader->getReadMemoryType()); 00189 hsize_t readDataSpaceDims = numberOfPoints; 00190 Hdf5DataSpaceResource readDataSpace(H5Screate_simple(1, &readDataSpaceDims, NULL)); 00191 int readStatus = H5Dread(mDataset, *memType, *readDataSpace, mDataspace, H5P_DEFAULT, pData); 00192 DO_IF(readStatus < 0, return NULL); 00193 return reinterpret_cast<T*>(pReader->getValue()); 00194 } 00195 00196 protected: 00197 hid_t mDataset; 00198 hid_t mDataspace; 00199 }; 00200 00201 #endif