1 #ifndef CONVERSION_UTILITIES_STRINGCONVERSION_H 2 #define CONVERSION_UTILITIES_STRINGCONVERSION_H 7 #include "../misc/traits.h" 13 #include <initializer_list> 31 std::free(stringData);
38 typedef std::pair<std::unique_ptr<char[], StringDataDeleter>, std::size_t>
StringData;
41 CPP_UTILITIES_EXPORT StringData
convertString(
const char *fromCharset,
const char *toCharset,
const char *inputBuffer, std::size_t inputBufferSize,
float outputBufferSizeFactor = 1.0f);
64 template <
class Container = std::initializer_list<std::
string> >
65 typename Container::value_type
joinStrings(
const Container &strings,
const typename Container::value_type &delimiter =
typename Container::value_type(),
bool omitEmpty =
false,
const typename Container::value_type &leftClosure =
typename Container::value_type(),
const typename Container::value_type &rightClosure =
typename Container::value_type())
67 typename Container::value_type res;
69 size_t entries = 0, size = 0;
70 for(
const auto &str : strings) {
71 if(!omitEmpty || !str.empty()) {
77 size += (entries * leftClosure.size()) + (entries * rightClosure.size()) + ((entries - 1) * delimiter.size());
79 for(
const auto &str : strings) {
80 if(!omitEmpty || !str.empty()) {
82 res.append(delimiter);
84 res.append(leftClosure);
86 res.append(rightClosure);
113 template <
class Container = std::list<std::
string> >
119 for(
typename Container::value_type::size_type i = 0, end =
string.size(), delimPos; i < end; i = delimPos + delimiter.size()) {
120 delimPos =
string.find(delimiter, i);
121 if(!merge && maxParts >= 0 && res.size() ==
static_cast<typename Container::value_type::size_type
>(maxParts)) {
128 delimPos = Container::value_type::npos;
130 if(delimPos == Container::value_type::npos) {
131 delimPos =
string.size();
135 res.back().append(delimiter);
136 res.back().append(
string.substr(i, delimPos - i));
139 res.emplace_back(
string.substr(i, delimPos - i));
153 template <
typename StringType>
154 bool startsWith(
const StringType &str,
const StringType &phrase)
156 if(str.size() < phrase.size()) {
159 for(
auto stri = str.cbegin(), strend = str.cend(), phrasei = phrase.cbegin(), phraseend = phrase.cend(); stri != strend; ++stri, ++phrasei) {
160 if(phrasei == phraseend) {
162 }
else if(*stri != *phrasei) {
172 template <
typename StringType>
173 bool startsWith(
const StringType &str,
const typename StringType::value_type *phrase)
175 for(
auto stri = str.cbegin(), strend = str.cend(); stri != strend; ++stri, ++phrase) {
178 }
else if(*stri != *phrase) {
189 template <
typename StringType>
192 typename StringType::size_type currentPos = 0;
193 for(
const auto &substr : substrings) {
194 if((currentPos = str.find(substr, currentPos)) == StringType::npos) {
197 currentPos += substr.size();
206 template <
typename StringType>
207 bool containsSubstrings(
const StringType &str, std::initializer_list<const typename StringType::value_type *> substrings)
209 typename StringType::size_type currentPos = 0;
210 for(
const auto *substr : substrings) {
211 if((currentPos = str.find(substr, currentPos)) == StringType::npos) {
214 currentPos += std::strlen(substr);
222 template <
typename StringType>
223 void findAndReplace(StringType &str,
const StringType &find,
const StringType &replace)
225 for(
typename StringType::size_type i = 0; (i = str.find(find, i)) != StringType::npos; i += replace.size()) {
226 str.replace(i, find.size(), replace);
236 template <
typename CharType>
243 res = digit +
'A' - 10;
254 template <
typename IntegralType,
class StringType = std::
string, Traits::EnableIf<std::is_
integral<IntegralType>, Traits::Not<std::is_
signed<IntegralType> > >...>
255 StringType
numberToString(IntegralType number,
typename StringType::value_type base = 10)
257 std::size_t resSize = 0;
258 for(
auto n = number; n; n /= base, ++resSize);
260 res.reserve(resSize);
262 res.insert(res.begin(), digitToChar<typename StringType::value_type>(number % base));
274 template <
typename IntegralType,
class StringType = std::
string, Traits::EnableIf<std::is_
integral<IntegralType>, std::is_
signed<IntegralType> >...>
275 StringType
numberToString(IntegralType number,
typename StringType::value_type base = 10)
277 const bool negative = number < 0;
280 number = -number, resSize = 1;
284 for(
auto n = number; n; n /= base, ++resSize);
286 res.reserve(resSize);
288 res.insert(res.begin(), digitToChar<typename StringType::value_type>(number % base));
292 res.insert(res.begin(),
'-');
305 template <
typename FloatingType,
class StringType = std::
string, Traits::EnableIf<std::is_
floating_po
int<FloatingType> >...>
306 StringType
numberToString(FloatingType number,
typename StringType::value_type base = 10)
308 std::basic_stringstream<typename StringType::value_type> ss;
309 ss << std::setbase(base) << number;
317 template <
typename CharType>
321 if(character >=
'0' && character <=
'9') {
322 res = character -
'0';
323 }
else if(character >=
'a' && character <=
'z') {
324 res = character -
'a' + 10;
325 }
else if(character >=
'A' && character <=
'Z') {
326 res = character -
'A' + 10;
343 template <
typename IntegralType,
class StringType, Traits::EnableIf<std::is_
integral<IntegralType>, Traits::Not<std::is_
signed<IntegralType> > >...>
344 IntegralType
stringToNumber(
const StringType &
string,
typename StringType::value_type base = 10)
346 IntegralType result = 0;
347 for(
const auto &c :
string) {
352 result += charToDigit<typename StringType::value_type>(c, base);
364 template <
typename IntegralType,
class StringType, Traits::EnableIf<std::is_
integral<IntegralType>, std::is_
signed<IntegralType> >...>
365 IntegralType
stringToNumber(
const StringType &
string,
typename StringType::value_type base = 10)
367 auto i =
string.begin();
368 auto end =
string.end();
372 const bool negative = (*i ==
'-');
376 IntegralType result = 0;
377 for(; i != end; ++i) {
382 result += charToDigit<typename StringType::value_type>(*i, base);
384 return negative ? -result : result;
396 template <
typename FloatingType,
class StringType, Traits::EnableIf<std::is_
floating_po
int<FloatingType> >...>
397 FloatingType
stringToNumber(
const StringType &
string,
typename StringType::value_type base = 10)
399 std::basic_stringstream<typename StringType::value_type> ss;
400 ss << std::setbase(base) << string;
402 if((ss >> result) && ss.eof()) {
416 template <
typename IntegralType,
class CharType, Traits::EnableIf<std::is_
integral<IntegralType>, Traits::Not<std::is_
signed<IntegralType> > >...>
419 IntegralType result = 0;
420 for(; *string; ++string) {
425 result += charToDigit<CharType>(*string, base);
437 template <
typename IntegralType,
class CharType, Traits::EnableIf<std::is_
integral<IntegralType>, std::is_
signed<IntegralType> >...>
438 IntegralType
stringToNumber(
const CharType *
string,
unsigned char base = 10)
443 const bool negative = (*
string ==
'-');
447 IntegralType result = 0;
448 for(; *string; ++string) {
453 result += charToDigit<CharType>(*string, base);
455 return negative ? -result : result;
467 template <
typename T>
470 char buffer[
sizeof(T)];
471 ConversionUtilities::BE::getBytes(integer, buffer);
472 return std::string(buffer + startOffset,
sizeof(T) - startOffset);
482 #endif // CONVERSION_UTILITIES_STRINGCONVERSION_H CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (little-endian).
bool startsWith(const StringType &str, const StringType &phrase)
Returns whether str starts with phrase.
void operator()(char *stringData)
Deletes the specified stringData with std::free(), because the memory has been allocated using std::m...
CPP_UTILITIES_EXPORT std::string encodeBase64(const byte *data, uint32 dataSize)
Encodes the specified data to Base64.
IntegralType stringToNumber(const StringType &string, typename StringType::value_type base=10)
Converts the given string to a number assuming string uses the specified base.
bool containsSubstrings(const StringType &str, std::initializer_list< StringType > substrings)
Returns whether str contains the specified substrings.
The ConversionException class is thrown by the various conversion functions of this library when a co...
CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (big-endian) string to UTF-8.
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar='\0')
Truncates all characters after the first occurrence of the specified terminationChar and the terminat...
StringType numberToString(IntegralType number, typename StringType::value_type base=10)
Converts the given number to its equivalent string representation using the specified base...
std::uint64_t uint64
unsigned 64-bit integer
The StringDataDeleter struct deletes the data of a StringData instance.
std::string interpretIntegerAsString(T integer, int startOffset=0)
Interprets the given integer at the specified position as std::string using the specified byte order...
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (big-endian).
EmptyPartsTreat
Specifies the role of empty parts when splitting strings.
CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to Latin-1.
void findAndReplace(StringType &str, const StringType &find, const StringType &replace)
Replaces all occurences of find with relpace in the specified str.
Contains several functions providing conversions between different data types.
std::uint32_t uint32
unsigned 32-bit integer
std::pair< std::unique_ptr< char[], StringDataDeleter >, std::size_t > StringData
Type used to return string encoding conversion result.
CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (little-endian) string to UTF-8.
CharType charToDigit(CharType character, CharType base)
Returns number/digit of the specified character representation using the specified base...
Container::value_type joinStrings(const Container &strings, const typename Container::value_type &delimiter=typename Container::value_type(), bool omitEmpty=false, const typename Container::value_type &leftClosure=typename Container::value_type(), const typename Container::value_type &rightClosure=typename Container::value_type())
Joins the given strings using the specified delimiter.
CPP_UTILITIES_EXPORT StringData convertString(const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor=1.0f)
Converts the specified string from one character set to another.
CharType digitToChar(CharType digit)
Returns the character representation of the specified digit.
std::uint8_t byte
unsigned byte
CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified Latin-1 string to UTF-8.
Container splitString(const typename Container::value_type &string, const typename Container::value_type &delimiter, EmptyPartsTreat emptyPartsRole=EmptyPartsTreat::Keep, int maxParts=-1)
Splits the given string at the specified delimiter.
CPP_UTILITIES_EXPORT std::string dataSizeToString(uint64 sizeInByte, bool includeByte=false)
Converts the specified data size in byte to its equivalent std::string representation.
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
CPP_UTILITIES_EXPORT std::pair< std::unique_ptr< byte[]>, uint32 > decodeBase64(const char *encodedStr, const uint32 strSize)
Decodes the specified Base64 encoded string.
CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits=false)
Converts the specified bitrate in kbit/s to its equivalent std::string representation.