Skip to content

Commit

Permalink
Plugins: Common String Helpers (Splash)
Browse files Browse the repository at this point in the history
Adds ArrayOfString helpers for libSplash write calls.
See
  ComputationalRadiationPhysics/libSplash#220
for the description of the problem.

If a user wants to write an array of strings they need to be padded
to the longest one. This helper does that.

Use it like this:
```C++
 #include "plugins/common/stringHelpers.hpp"
// [...]

// create some strings
std::list<std::string> myListOfStr;
myListOfStr.push_back("short");
myListOfStr.push_back("middle");
myListOfStr.push_back("loooong");

// convert to splash format
helper::GetSplashArrayOfString getSplashArrayOfString;
helper::GetSplashArrayOfString::Result myArrOfStr;
myArrOfStr = getSplashArrayOfString( myListOfStr );

// splash calls
dc->writeGlobalAttribute(
    threadParams->currentStep,
    myArrOfStr.colType,
    "someListOfStr",
    1u, /* ndims: 1D array */
    Dimensions(myListOfStr.size(),0,0), /* size of 1D array */
    &(myArrOfStr.buffers.at(0))
);
```

Also adds a `helper::` namespace to avoid polluting the `PIConGPU`
namespace.
  • Loading branch information
ax3l committed Jan 8, 2016
1 parent abffb22 commit f97789b
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions src/picongpu/include/plugins/common/stringHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@
#include <string>
#include <sstream>
#include <ctime>
// libSplash
#if(ENABLE_HDF5 == 1)
# include <splash/splash.h>
# include <list>
# include <algorithm>
#endif


namespace picongpu
{
namespace helper
{
/** Return the current date as string
*
Expand All @@ -50,4 +58,86 @@ namespace picongpu
return dateString.str();
}

#if(ENABLE_HDF5 == 1)
/** Create c-strings suitable for libSplash
*
* Convert a std::list of strings to a format that is suitable to
* be written into libSplash attributes (\0-concated and padded
* array of constant c-strings).
* Each string will be padded to the length of the longest string.
*
* Independent of the padding you chose, the final strings will be '\0'
* terminated.
*/
class GetSplashArrayOfString
{
private:
// compare two std::string by their size
struct CompStrBySize
{
bool operator()( std::string i, std::string j)
{
return i.size() < j.size();
}
};

public:
// resulting type containing all attributes for a libSplash write call
struct Result
{
splash::ColTypeString colType;
std::vector<char*> listIndex;
std::vector<char> buffers; // all of same length
};

Result operator()(
std::list<std::string> listOfStrings,
char padding = '\0'
)
{
// find length of longest string in list
CompStrBySize compStrBySize;
std::string longestString = *std::max_element(
listOfStrings.begin(),
listOfStrings.end(),
compStrBySize
);
size_t lenMax = longestString.size();

// create libSplash data type suitable for longest string
Result result;
result.colType = splash::ColTypeString(lenMax);

// prepare buffer with padding
// size per buffer must include terminator \0 !
const size_t bytesPerEntry = lenMax + 1;
const size_t lenAllBuffers = listOfStrings.size() * bytesPerEntry;
result.buffers.assign( lenAllBuffers, padding );

// copy buffers
std::list<std::string>::iterator listIt = listOfStrings.begin();
for(
size_t i = 0;
i < listOfStrings.size();
++i, ++listIt
)
{
// index points to each part of the buffer individually
const size_t startIdx = i * bytesPerEntry;
char* start = &result.buffers.at( startIdx );
result.listIndex.push_back( start );

// copy byte wise
std::copy( listIt->c_str(), listIt->c_str() + bytesPerEntry, start );
if( padding != '\0' )
result.buffers.at( startIdx + lenMax ) = '\0';
}

// return
return result;
}
};
#endif

} // namespace helper
} // namespace picongpu

0 comments on commit f97789b

Please sign in to comment.