Skip to content

Commit 39d01a0

Browse files
committed
setAttribute: Reject Empty Strings (openPMD#1087)
* setAttribute: Reject Empty Strings Some backends, especially HDF5, do not allow us to define zero-sized strings. We thus need to catch this in the frontend and forward the restriction to the user. * Test: setAttribute("key", "") throws * setAttribute Check: C++14 compatible
1 parent 34f04c1 commit 39d01a0

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

include/openPMD/backend/Attributable.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <vector>
3232
#include <string>
3333
#include <cstddef>
34+
#include <type_traits>
3435

3536
// expose private and protected members for invasive testing
3637
#ifndef OPENPMD_protected
@@ -83,8 +84,29 @@ class AttributableData
8384
private:
8485
A_MAP m_attributes;
8586
};
87+
88+
/** Verify values of attributes in the frontend
89+
*
90+
* verify string attributes are not empty (backend restriction, e.g., HDF5)
91+
*/
92+
template< typename T >
93+
inline void
94+
attr_value_check( std::string const /* key */, T /* value */ )
95+
{
8696
}
8797

98+
template< >
99+
inline void
100+
attr_value_check( std::string const key, std::string const value )
101+
{
102+
if( value.empty() )
103+
throw std::runtime_error(
104+
"[setAttribute] Value for string attribute '" + key +
105+
"' must not be empty!" );
106+
}
107+
108+
} // namespace internal
109+
88110
/** @brief Layer to manage storage of attributes associated with file objects.
89111
*
90112
* Mandatory and user-defined Attributes and their data for every object in the
@@ -394,6 +416,8 @@ template< typename T >
394416
inline bool
395417
AttributableInterface::setAttribute( std::string const & key, T value )
396418
{
419+
internal::attr_value_check( key, value );
420+
397421
auto & attri = get();
398422
if(IOHandler() && Access::READ_ONLY == IOHandler()->m_frontendAccess )
399423
{
@@ -420,6 +444,7 @@ AttributableInterface::setAttribute( std::string const & key, T value )
420444
return false;
421445
}
422446
}
447+
423448
inline bool
424449
AttributableInterface::setAttribute( std::string const & key, char const value[] )
425450
{

test/ParallelIOTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# include <fstream>
1414
# include <iostream>
1515
# include <algorithm>
16+
# include <stdexcept>
1617
# include <string>
1718
# include <vector>
1819
# include <list>
@@ -226,6 +227,7 @@ TEST_CASE( "hdf5_write_test", "[parallel][hdf5]" )
226227
auto mpi_rank = static_cast<uint64_t>(mpi_r);
227228
Series o = Series("../samples/parallel_write.h5", Access::CREATE, MPI_COMM_WORLD);
228229

230+
REQUIRE_THROWS_AS(o.setAuthor(""), std::runtime_error);
229231
o.setAuthor("Parallel HDF5");
230232
ParticleSpecies& e = o.iterations[1].particles["e"];
231233

test/SerialIOTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <list>
2525
#include <memory>
2626
#include <numeric>
27+
#include <stdexcept>
2728
#include <sstream>
2829
#include <string>
2930
#include <tuple>
@@ -1785,6 +1786,7 @@ void bool_test(const std::string & backend)
17851786
{
17861787
Series o = Series("../samples/serial_bool." + backend, Access::CREATE);
17871788

1789+
REQUIRE_THROWS_AS(o.setAuthor(""), std::runtime_error);
17881790
o.setAttribute("Bool attribute (true)", true);
17891791
o.setAttribute("Bool attribute (false)", false);
17901792
}

0 commit comments

Comments
 (0)