Skip to content

Commit

Permalink
libcore|String: Added printf-style formatting, utility methods
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Mar 20, 2016
1 parent 9c83fd3 commit ada6b6c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
23 changes: 23 additions & 0 deletions doomsday/sdk/libcore/include/de/data/string.h
Expand Up @@ -284,6 +284,20 @@ class DENG2_PUBLIC String : public QString
*/
dint toInt(bool *ok = 0, int base = 10, IntConversionFlags flags = AllowOnlyWhitespace) const;

/**
* Adds a prefix to each line in the text.
*
* @param prefix Prefix text.
*
* @return Prefixed text.
*/
String addLinePrefix(String const &prefix) const;

/**
* Prefixes double quotes and backslashes with a backslash.
*/
String escaped() const;

public:
/**
* Builds a String out of an array of bytes that contains a UTF-8 string.
Expand Down Expand Up @@ -321,6 +335,15 @@ class DENG2_PUBLIC String : public QString
*/
static void skipSpace(String::const_iterator &i, String::const_iterator const &end);

/**
* Formats a string using standard printf() formatting. Uses UTF-8 encoding.
*
* @param format Format string.
*
* @return Formatted output..
*/
static String format(String format, ...);

/**
* Formats data according to formatting instructions. Outputs a
* string containing the formatted data.
Expand Down
52 changes: 52 additions & 0 deletions doomsday/sdk/libcore/src/data/string.cpp
Expand Up @@ -23,6 +23,8 @@

#include <QDir>
#include <QTextStream>
#include <cstdio>
#include <cstdarg>

using namespace de;

Expand Down Expand Up @@ -462,6 +464,38 @@ void String::skipSpace(String::const_iterator &i, String::const_iterator const &
while(i != end && (*i).isSpace()) ++i;
}

String String::format(String format, ...)
{
va_list args;
Block buffer;
int neededSize = 1024;

forever
{
buffer.resize(neededSize);

va_start(args, format);
int count = vsnprintf((char *) buffer.data(), buffer.size(), format.toUtf8(), args);
va_end(args);

if(count >= 0 && count < neededSize)
{
buffer.resize(count);
return fromUtf8(buffer);
}

if(count >= 0)
{
neededSize = count + 1;
}
else
{
neededSize *= 2; // Try bigger.
}
}
return fromUtf8(buffer);
}

// Seems like an ommission on the part of QChar...
static inline bool isSign(QChar const &ch)
{
Expand Down Expand Up @@ -489,6 +523,24 @@ dint String::toInt(bool *ok, int base, IntConversionFlags flags) const
return token.QString::toInt(ok, base);
}

String String::addLinePrefix(String const &prefix) const
{
String result;
for(auto const &str : QString::split(QChar('\n')))
{
if(!result.isEmpty()) result += "\n";
result += prefix + str;
}
return result;
}

String String::escaped() const
{
String esc = *this;
esc.replace("\\", "\\\\").replace("\"", "\\\"");
return esc;
}

void String::advanceFormat(String::const_iterator &i, String::const_iterator const &end)
{
++i;
Expand Down

0 comments on commit ada6b6c

Please sign in to comment.