StringFunctions.h#
↰ Parent directory (strings
)
Contains helper functions for std::string manipulation.
Includes#
algorithm
cctype
cstdarg
cstdio
cstring
cwchar
iostream
memory
string
(CompileTimeHash.h)vector
Included By#
Namespaces#
Functions#
Source Code#
#pragma once
#include <memory>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdarg>
#include <cstring>
#include <string>
#include <cstdio>
#include <cctype>
#include <cwchar>
namespace pvr {
namespace strings {
inline std::basic_string<wchar_t> vaFormatString(const wchar_t* const format, va_list argumentList)
{
bool result = true;
#if defined(_WIN32)
size_t newStringSize = (size_t)_vscwprintf(format, argumentList);
#else
va_list argumentListCopy;
va_copy(argumentListCopy, argumentList);
size_t newStringSize = (size_t)vswprintf(0, 0, format, argumentListCopy);
va_end(argumentListCopy);
#endif
// Create a new std::string
std::basic_string<wchar_t> newString;
newString.resize(newStringSize + 1);
{
#ifdef _WIN32
if (static_cast<size_t>(_vsnwprintf_s(const_cast<wchar_t*>(newString.c_str()), newStringSize + 1, newStringSize, format, argumentList)) != newStringSize)
#else
if (static_cast<size_t>(vswprintf(const_cast<wchar_t*>(newString.c_str()), newStringSize + 1, format, argumentList)) != newStringSize)
#endif
{
result = false;
}
}
if (!result) { newString.resize(0); }
return newString;
}
inline std::string createFormatted(const char* const format, ...)
{
// initialize use of the variable argument array
va_list vaArgs;
va_start(vaArgs, format);
// Acquire the size by taking a copy of the variable argument array
va_list vaArgsCopy;
va_copy(vaArgsCopy, vaArgs);
#if defined(_WIN32)
const size_t iLen = (size_t)vsnprintf(nullptr, 0, format, vaArgsCopy);
#else
const size_t iLen = (size_t)std::vsnprintf(nullptr, 0, format, vaArgsCopy);
#endif
va_end(vaArgsCopy);
// return a formatted string without risking memory mismanagement
// and without assuming any compiler or platform specific behavior
std::vector<char> zc(iLen + 1);
#if defined(_WIN32)
vsnprintf(zc.data(), zc.size(), format, vaArgs);
#else
std::vsnprintf(zc.data(), zc.size(), format, vaArgs);
#endif
va_end(vaArgs);
return std::string(zc.data(), iLen);
}
inline std::basic_string<wchar_t> createFormatted(const wchar_t* format, ...)
{
// Calculate the length of the new std::string
va_list argumentList;
va_start(argumentList, format);
std::basic_string<wchar_t> newString = strings::vaFormatString(format, argumentList);
va_end(argumentList);
return newString;
}
inline void ignoreWhitespace(char** pszString)
{
while (*pszString[0] == '\t' || *pszString[0] == '\n' || *pszString[0] == '\r' || *pszString[0] == ' ') { (*pszString)++; }
}
inline char* readEOLToken(char* pToken)
{
char* pReturn = nullptr;
char szDelim[2] = { '\n', 0 }; // try newline
pReturn = strtok(pToken, szDelim);
if (pReturn == nullptr)
{
szDelim[0] = '\r';
pReturn = strtok(pToken, szDelim); // try linefeed
}
return pReturn;
}
inline bool concatenateLinesUntil(std::string& outStr, int& line, const std::vector<std::string>& lines, uint32_t limit, const char* endStr)
{
uint32_t i, j;
size_t nLen;
nLen = 0;
for (i = static_cast<uint32_t>(line); i < limit; ++i)
{
if (strcmp(lines[i].c_str(), endStr) == 0) { break; }
nLen += strlen(lines[i].c_str()) + 1;
}
if (i == limit) { return false; }
if (nLen != 0u)
{
++nLen;
outStr.reserve(nLen);
for (j = static_cast<uint32_t>(line); j < i; ++j)
{
outStr.append(lines[j]);
outStr.append("\n");
}
}
line = static_cast<int>(i);
return true;
}
inline void toLower(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), [](char c) { return static_cast<char>(std::tolower(static_cast<int>(c))); });
}
inline std::string toLower(const std::string& str)
{
std::string loweredString = str;
pvr::strings::toLower(loweredString);
return loweredString;
}
inline bool startsWith(const std::string& str, const std::string& substr)
{
if (str.rfind(substr, 0) == 0) { return true; };
return false;
}
inline bool endsWith(const std::string& str, const std::string& substr)
{
if (str.length() >= substr.length()) { return (0 == str.compare(str.length() - substr.length(), substr.length(), substr)); }
else
{
return false;
}
}
inline void getFileDirectory(const std::string& filePath, std::string& outFileDir)
{
outFileDir.clear();
auto pos = filePath.find_last_of("/");
if (pos == std::string::npos) { return; }
outFileDir.assign(filePath.substr(0, pos));
}
inline void getFileNameAndExtension(const std::string& fileAndExtension, std::string& filename, std::string& extension)
{
auto it = std::find(fileAndExtension.rbegin(), fileAndExtension.rend(), '.');
if (it == fileAndExtension.rend())
{
filename = fileAndExtension;
extension = "";
return;
}
auto position = fileAndExtension.rend() - it; // rend is the position one-after the start of the std::string.
filename.assign(fileAndExtension.begin(), fileAndExtension.begin() + position - 1);
extension.assign(fileAndExtension.begin() + position, fileAndExtension.end());
}
} // namespace strings
} // namespace pvr