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"
// include <splash/splash.h>
// include <list>
// include <string>

// 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 );
ColTypeString ctSomeListOfStr( myArrOfStr.maxLen );

// splash call
dc->writeGlobalAttribute(
    threadParams->currentStep,
    ctSomeListOfStr,
    "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.
- Declutters the helpers in a `.hpp` + `.cpp` file.
  • Loading branch information
ax3l committed Jan 15, 2016
1 parent c17cbf9 commit 4aedc77
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 14 deletions.
56 changes: 42 additions & 14 deletions src/picongpu/include/plugins/common/stringHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,59 @@
#include <string>
#include <sstream>
#include <ctime>

#include <vector>
#include <list>
#include <algorithm>
#include <iostream>

namespace picongpu
{
namespace helper
{
/** Return the current date as string
*
* \param format, \see http://www.cplusplus.com/reference/ctime/strftime/
* \return std::string with formatted date
*/
std::string getDateString( std::string format )
{
time_t rawtime;
struct tm* timeinfo;
const size_t maxLen = 30;
char buffer [maxLen];
std::string getDateString( std::string format );

time( &rawtime );
timeinfo = localtime( &rawtime );
/** Create array of c-strings suitable for libSplash
*
* Convert a std::list of strings to a format that is suitable to
* be written into libSplash (concated and padded array of constant
* c-strings). Strings will be padded to longest string.
*
* Independent of the padding you chose, the strings will be '\0'
* separated & terminated. \0 padding is default and recommended.
*/
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();
}
};

strftime( buffer, maxLen, format.c_str(), timeinfo );
public:
// resulting type containing all attributes for a libSplash write call
struct Result
{
size_t maxLen; // size of the longest string
std::vector<char> buffers; // all of same length lenMax

std::stringstream dateString;
dateString << buffer;
Result() : maxLen(0)
{}
};

return dateString.str();
}
Result operator()(
std::list<std::string> listOfStrings,
char padding = '\0'
);
};

} // namespace helper
} // namespace picongpu
101 changes: 101 additions & 0 deletions src/picongpu/stringHelpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* Copyright 2015-2016 Axel Huebl
*
* This file is part of PIConGPU.
*
* PIConGPU is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PIConGPU is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PIConGPU.
* If not, see <http://www.gnu.org/licenses/>.
*/

#include "include/plugins/common/stringHelpers.hpp"

namespace picongpu
{
namespace helper
{
/** Return the current date as string
*
* \param format, \see http://www.cplusplus.com/reference/ctime/strftime/
* \return std::string with formatted date
*/
std::string getDateString( std::string format )
{
time_t rawtime;
struct tm* timeinfo;
const size_t maxLen = 30;
char buffer [maxLen];

time( &rawtime );
timeinfo = localtime( &rawtime );

strftime( buffer, maxLen, format.c_str(), timeinfo );

std::stringstream dateString;
dateString << buffer;

return dateString.str();
}

GetSplashArrayOfString::Result
GetSplashArrayOfString::operator()(
std::list<std::string> listOfStrings,
char padding
)
{
Result result;

// find length of longest string in list
CompStrBySize compStrBySize;
std::string longestString = *std::max_element(
listOfStrings.begin(),
listOfStrings.end(),
compStrBySize
);
result.maxLen = longestString.size();

// allocate & prepare buffer with padding
// size per buffer must include terminator \0 !
const size_t bytesPerEntry = result.maxLen + 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;
std::vector<char>::iterator startIt =
result.buffers.begin() + startIdx;

// copy byte wise onto padding
std::copy(
listIt->begin(),
listIt->end(),
startIt
);
if( padding != '\0' )
result.buffers.at( startIdx + result.maxLen ) = '\0';
}

// return
return result;
}

} // namespace helper
} // namespace picongpu

0 comments on commit 4aedc77

Please sign in to comment.