1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-12-23 12:56:53 +01:00

introduce max_str_len parameter

This commit is contained in:
q-posev 2021-06-03 16:13:11 +02:00
parent 313ab12c61
commit 40e9aa9234
2 changed files with 107 additions and 41 deletions

View File

@ -142,6 +142,7 @@ typedef int32_t trexio_exit_code;
| ~TREXIO_GROUP_WRITE_ERROR~ | 19 | 'Error writing group' | | ~TREXIO_GROUP_WRITE_ERROR~ | 19 | 'Error writing group' |
| ~TREXIO_ELEM_READ_ERROR~ | 20 | 'Error reading element' | | ~TREXIO_ELEM_READ_ERROR~ | 20 | 'Error reading element' |
| ~TREXIO_ELEM_WRITE_ERROR~ | 21 | 'Error writing element' | | ~TREXIO_ELEM_WRITE_ERROR~ | 21 | 'Error writing element' |
| ~TREXIO_INVALID_STR_LEN~ | 30 | 'Invalid max_str_len' |
# We need to force Emacs not to indent the Python code: # We need to force Emacs not to indent the Python code:
# -*- org-src-preserve-indentation: t # -*- org-src-preserve-indentation: t
@ -172,7 +173,7 @@ return '\n'.join(result)
#+RESULTS: #+RESULTS:
:results: :results:
#+begin_src c :tangle prefix_front.h :exports none #+begin_src c :tangle prefix_front.h
#define TREXIO_FAILURE ((trexio_exit_code) -1) #define TREXIO_FAILURE ((trexio_exit_code) -1)
#define TREXIO_SUCCESS ((trexio_exit_code) 0) #define TREXIO_SUCCESS ((trexio_exit_code) 0)
#define TREXIO_INVALID_ARG_1 ((trexio_exit_code) 1) #define TREXIO_INVALID_ARG_1 ((trexio_exit_code) 1)
@ -196,9 +197,10 @@ return '\n'.join(result)
#define TREXIO_GROUP_WRITE_ERROR ((trexio_exit_code) 19) #define TREXIO_GROUP_WRITE_ERROR ((trexio_exit_code) 19)
#define TREXIO_ELEM_READ_ERROR ((trexio_exit_code) 20) #define TREXIO_ELEM_READ_ERROR ((trexio_exit_code) 20)
#define TREXIO_ELEM_WRITE_ERROR ((trexio_exit_code) 21) #define TREXIO_ELEM_WRITE_ERROR ((trexio_exit_code) 21)
#define TREXIO_INVALID_STR_LEN ((trexio_exit_code) 30)
#+end_src #+end_src
#+begin_src f90 :tangle prefix_fortran.f90 :exports none #+begin_src f90 :tangle prefix_fortran.f90
integer(trexio_exit_code), parameter :: TREXIO_FAILURE = -1 integer(trexio_exit_code), parameter :: TREXIO_FAILURE = -1
integer(trexio_exit_code), parameter :: TREXIO_SUCCESS = 0 integer(trexio_exit_code), parameter :: TREXIO_SUCCESS = 0
integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_1 = 1 integer(trexio_exit_code), parameter :: TREXIO_INVALID_ARG_1 = 1
@ -222,6 +224,7 @@ return '\n'.join(result)
integer(trexio_exit_code), parameter :: TREXIO_GROUP_WRITE_ERROR = 19 integer(trexio_exit_code), parameter :: TREXIO_GROUP_WRITE_ERROR = 19
integer(trexio_exit_code), parameter :: TREXIO_ELEM_READ_ERROR = 20 integer(trexio_exit_code), parameter :: TREXIO_ELEM_READ_ERROR = 20
integer(trexio_exit_code), parameter :: TREXIO_ELEM_WRITE_ERROR = 21 integer(trexio_exit_code), parameter :: TREXIO_ELEM_WRITE_ERROR = 21
integer(trexio_exit_code), parameter :: TREXIO_INVALID_STR_LEN = 30
#+end_src #+end_src
:end: :end:
@ -1425,17 +1428,18 @@ end interface
#+begin_src c :tangle hrw_dset_str_front.h :exports none #+begin_src c :tangle hrw_dset_str_front.h :exports none
trexio_exit_code trexio_has_$group_dset$(trexio_t* const file); trexio_exit_code trexio_has_$group_dset$(trexio_t* const file);
trexio_exit_code trexio_read_$group_dset$(trexio_t* const file, char* const dset); trexio_exit_code trexio_read_$group_dset$(trexio_t* const file, char* const dset, const uint32_t max_str_len);
trexio_exit_code trexio_write_$group_dset$(trexio_t* const file, const char* dset); trexio_exit_code trexio_write_$group_dset$(trexio_t* const file, const char* dset, const uint32_t max_str_len);
#+end_src #+end_src
#+begin_src c :tangle read_dset_str_front.c #+begin_src c :tangle read_dset_str_front.c
trexio_exit_code trexio_exit_code
trexio_read_$group_dset$ (trexio_t* const file, char* const dset) trexio_read_$group_dset$ (trexio_t* const file, char* const dset, const uint32_t max_str_len)
{ {
if (file == NULL) return TREXIO_INVALID_ARG_1; if (file == NULL) return TREXIO_INVALID_ARG_1;
if (dset == NULL) return TREXIO_INVALID_ARG_2; if (dset == NULL) return TREXIO_INVALID_ARG_2;
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
trexio_exit_code rc; trexio_exit_code rc;
int64_t $group_dset_dim$ = 0; int64_t $group_dset_dim$ = 0;
@ -1457,7 +1461,7 @@ trexio_read_$group_dset$ (trexio_t* const file, char* const dset)
break; break;
case TREXIO_HDF5: case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_dset$(file, dset, rank, dims); rc = trexio_hdf5_read_$group_dset$(file, dset, rank, dims, max_str_len);
break; break;
/* /*
case TREXIO_JSON: case TREXIO_JSON:
@ -1473,11 +1477,12 @@ trexio_read_$group_dset$ (trexio_t* const file, char* const dset)
#+begin_src c :tangle write_dset_str_front.c #+begin_src c :tangle write_dset_str_front.c
trexio_exit_code trexio_exit_code
trexio_write_$group_dset$ (trexio_t* const file, const char* dset) trexio_write_$group_dset$ (trexio_t* const file, const char* dset, const uint32_t max_str_len)
{ {
if (file == NULL) return TREXIO_INVALID_ARG_1; if (file == NULL) return TREXIO_INVALID_ARG_1;
if (dset == NULL) return TREXIO_INVALID_ARG_2; if (dset == NULL) return TREXIO_INVALID_ARG_2;
if (max_str_len <= 0) return TREXIO_INVALID_ARG_3;
trexio_exit_code rc; trexio_exit_code rc;
int64_t $group_dset_dim$ = 0; int64_t $group_dset_dim$ = 0;
@ -1492,30 +1497,45 @@ trexio_write_$group_dset$ (trexio_t* const file, const char* dset)
assert(file->back_end < TREXIO_INVALID_BACK_END); assert(file->back_end < TREXIO_INVALID_BACK_END);
char* tmp_str = CALLOC(dims[0]*(max_str_len+1), char);
if (tmp_str == NULL) return TREXIO_ALLOCATION_FAILED;
char** dset_str = CALLOC(dims[0], char*); char** dset_str = CALLOC(dims[0], char*);
char* tmp_str = CALLOC(dims[0]*32, char); if (dset_str == NULL) return TREXIO_ALLOCATION_FAILED;
char* pch; char* pch;
pch = strtok( (char*) dset, TREXIO_DELIM);
size_t pch_len; size_t pch_len;
pch_len = strlen(pch); /* parse the string using strtok */
dset_str[0]=tmp_str; for(uint64_t i=0; i<dims[0]; i++) {
strncpy(tmp_str, pch, pch_len);
tmp_str += pch_len + 1; if(i==0) {
for(size_t i=1; i<dims[0]; i++){ pch = strtok( (char*) dset, TREXIO_DELIM);
} else {
pch = strtok(NULL, TREXIO_DELIM); pch = strtok(NULL, TREXIO_DELIM);
}
if (pch == NULL) {
FREE(dset_str[0]);
FREE(dset_str);
return TREXIO_FAILURE;
}
pch_len = strlen(pch); pch_len = strlen(pch);
if (pch_len > max_str_len) {
FREE(dset_str[0]);
FREE(dset_str);
return TREXIO_INVALID_STR_LEN;
}
dset_str[i]=tmp_str; dset_str[i]=tmp_str;
strncpy(tmp_str, pch, pch_len); strncpy(tmp_str, pch, max_str_len);
tmp_str += pch_len + 1; tmp_str += max_str_len + 1;
} }
switch (file->back_end) { switch (file->back_end) {
case TREXIO_TEXT: case TREXIO_TEXT:
//return trexio_text_write_$group_dset$(file, dset, rank, dims); //rc = trexio_text_write_$group_dset$(file, dset, rank, dims);
break; break;
case TREXIO_HDF5: case TREXIO_HDF5:
@ -1523,7 +1543,7 @@ trexio_write_$group_dset$ (trexio_t* const file, const char* dset)
break; break;
/* /*
case TREXIO_JSON: case TREXIO_JSON:
return trexio_json_write_$group_dset$(file, dset, rank, dims); rc = trexio_json_write_$group_dset$(file, dset, rank, dims);
break; break;
,*/ ,*/
} }
@ -1571,20 +1591,22 @@ trexio_has_$group_dset$ (trexio_t* const file)
#+begin_src f90 :tangle write_dset_str_front_fortran.f90 #+begin_src f90 :tangle write_dset_str_front_fortran.f90
interface interface
integer function trexio_write_$group_dset$ (trex_file, dset) bind(C) integer function trexio_write_$group_dset$ (trex_file, dset, max_str_len) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file integer(8), intent(in), value :: trex_file
character, intent(in) :: dset(*) character, intent(in) :: dset(*)
integer(4), intent(in) :: max_str_len
end function trexio_write_$group_dset$ end function trexio_write_$group_dset$
end interface end interface
#+end_src #+end_src
#+begin_src f90 :tangle read_dset_str_front_fortran.f90 #+begin_src f90 :tangle read_dset_str_front_fortran.f90
interface interface
integer function trexio_read_$group_dset$ (trex_file, dset) bind(C) integer function trexio_read_$group_dset$ (trex_file, dset, max_str_len) bind(C)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
integer(8), intent(in), value :: trex_file integer(8), intent(in), value :: trex_file
character, intent(out) :: dset(*) character, intent(out) :: dset(*)
integer(4), intent(in) :: max_str_len
end function trexio_read_$group_dset$ end function trexio_read_$group_dset$
end interface end interface
#+end_src #+end_src

View File

@ -319,17 +319,17 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $
H5Dclose(dset_id); H5Dclose(dset_id);
if (status < 0) { if (status < 0) {
free(ddims); FREE(ddims);
return TREXIO_FAILURE; return TREXIO_FAILURE;
} }
for (uint32_t i=0; i<rank; ++i){ for (uint32_t i=0; i<rank; ++i){
if (ddims[i] != dims[i]) { if (ddims[i] != dims[i]) {
free(ddims); FREE(ddims);
return TREXIO_INVALID_ARG_4; return TREXIO_INVALID_ARG_4;
} }
} }
free(ddims); FREE(ddims);
/* High-level H5LT API. No need to deal with dataspaces and datatypes */ /* High-level H5LT API. No need to deal with dataspaces and datatypes */
status = H5LTread_dataset(f->$group$_group, status = H5LTread_dataset(f->$group$_group,
@ -413,13 +413,13 @@ trexio_hdf5_has_$group_dset$ (trexio_t* const file)
#+begin_src c :tangle hrw_dset_str_hdf5.h :exports none #+begin_src c :tangle hrw_dset_str_hdf5.h :exports none
trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file); trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file);
trexio_exit_code trexio_hdf5_read_$group_dset$(trexio_t* const file, char* const $group_dset$, const uint32_t rank, const uint64_t* dims); trexio_exit_code trexio_hdf5_read_$group_dset$(trexio_t* const file, char* const $group_dset$, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len);
trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file, const char** $group_dset$, const uint32_t rank, const uint64_t* dims); trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file, const char** $group_dset$, const uint32_t rank, const uint64_t* dims);
#+end_src #+end_src
#+begin_src c :tangle read_dset_str_hdf5.c #+begin_src c :tangle read_dset_str_hdf5.c
trexio_exit_code trexio_exit_code
trexio_hdf5_read_$group_dset$ (trexio_t* const file, char* const $group_dset$, const uint32_t rank, const uint64_t* dims) trexio_hdf5_read_$group_dset$ (trexio_t* const file, char* const $group_dset$, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len)
{ {
if (file == NULL) return TREXIO_INVALID_ARG_1; if (file == NULL) return TREXIO_INVALID_ARG_1;
@ -433,40 +433,78 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file, char* const $group_dset$, c
hid_t dset_id = H5Dopen(f->$group$_group, $GROUP_DSET$_NAME, H5P_DEFAULT); hid_t dset_id = H5Dopen(f->$group$_group, $GROUP_DSET$_NAME, H5P_DEFAULT);
if (dset_id <= 0) return TREXIO_INVALID_ID; if (dset_id <= 0) return TREXIO_INVALID_ID;
hid_t dspace = H5Dget_space(dset_id);
int rrank;
// allocate space for the dimensions to be read // allocate space for the dimensions to be read
hsize_t* ddims = CALLOC( (int) rank, hsize_t); hsize_t* ddims = CALLOC( (int) rank, hsize_t);
if (ddims == NULL) return TREXIO_FAILURE; if (ddims == NULL) {
H5Dclose(dset_id);
return TREXIO_ALLOCATION_FAILED;
}
hid_t dspace = H5Dget_space(dset_id);
if (dset_id <= 0) {
FREE(ddims);
H5Dclose(dset_id);
return TREXIO_INVALID_ID;
}
// get the rank of the dataset in a file // get the rank of the dataset in a file
rrank = H5Sget_simple_extent_dims(dspace, ddims, NULL); int rrank = H5Sget_simple_extent_dims(dspace, ddims, NULL);
if (rrank != (int) rank) return TREXIO_INVALID_ARG_3; if (rrank != (int) rank) {
FREE(ddims);
H5Dclose(dset_id);
H5Sclose(dspace);
return TREXIO_INVALID_ARG_3;
}
for (int i=0; i<rrank; i++) { for (int i=0; i<rrank; i++) {
if (ddims[i] != dims[i]) { if (ddims[i] != dims[i]) {
free(ddims); H5Dclose(dset_id);
H5Sclose(dspace);
FREE(ddims);
return TREXIO_INVALID_ARG_4; return TREXIO_INVALID_ARG_4;
} }
} }
free(ddims); FREE(ddims);
hid_t memtype = H5Tcopy (H5T_C_S1); hid_t memtype = H5Tcopy (H5T_C_S1);
status = H5Tset_size(memtype, H5T_VARIABLE); status = H5Tset_size(memtype, H5T_VARIABLE);
if (status < 0) return TREXIO_FAILURE; if (status < 0 || memtype <= 0) {
H5Dclose(dset_id);
H5Sclose(dspace);
return TREXIO_FAILURE;
}
char** rdata = CALLOC(dims[0], char*); char** rdata = CALLOC(dims[0], char*);
if (rdata == NULL) return TREXIO_ALLOCATION_FAILED; if (rdata == NULL) {
H5Dclose(dset_id);
H5Sclose(dspace);
H5Tclose(memtype);
return TREXIO_ALLOCATION_FAILED;
}
status = H5Dread(dset_id, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); status = H5Dread(dset_id, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
if (status < 0) return TREXIO_FAILURE; if (status < 0) {
FREE(rdata);
H5Dclose(dset_id);
H5Sclose(dspace);
H5Tclose(memtype);
return TREXIO_FAILURE;
}
// copy contents of temporary rdata buffer into the group_dset otherwise they are lost // copy contents of temporary rdata buffer into the group_dset otherwise they are lost
// after calling H5Treclaim or H5Dvlen_reclaim functions // after calling H5Treclaim or H5Dvlen_reclaim functions
strcpy($group_dset$, ""); strcpy($group_dset$, "");
for (uint64_t i=0; i<dims[0]; i++){ for (uint64_t i=0; i<dims[0]; i++){
if (strlen(rdata[i]) > max_str_len) {
FREE(rdata);
H5Dclose(dset_id);
H5Sclose(dspace);
H5Tclose(memtype);
return TREXIO_INVALID_STR_LEN;
}
strcat($group_dset$, rdata[i]); strcat($group_dset$, rdata[i]);
strcat($group_dset$, TREXIO_DELIM); strcat($group_dset$, TREXIO_DELIM);
} }
@ -475,9 +513,15 @@ trexio_hdf5_read_$group_dset$ (trexio_t* const file, char* const $group_dset$, c
//status = H5Treclaim (memtype, dspace, H5P_DEFAULT, rdata); //status = H5Treclaim (memtype, dspace, H5P_DEFAULT, rdata);
// this function is deprecated but used in v.<1.12.0 // this function is deprecated but used in v.<1.12.0
status = H5Dvlen_reclaim (memtype, dspace, H5P_DEFAULT, rdata); status = H5Dvlen_reclaim (memtype, dspace, H5P_DEFAULT, rdata);
if (status < 0) return TREXIO_FAILURE; if (status < 0) {
FREE(rdata);
H5Dclose(dset_id);
H5Sclose(dspace);
H5Tclose(memtype);
return TREXIO_FAILURE;
}
if (rdata != NULL) FREE(rdata); FREE(rdata);
H5Dclose(dset_id); H5Dclose(dset_id);
H5Sclose(dspace); H5Sclose(dspace);
H5Tclose(memtype); H5Tclose(memtype);