Skip to content
Snippets Groups Projects
Commit 92031b05 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

[utility] Add function for printf-like formating

This basically wraps the raw snprintf in order to provide
overflow-save printf functionality while hiding the details
like buffers handling, multiple calls to snprintf, ...

Note that snprintf is a c++11 feature that is, however,
present in gcc-4.4.
parent ec2b55cc
No related branches found
No related tags found
No related merge requests found
......@@ -10,6 +10,14 @@
#include <cstddef>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <memory>
#include <string>
#include <new>
#include <dune/common/exceptions.hh>
namespace Dune {
......@@ -48,8 +56,59 @@ namespace Dune {
return std::equal(suffix, suffix+len, it);
}
/**
* \brief Format values according to printf format string
*
* \param s The format string to be used
* \param args The valued to be formated
*
* This is a wrapper to std::snprintf that provides
* overflow save printf functionality. For up to 1000
* characters a static buffer is used. If this is not sufficient
* a dynamic buffer of appropriate size is allocated.
*/
template<class... T>
static std::string formatString(const std::string& s, const T&... args)
{
static const int bufferSize=1000;
static char buffer[bufferSize];
// try to format with static buffer
int r = std::snprintf(buffer, bufferSize, s.c_str(), args...);
// negative return values correspond to errors
if (r<0)
DUNE_THROW(Dune::Exception,"Could not convert format string using given arguments.");
// if buffer was large enough return result as string
if (r<bufferSize)
return std::string(buffer);
// if buffer was to small allocate a larger buffer using
// the predicted size hint (+1 for the terminating 0-byte).
int dynamicBufferSize = r+1;
std::unique_ptr<char[]> dynamicBuffer;
try {
dynamicBuffer = std::unique_ptr<char[]>(new char[dynamicBufferSize]());
// dynamicBuffer = Dune::Std::make_unique<char[]>(dynamicBufferSize);
}
catch (const std::bad_alloc&) {
DUNE_THROW(Dune::Exception,"Could allocate large enough dynamic buffer in formatString.");
}
// convert and check for errors again
r = std::snprintf(dynamicBuffer.get(), dynamicBufferSize, s.c_str(), args...);
if (r<0)
DUNE_THROW(Dune::Exception,"Could not convert format string using given arguments.");
// the new buffer should always be large enough
assert(r<dynamicBufferSize);
return std::string(dynamicBuffer.get());
}
/** @} */
}
#endif // DUNE_COMMON_STRINGUTILITY_HH
\ No newline at end of file
#endif // DUNE_COMMON_STRINGUTILITY_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment