diff --git a/include/openmc/hdf5_interface.h b/include/openmc/hdf5_interface.h index f0b3a245c7..fa64605513 100644 --- a/include/openmc/hdf5_interface.h +++ b/include/openmc/hdf5_interface.h @@ -1,9 +1,11 @@ #ifndef OPENMC_HDF5_INTERFACE_H #define OPENMC_HDF5_INTERFACE_H +#include // for min #include #include #include +#include // for strlen #include #include #include @@ -193,13 +195,13 @@ read_attribute(hid_t obj_id, const char* name, std::vector& vec) // Allocate a C char array to get strings auto n = attribute_typesize(obj_id, name); - char buffer[m][n+1]; + char buffer[m][n]; // Read char data in attribute read_attr_string(obj_id, name, n, buffer[0]); for (int i = 0; i < m; ++i) { - vec.emplace_back(&buffer[i][0]); + vec.emplace_back(&buffer[i][0], std::min(strlen(buffer[i]), n)); } } diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 0c7bdb92d5..8872a84f6a 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -1131,6 +1131,7 @@ contains do i = 0, dims(1) - 1 n = len_trim(buffer(i+1)) + 1 buffer_(i*m+1 : i*m+n) = to_c_string(buffer(i+1)) + if (n < m) buffer_(i*m+n : i*m+m) = C_NULL_CHAR end do call write_string_c(group_id, 1, dims, m, to_c_string(name), & @@ -1361,7 +1362,7 @@ contains ! Allocate a C char array to get strings n = attribute_typesize(obj_id, to_c_string(name)) m = size(buffer) - allocate(buffer_((n+1)*m)) + allocate(buffer_(n*m)) ! Read attribute call read_attr_string_c(obj_id, to_c_string(name), n, buffer_) @@ -1370,7 +1371,7 @@ contains do i = 1, m buffer(i) = '' do j = 1, n - k = (i-1)*(n+1) + j + k = (i-1)*n + j if (buffer_(k) == C_NULL_CHAR) exit buffer(i)(j:j) = buffer_(k) end do diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index cecf283ac1..d72f7d424d 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -392,7 +392,7 @@ object_name(hid_t obj_id) // Read and return name H5Iget_name(obj_id, buffer, size); - return {buffer, size}; + return buffer; } @@ -439,7 +439,9 @@ read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer) { // Create datatype for a string hid_t datatype = H5Tcopy(H5T_C_S1); - H5Tset_size(datatype, slen + 1); + H5Tset_size(datatype, slen); + // numpy uses null-padding when writing fixed-length strings + H5Tset_strpad(datatype, H5T_STR_NULLPAD); // Read data into buffer read_attr(obj_id, name, datatype, buffer); @@ -503,7 +505,9 @@ read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool inde { // Create datatype for a string hid_t datatype = H5Tcopy(H5T_C_S1); - H5Tset_size(datatype, slen + 1); + H5Tset_size(datatype, slen); + // numpy uses null-padding when writing fixed-length strings + H5Tset_strpad(datatype, H5T_STR_NULLPAD); // Read data into buffer read_dataset(obj_id, name, datatype, buffer, indep); diff --git a/src/initialize.cpp b/src/initialize.cpp index 19fc82c859..0c26135dc9 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -115,10 +115,9 @@ parse_command_line(int argc, char* argv[]) // Check what type of file this is hid_t file_id = file_open(argv[i], 'r', true); - size_t len = attribute_typesize(file_id, "filetype"); - read_attr_string(file_id, "filetype", len, buffer); + std::string filetype; + read_attribute(file_id, "filetype", filetype); file_close(file_id); - std::string filetype {buffer}; // Set path and flag for type of run if (filetype == "statepoint") { @@ -141,8 +140,7 @@ parse_command_line(int argc, char* argv[]) // Check file type is a source file file_id = file_open(argv[i+1], 'r', true); - len = attribute_typesize(file_id, "filetype"); - read_attr_string(file_id, "filetype", len, buffer); + read_attribute(file_id, "filetype", filetype); file_close(file_id); if (filetype != "source") { std::string msg {"Second file after restart flag must be a source file"}; diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 56f3392ff2..0bb464da07 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -208,7 +208,7 @@ void get_name_c(int index, int name_len, char* name) { // First blank out our input string - std::string str(name_len, ' '); + std::string str(name_len - 1, ' '); std::strcpy(name, str.c_str()); // Now get the data and copy to the C-string