diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org index 5e0096a..fb517ad 100644 --- a/src/templates_front/templator_front.org +++ b/src/templates_front/templator_front.org @@ -688,29 +688,6 @@ interface end interface #+end_src -** C helper functions - - #+begin_src c :tangle prefix_front.c -trexio_exit_code transform_str (char** dest, const char** src, uint64_t str_max_num, uint32_t str_max_len){ - - if (dest == NULL) return TREXIO_INVALID_ARG_1; - assert (str_max_num > 0); - assert (str_max_len > 0); - - char* tmp_str = (char*)calloc(str_max_num*(str_max_len+1)+1,sizeof(char)); - - for (int i=0; iback_end) { case TREXIO_TEXT: - rc = trexio_text_write_$group_num$(file, (int64_t) num); + return trexio_text_write_$group_num$(file, (int64_t) num); break; case TREXIO_HDF5: - rc = trexio_hdf5_write_$group_num$(file, (int64_t) num); + return trexio_hdf5_write_$group_num$(file, (int64_t) num); break; /* case TREXIO_JSON: - rc = trexio_json_write_$group_num$(file, (int64_t) num); + return trexio_json_write_$group_num$(file, (int64_t) num); break; ,*/ } - if (rc != TREXIO_SUCCESS) return rc; - return TREXIO_SUCCESS; + return TREXIO_FAILURE; } #+end_src @@ -917,26 +891,23 @@ trexio_write_$group_num$_32 (trexio_t* const file, const int32_t num) if (file == NULL) return TREXIO_INVALID_ARG_1; if (num < 0 ) return TREXIO_INVALID_ARG_2; - trexio_exit_code rc = TREXIO_GROUP_WRITE_ERROR; - switch (file->back_end) { case TREXIO_TEXT: - rc = trexio_text_write_$group_num$(file, (int64_t) num); + return trexio_text_write_$group_num$(file, (int64_t) num); break; case TREXIO_HDF5: - rc = trexio_hdf5_write_$group_num$(file, (int64_t) num); + return trexio_hdf5_write_$group_num$(file, (int64_t) num); break; /* case TREXIO_JSON: - rc = trexio_json_write_$group_num$(file, (int64_t) num); + return trexio_json_write_$group_num$(file, (int64_t) num); break; ,*/ } - if (rc != TREXIO_SUCCESS) return rc; - return TREXIO_SUCCESS; + return TREXIO_FAILURE; } #+end_src @@ -980,8 +951,8 @@ trexio_has_$group_num$ (trexio_t* const file) break; ,*/ } - return TREXIO_FAILURE; + return TREXIO_FAILURE; } #+end_src @@ -1411,7 +1382,7 @@ end interface #+end_src ** Templates for front end has/read/write a dataset of strings - +*** Introduction This section concerns API calls related to datasets of strings. | Function name | Description | @@ -1622,6 +1593,145 @@ interface end interface #+end_src +** Templates for front end has/read/write a single string attribute +*** Introduction + + This section concerns API calls related to string attributes. + + | Function name | Description | + |----------------------------+----------------------------------------------| + | ~trexio_has_$group_str$~ | Check if a string attribute exists in a file | + | ~trexio_read_$group_str$~ | Read a string attribute | + | ~trexio_write_$group_str$~ | Write a string attribute | + +*** C templates for front end + + #+begin_src c :tangle hrw_attr_str_front.h :exports none +trexio_exit_code trexio_has_$group_str$(trexio_t* const file); +trexio_exit_code trexio_read_$group_str$(trexio_t* const file, char* const str); +trexio_exit_code trexio_write_$group_str$(trexio_t* const file, const char* str); + #+end_src + + #+begin_src c :tangle read_attr_str_front.c +trexio_exit_code +trexio_read_$group_str$ (trexio_t* const file, char* const str) +{ + + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (str == NULL) return TREXIO_INVALID_ARG_2; + + switch (file->back_end) { + + case TREXIO_TEXT: + //return trexio_text_read_$group_str$(file, str); + break; + + case TREXIO_HDF5: + return trexio_hdf5_read_$group_str$(file, str); + break; +/* + case TREXIO_JSON: + return trexio_json_read_$group_str$(file, str); + break; +,*/ + } + + return TREXIO_FAILURE; +} + #+end_src + + #+begin_src c :tangle write_attr_str_front.c +trexio_exit_code +trexio_write_$group_str$ (trexio_t* const file, const char* str) +{ + + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (str == NULL) return TREXIO_INVALID_ARG_2; + + switch (file->back_end) { + + case TREXIO_TEXT: + //return trexio_text_write_$group_str$(file, str); + break; + + case TREXIO_HDF5: + return trexio_hdf5_write_$group_str$(file, str); + break; +/* + case TREXIO_JSON: + return trexio_json_write_$group_str$(file, str); + break; +,*/ + } + + return TREXIO_FAILURE; +} + #+end_src + + #+begin_src c :tangle has_attr_str_front.c +trexio_exit_code +trexio_has_$group_str$ (trexio_t* const file) +{ + + if (file == NULL) return TREXIO_INVALID_ARG_1; + + assert(file->back_end < TREXIO_INVALID_BACK_END); + + switch (file->back_end) { + + case TREXIO_TEXT: + //return trexio_text_has_$group_str$(file); + break; + + case TREXIO_HDF5: + return trexio_hdf5_has_$group_str$(file); + break; +/* + case TREXIO_JSON: + return trexio_json_has_$group_str$(file); + break; +,*/ + } + return TREXIO_FAILURE; + +} + #+end_src + +*** Fortran templates for front end + + The ~Fortran~ templates that provide an access to the ~C~ API calls from Fortran. + These templates are based on the use of ~iso_c_binding~. Pointers have to be passed by value. + + + #+begin_src f90 :tangle write_attr_str_front_fortran.f90 +interface + integer function trexio_write_$group_str$ (trex_file, str) bind(C) + use, intrinsic :: iso_c_binding + integer(8), intent(in), value :: trex_file + character, intent(in) :: str(*) + end function trexio_write_$group_str$ +end interface + #+end_src + + #+begin_src f90 :tangle read_attr_str_front_fortran.f90 +interface + integer function trexio_read_$group_str$ (trex_file, str) bind(C) + use, intrinsic :: iso_c_binding + integer(8), intent(in), value :: trex_file + character, intent(out) :: str(*) + end function trexio_read_$group_str$ +end interface + #+end_src + + #+begin_src f90 :tangle has_attr_str_front_fortran.f90 +interface + integer function trexio_has_$group_str$ (trex_file) bind(C) + use, intrinsic :: iso_c_binding + integer(8), intent(in), value :: trex_file + end function trexio_has_$group_str$ +end interface + #+end_src + * Fortran helper/wrapper functions The function below adapts the original C-based ~trexio_open~ for Fortran. diff --git a/src/templates_hdf5/templator_hdf5.org b/src/templates_hdf5/templator_hdf5.org index 62f1e58..2680f9b 100644 --- a/src/templates_hdf5/templator_hdf5.org +++ b/src/templates_hdf5/templator_hdf5.org @@ -56,6 +56,7 @@ #define $GROUP$_GROUP_NAME "$group$" #define $GROUP_NUM$_NAME "$group_num$" #define $GROUP_DSET$_NAME "$group_dset$" +#define $GROUP_STR$_NAME "$group_str$" #+end_src ** Template for HDF5 structures @@ -155,7 +156,7 @@ trexio_hdf5_deinit (trexio_t* const file) } #+end_src -** Template for HDF5 has/read/write a number +** Template for HDF5 has/read/write a single dimensioning variable #+begin_src c :tangle hrw_num_hdf5.h :exports none trexio_exit_code trexio_hdf5_has_$group_num$ (trexio_t* const file); @@ -176,11 +177,14 @@ trexio_hdf5_read_$group_num$ (trexio_t* const file, uint64_t* const num) /* Quit if the dimensioning attribute is missing in the file */ if (H5Aexists(f->$group$_group, $GROUP_NUM$_NAME) == 0) return TREXIO_FAILURE; - /* Read the nucleus_num attribute of nucleus group */ + /* Read the $group_num$ attribute of $group$ group */ const hid_t num_id = H5Aopen(f->$group$_group, $GROUP_NUM$_NAME, H5P_DEFAULT); if (num_id <= 0) return TREXIO_INVALID_ID; const herr_t status = H5Aread(num_id, H5T_NATIVE_UINT64, num); + + H5Aclose(num_id); + if (status < 0) return TREXIO_FAILURE; return TREXIO_SUCCESS; @@ -623,7 +627,132 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file) } #+end_src + +** Template for HDF5 has/read/write a single string attribute + #+begin_src c :tangle hrw_attr_str_hdf5.h :exports none +trexio_exit_code trexio_hdf5_has_$group_str$ (trexio_t* const file); +trexio_exit_code trexio_hdf5_read_$group_str$ (trexio_t* const file, char* const str); +trexio_exit_code trexio_hdf5_write_$group_str$(trexio_t* const file, const char* str); + #+end_src + + + #+begin_src c :tangle read_attr_str_hdf5.c +trexio_exit_code +trexio_hdf5_read_$group_str$ (trexio_t* const file, char* const str) +{ + + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (str == NULL) return TREXIO_INVALID_ARG_2; + + const trexio_hdf5_t* f = (const trexio_hdf5_t*) file; + /* Quit if the string attribute is missing in the file */ + if (H5Aexists(f->$group$_group, $GROUP_STR$_NAME) == 0) return TREXIO_HAS_NOT; + + /* Read the $group_str$ attribute of $group$ group */ + const hid_t str_id = H5Aopen(f->$group$_group, $GROUP_STR$_NAME, H5P_DEFAULT); + if (str_id <= 0) return TREXIO_INVALID_ID; + + const hid_t ftype_id = H5Aget_type(str_id); + if (ftype_id <= 0) return TREXIO_INVALID_ID; + uint64_t sdim = H5Tget_size(ftype_id); + if (sdim <= 0) return TREXIO_FAILURE; + sdim++; /* Make room for null terminator */ + + const hid_t mem_id = H5Tcopy(H5T_C_S1); + if (mem_id <= 0) return TREXIO_INVALID_ID; + + herr_t status; + status = H5Tset_size(mem_id, sdim); + if (status < 0) return TREXIO_FAILURE; + + status = H5Aread(str_id, mem_id, str); + if (status < 0) return TREXIO_FAILURE; + + H5Aclose(str_id); + H5Tclose(mem_id); + H5Tclose(ftype_id); + + return TREXIO_SUCCESS; + +} + #+end_src + + + #+begin_src c :tangle write_attr_str_hdf5.c +trexio_exit_code +trexio_hdf5_write_$group_str$ (trexio_t* const file, const char* str) +{ + + if (file == NULL) return TREXIO_INVALID_ARG_1; + if (str == NULL) return TREXIO_INVALID_ARG_2; + + trexio_hdf5_t* const f = (trexio_hdf5_t*) file; + + + /* Setup the dataspace */ + const hid_t dtype_id = H5Tcopy(H5T_C_S1); + if (dtype_id <= 0) return TREXIO_INVALID_ID; + + size_t str_attr_len = strlen(str) + 1; + + herr_t status; + status = H5Tset_size(dtype_id, str_attr_len); + if (status < 0) return TREXIO_FAILURE; + + status = H5Tset_strpad(dtype_id, H5T_STR_NULLTERM); + if (status < 0) return TREXIO_FAILURE; + + const hid_t dspace_id = H5Screate(H5S_SCALAR); + if (dspace_id <= 0) return TREXIO_INVALID_ID; + + /* Create the $group_str$ attribute of $group$ group */ + const hid_t str_id = H5Acreate(f->$group$_group, $GROUP_STR$_NAME, dtype_id, dspace_id, + H5P_DEFAULT, H5P_DEFAULT); + + if (str_id <= 0) { + H5Sclose(dspace_id); + H5Tclose(dtype_id); + return TREXIO_INVALID_ID; + } + + status = H5Awrite(str_id, dtype_id, str); + if (status < 0) { + H5Aclose(str_id); + H5Sclose(dspace_id); + H5Tclose(dtype_id); + return TREXIO_FAILURE; + } + + H5Aclose(str_id); + H5Sclose(dspace_id); + H5Tclose(dtype_id); + return TREXIO_SUCCESS; + +} + #+end_src + + #+begin_src c :tangle has_attr_str_hdf5.c +trexio_exit_code +trexio_hdf5_has_$group_str$ (trexio_t* const file) +{ + + if (file == NULL) return TREXIO_INVALID_ARG_1; + + const trexio_hdf5_t* f = (const trexio_hdf5_t*) file; + + htri_t status = H5Aexists(f->$group$_group, $GROUP_STR$_NAME); + /* H5Aexists returns positive value if attribute exists, 0 if does not, negative if error */ + if (status > 0){ + return TREXIO_SUCCESS; + } else if (status == 0) { + return TREXIO_HAS_NOT; + } else { + return TREXIO_FAILURE; + } + +} + #+end_src * Constant file suffixes (not used by the generator) :noexport: #+begin_src c :tangle suffix_hdf5.h