1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2025-01-03 10:06:01 +01:00

[WIP] add has/read/write functions for string attributes [front,hdf5]

This commit is contained in:
q-posev 2021-06-04 15:33:50 +02:00
parent f1f47f4369
commit 5b1cf03aaf
2 changed files with 281 additions and 42 deletions

View File

@ -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; i<str_max_num; i++){
dest[i] = tmp_str;
strncpy(tmp_str, src[i], str_max_len);
tmp_str += str_max_len + 1;
}
/*tmp_str cannot be freed here but it is taken case of when pointer to dest is deallocated */
return TREXIO_SUCCESS;
}
#+end_src
* Templates for front end
** Description
@ -779,7 +756,7 @@ trexio_exit_code transform_str (char** dest, const char** src, uint64_t str_max_
*read* and *write* functionality. TREXIO supports I/O with single
or double precision for integer and floating point numbers.
** Templates for front end has/read/write a dimension
** Templates for front end has/read/write a single dimensioning variable
This section concerns API calls related to dimensioning variables.
@ -854,26 +831,23 @@ trexio_write_$group_num$_64 (trexio_t* const file, const int64_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
@ -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.

View File

@ -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;
@ -624,6 +628,131 @@ 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