Skip to content
Snippets Groups Projects
Commit 80502b4a authored by Giovanni La Mura's avatar Giovanni La Mura
Browse files

Define HDF5 I/O wrapper library

parent 27a5b3b9
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,8 @@ class FileSchema {
protected:
//! \brief Number of records conained in the file.
int num_records;
//! \brief Array of record names.
std::string *record_names;
//! \brief Array of record descriptors.
std::string *record_types;
......@@ -28,11 +30,28 @@ class FileSchema {
* \param num_rec: `int` Number of records in the file.
* \param rec_types: `string *` Description of the records in the file.
*/
FileSchema(int num_rec, std::string *rec_types);
FileSchema(int num_rec, std::string *rec_types, std::string *rec_names=NULL);
/*! \brief FileSchema instance destroyer.
*/
~FileSchema();
/*! \brief Get the number of records in file.
*
* \return num_records: `int` The number of records contained in the file.
*/
int get_record_number() { return num_records; }
/*! \brief Get a copy of the record types.
*
* \return rec_types: `string *` A new vector of strings with description of records.
*/
std::string *get_record_names();
/*! \brief Get a copy of the record names.
*
* \return rec_names: `string *` A new vector of strings with record names.
*/
std::string *get_record_types();
};
/*! \class HDFFile
......@@ -43,28 +62,56 @@ class FileSchema {
*/
class HDFFile {
protected:
//! \brief Identifier list.
List<hid_t> *id_list;
//! \brief Name of the file.
std::string file_name;
//! \brief Flag for the open file status.
bool file_open_flag;
//! File identifier handle.
hid_t file_id;
//! Return status of the last operation.
herr_t status;
public:
/*! \brief HDFFile instance constructor.
*
* \param name: `string` Name of the file.
* \param flags: `unsigned int` File access flags.
* \param fcpl_id: `hid_t` File creation property list identifier.
* \param fapl_id: `hid_t` File access property list identifier.
* \param flags: `unsigned int` File access flags (default is `H5F_ACC_EXCL`).
* \param fcpl_id: `hid_t` File creation property list identifier (default is `H5P_DEFAULT`).
* \param fapl_id: `hid_t` File access property list identifier (default is `H5P_DEFAULT`).
*/
HDFFile(
std::string name, unsigned int flags = H5F_ACC_EXCL,
hid_t fcpl_id = H5P_DEFAULT, hid_t fapl_id = H5P_DEFAULT
);
);
/*! \brief HDFFile instance destroyer.
*/
~HDFFile();
/*! \brief Close the current file.
*/
herr_t close();
/*! \brief Create an empty file from a `FileSchema` instance.
*
* \param schema: `FileSchema &` Reference to `FileSchema` instance.
* \param name: `string` Name of the file.
* \param flags: `unsigned int` File access flags (default is `H5F_ACC_EXCL`).
* \param fcpl_id: `hid_t` File creation property list identifier (default is `H5P_DEFAULT`).
* \param fapl_id: `hid_t` File access property list identifier (default is `H5P_DEFAULT`).
* \return hdf_file: `HDFFile *` Pointer to a new, open HDF5 file.
*/
static HDFFile* from_schema(
FileSchema &schema, std::string name, unsigned int flags = H5F_ACC_EXCL,
hid_t fcpl_id = H5P_DEFAULT, hid_t fapl_id = H5P_DEFAULT
);
/*! \brief Get current status.
*/
hid_t get_file_id() { return file_id; }
/*! \brief Get current status.
*/
herr_t get_status() { return status; }
......@@ -72,5 +119,26 @@ class HDFFile {
/*! \brief Check whether the attached file is currently open.
*/
bool is_open() { return file_open_flag; }
/* ! \brief Read data from attached file.
*/
// herr_t read();
/*! \brief Write data to attached file.
*
* \param dataset_name: `string` Name of the dataset to write to.
* \param data_type: `string` Memory data type identifier.
* \param buffer: `hid_t` Starting address of the memory sector to be written.
* \param mem_space_id: `hid_t` Memory data space identifier (defaults to `H5S_ALL`).
* \param file_space_id: `hid_t` File space identifier (defaults to `H5S_ALL`).
* \param dapl_id: `hid_t` Data access property list identifier (defaults to `H5P_DEFAULT`).
* \param dxpl_id: `hid_t` Data transfer property list identifier (defaults to `H5P_DEFAULT`).
* \return status: `herr_t` Exit status of the operation.
*/
herr_t write(
std::string dataset_name, std::string data_type, const void *buffer,
hid_t mem_space_id=H5S_ALL, hid_t file_space_id=H5S_ALL,
hid_t dapl_id=H5P_DEFAULT, hid_t dxpl_id=H5P_DEFAULT
);
};
#endif
......@@ -2,32 +2,171 @@
*
* \brief Implementation of file I/O operations.
*/
#include <stdexcept>
#include <regex>
#include <string>
#include "hdf5.h"
#ifndef INCLUDE_LIST_H_
#include "List.h"
#endif
#ifndef INCLUDE_FILE_IO_H_
#include "../include/file_io.h"
#include "file_io.h"
#endif
using namespace std;
FileSchema::FileSchema(int num_rec, string *rec_types) {
FileSchema::FileSchema(int num_rec, string *rec_types, string *rec_names) {
num_records = num_rec;
record_types = new string[num_rec];
for (int i = 0; i < num_rec; i++) record_types[i] = rec_types[i];
record_names = new string[num_rec];
for (int i = 0; i < num_rec; i++) {
record_types[i] = rec_types[i];
if (rec_names != NULL) record_names[i] = rec_names[i];
else record_names[i] = "/dset" + to_string(i);
}
}
FileSchema::~FileSchema() {
delete[] record_names;
delete[] record_types;
}
FileSchema::~FileSchema() { delete[] record_types; }
string* FileSchema::get_record_names() {
string *rec_names = new string[num_records];
for (int i = 0; i < num_records; i++) rec_names[i] = record_names[i];
return rec_names;
}
string* FileSchema::get_record_types() {
string *rec_types = new string[num_records];
for (int i = 0; i < num_records; i++) rec_types[i] = record_types[i];
return rec_types;
}
HDFFile::HDFFile(string name, unsigned int flags, hid_t fcpl_id, hid_t fapl_id) {
file_name = name;
file_id = H5Fcreate(name.c_str(), flags, fcpl_id, fapl_id);
id_list = new List<hid_t>(1);
id_list->set(0, file_id);
if (file_id != H5I_INVALID_HID) file_open_flag = true;
status = (herr_t)0;
}
HDFFile::~HDFFile() {
if (H5Iis_valid(file_id) > 0) status = H5Fclose(file_id);
delete id_list;
}
herr_t HDFFile::close() {
status = H5Fclose(file_id);
if (status == 0) file_open_flag = false;
return status;
}
HDFFile* HDFFile::from_schema(
FileSchema &schema, string name, unsigned int flags,
hid_t fcpl_id, hid_t fapl_id
) {
HDFFile *hdf_file = new HDFFile(name, flags, fcpl_id, fapl_id);
hid_t file_id = hdf_file->get_file_id();
herr_t status;
string *rec_types = schema.get_record_types();
string *rec_names = schema.get_record_names();
string known_types[] = {"INT32", "FLOAT64"};
int rec_num = schema.get_record_number();
regex re;
smatch m;
for (int ri = 0; ri < rec_num; ri++) {
int rank = 0;
hsize_t *dims, *max_dims;
hid_t data_type;
string str_target = rec_types[ri];
int type_index = 0;
bool found_type = false;
while (!found_type) {
re = regex(known_types[type_index++]);
if (regex_search(str_target, m, re)) {
found_type = true;
str_target = m.suffix().str();
if (type_index == 1) data_type = H5Tcopy(H5T_NATIVE_INT);
else if (type_index == 2) data_type = H5Tcopy(H5T_NATIVE_DOUBLE);
}
if (type_index == 2) break;
}
if (found_type) {
re = regex("[0-9]+");
string old_target = str_target;
while (regex_search(str_target, m, re)) {
rank++;
str_target = m.suffix().str();
}
dims = new hsize_t[rank]();
max_dims = new hsize_t[rank]();
str_target = old_target;
for (int ti = 0; ti < rank; ti++) {
regex_search(str_target, m, re);
hsize_t dim = (hsize_t)stoi(m.str());
dims[ti] = dim;
max_dims[ti] = dim;
str_target = m.suffix().str();
}
hid_t dataspace_id = H5Screate_simple(rank, dims, max_dims);
hid_t dataset_id = H5Dcreate(
file_id, rec_names[ri].c_str(), data_type, dataspace_id, H5P_DEFAULT,
H5P_DEFAULT, H5P_DEFAULT
);
status = H5Sclose(dataspace_id);
status = H5Dclose(dataset_id);
delete[] dims;
delete[] max_dims;
} else {
string message = "unrecognized type \"" + rec_types[ri] + "\"\n";
throw runtime_error(message);
}
}
delete[] rec_types;
delete[] rec_names;
return hdf_file;
}
herr_t HDFFile::write(
string dataset_name, string data_type, const void *buffer,
hid_t mem_space_id, hid_t file_space_id, hid_t dapl_id,
hid_t dxpl_id
) {
string known_types[] = {"INT32", "FLOAT64"};
regex re;
smatch m;
bool found_type = false;
int type_index = 0;
while (!found_type) {
re = regex(known_types[type_index++]);
found_type = regex_search(data_type, m, re);
if (type_index == 2) break;
}
if (found_type) {
hid_t dataset_id = H5Dopen2(file_id, dataset_name.c_str(), dapl_id);
hid_t mem_type_id;
switch (type_index) {
case 1:
mem_type_id = H5T_NATIVE_INT; break;
case 2:
mem_type_id = H5T_NATIVE_DOUBLE; break;
default:
throw runtime_error("Unrecognized data type \"" + data_type + "\"");
}
if (dataset_id != H5I_INVALID_HID) {
status = H5Dwrite(dataset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buffer);
if (status == 0) status = H5Dclose(dataset_id);
else status = (herr_t)-2;
} else {
status = (herr_t)-1;
}
} else {
throw runtime_error("Unrecognized data type \"" + data_type + "\"");
}
return status;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment