#include "h5core/h5_core.h" #include "h5_core_private.h" #include #include #include #include #include #include #include h5_err_t h5_add_attachment ( h5_file_t* const f, const char* const fname ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, fname='%s'", f, fname); // allowed file modes: O_RDWR, O_WRONLY; O_APPEND if (f->mode == H5_O_RDONLY) { H5_PRIV_FUNC_LEAVE ( h5priv_handle_file_mode_error (f->mode)); } struct stat st; if (stat (fname, &st) < 0) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_HDF5, "Cannot stat file '%s'", fname)); } hsize_t fsize = st.st_size; hsize_t write_length; char* buf = NULL; if (f->myproc == 0) { TRY (buf = h5_calloc (1, fsize)); write_length = fsize; int fd; if ((fd = open (fname, O_RDONLY)) < 0) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_HDF5, "Cannot open file '%s' for reading", fname)); } again: if (read (fd, buf, fsize) < 0) { if (errno == EINTR) { goto again; } else { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_HDF5, "Cannot read file '%s'", fname)); } } if (close (fd) < 0) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_HDF5, "Cannot close file '%s'", fname)); } } else { TRY (buf = h5_calloc (1, 1)); write_length = 0; } hid_t loc_id; TRY (loc_id = h5priv_open_group (1, f->file, H5_ATTACHMENT)); h5_err_t exists; TRY (exists = hdf5_link_exists (loc_id, fname)); if (exists && (f->mode == H5_O_RDWR || f->mode == H5_O_WRONLY)) { // remove } else if (exists && f->mode == H5_O_APPEND) { H5_PRIV_FUNC_LEAVE ( h5priv_handle_file_mode_error (f->mode)); } hid_t diskspace_id; TRY (diskspace_id = hdf5_create_dataspace (1, &fsize, &fsize)); hid_t dataset_id; TRY (dataset_id = hdf5_create_dataset (loc_id, fname, H5T_NATIVE_CHAR, diskspace_id, H5P_DEFAULT)); hsize_t start = 0; TRY (hdf5_select_hyperslab_of_dataspace ( diskspace_id, H5S_SELECT_SET, &start, NULL, &write_length, NULL)); hid_t memspace_id; hsize_t max = H5S_UNLIMITED; TRY (memspace_id = hdf5_create_dataspace (1, &write_length, &max)); TRY (hdf5_write_dataset (dataset_id, H5T_NATIVE_CHAR, memspace_id, diskspace_id, f->xfer_prop, buf)); TRY (hdf5_close_dataspace (diskspace_id)); TRY (hdf5_close_dataspace (memspace_id)); TRY (hdf5_close_dataset (dataset_id)); TRY (hdf5_close_group (loc_id)); TRY (h5_free (buf)); H5_CORE_API_RETURN (H5_SUCCESS); } static inline hid_t open_attachments ( h5_file_t* const f ) { h5_err_t exists = hdf5_link_exists (f->file, H5_ATTACHMENT); if (exists > 0) { return hdf5_open_group (f->file, H5_ATTACHMENT); } else if (exists == 0) { return h5_warn ("No attachment group in file"); } return exists; } h5_ssize_t h5_get_num_attachments ( h5_file_t* const f ) { H5_CORE_API_ENTER (h5_ssize_t, "f=%p", f); h5_ssize_t num = 0; hid_t group_id; TRY (group_id = open_attachments (f)); if (group_id < 0) { H5_CORE_API_LEAVE (0); } TRY (num = hdf5_get_num_datasets (group_id)); TRY (hdf5_close_group (group_id)); H5_CORE_API_RETURN (num); } h5_err_t h5_get_attachment_info_by_idx ( h5_file_t* const f, const h5_size_t idx, // IN char* const fname, // OUT h5_size_t len_fname, // IN h5_size_t* const fsize // OUT ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, idx=%llu, fname=%s, len_fname=%llu, fsize=%p", f, (unsigned long long)idx, fname, (unsigned long long)len_fname, fsize); hid_t loc_id; TRY (loc_id = open_attachments (f)); if (loc_id < 0) { // no attachment group in file H5_CORE_API_LEAVE (0); } TRY (hdf5_get_name_of_dataset_by_idx ( loc_id, idx, fname, len_fname)); if (fsize) { // get number of elements, do not change value on error h5_ssize_t ssize; TRY (ssize = hdf5_get_npoints_of_dataset_by_name (loc_id, fname)); *fsize = ssize; } TRY (hdf5_close_group (loc_id)); H5_CORE_API_RETURN (H5_SUCCESS); } h5_err_t h5_get_attachment_info_by_name ( h5_file_t* const f, const char* const fname, // IN h5_size_t* const fsize // OUT ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, fname='%s', fsize=%p", f, fname, fsize); hid_t loc_id; TRY (loc_id = open_attachments (f)); if (loc_id < 0) { H5_CORE_API_LEAVE (H5_NOK); } if (fsize) { // get number of elements, do not change value on error h5_ssize_t ssize; TRY (ssize = hdf5_get_npoints_of_dataset_by_name (loc_id, fname)); *fsize = ssize; } TRY (hdf5_close_group (loc_id)); H5_CORE_API_RETURN (H5_SUCCESS); } h5_err_t h5_get_attachment ( h5_file_t* const f, const char* const fname ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, fname='%s'", f, fname); // allowed modes: O_RDWR, O_RDONLY; O_APPEND // forbidden modes: O_WRONLY if (f->mode == H5_O_WRONLY) { H5_PRIV_FUNC_LEAVE ( h5priv_handle_file_mode_error (f->mode)); } hid_t loc_id; TRY (loc_id = hdf5_open_group (f->file, H5_ATTACHMENT)); h5_err_t exists; TRY (exists = hdf5_link_exists (loc_id, fname)); if (f->mode == H5_O_WRONLY) { H5_PRIV_FUNC_LEAVE ( h5priv_handle_file_mode_error (f->mode)); } else if (!exists) { H5_PRIV_FUNC_LEAVE ( h5_error ( H5_ERR_H5, "Attachment '%s' doesn't exist", fname)); } // read dataset hid_t dataset_id, diskspace_id; h5_ssize_t fsize; TRY (dataset_id = hdf5_open_dataset (loc_id, fname)); TRY (diskspace_id = hdf5_get_dataset_space (dataset_id)); TRY (fsize = hdf5_get_npoints_of_dataspace (diskspace_id)); hsize_t read_length; char* buf = NULL; if (f->myproc == 0) { buf = malloc (fsize); read_length = fsize; } else { buf = malloc (1); read_length = 0; } hsize_t start = 0; TRY (hdf5_select_hyperslab_of_dataspace ( diskspace_id, H5S_SELECT_SET, &start, NULL, &read_length, NULL)); hid_t memspace_id; hsize_t max = H5S_UNLIMITED; TRY (memspace_id = hdf5_create_dataspace (1, &read_length, &max)); TRY (hdf5_read_dataset (dataset_id, H5T_NATIVE_CHAR, memspace_id, diskspace_id, f->xfer_prop, buf)); TRY (hdf5_close_dataspace (diskspace_id)); TRY (hdf5_close_dataspace (memspace_id)); TRY (hdf5_close_dataset (dataset_id)); TRY (hdf5_close_group (loc_id)); // write file if (f->myproc == 0) { int fd; if ((fd = open (fname, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_H5, "Error opening file '%s': %s", fname, strerror(errno))); } if (write (fd, buf, fsize) != fsize) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_H5, "Error writing to file '%s': %s", fname, strerror(errno))); } if (close (fd) < 0) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_H5, "Error closing file '%s': %s", fname, strerror(errno))); } } TRY (h5_free (buf)); H5_CORE_API_RETURN (H5_SUCCESS); } h5_err_t h5_delete_attachment ( h5_file_t* const f, const char* const fname ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, fname='%s'", f, fname); hid_t group_id; TRY (group_id = open_attachments (f)); if (group_id < 0) { H5_CORE_API_LEAVE (H5_NOK); } TRY (hdf5_delete_link (group_id, fname, H5P_DEFAULT)); TRY (hdf5_close_group (group_id)); H5_CORE_API_RETURN (H5_SUCCESS); }