C++ Utilities  5.10.3
Useful C++ classes and routines such as argument parser, IO and conversion utilities
stringconversion.h
Go to the documentation of this file.
1 #ifndef CONVERSION_UTILITIES_STRINGCONVERSION_H
2 #define CONVERSION_UTILITIES_STRINGCONVERSION_H
3 
4 #include "./binaryconversion.h"
6 
7 #include "../misc/traits.h"
8 
9 #include <cstdlib>
10 #include <cstring>
11 #include <initializer_list>
12 #include <iomanip>
13 #include <list>
14 #include <memory>
15 #include <sstream>
16 #include <string>
17 #include <string_view>
18 #include <system_error>
19 #include <vector>
20 
21 #if __cplusplus >= 201709
22 #include <ranges>
23 #endif
24 
25 namespace CppUtilities {
26 
35  void operator()(char *stringData)
36  {
37  std::free(stringData);
38  }
39 };
40 
44 using StringData = std::pair<std::unique_ptr<char[], StringDataDeleter>, std::size_t>;
45 //using StringData = std::pair<std::unique_ptr<char>, std::size_t>; // might work too
46 
48  const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor = 1.0f);
49 CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize);
50 CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
51 CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize);
52 CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
53 CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize);
54 CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize);
55 
56 #ifdef PLATFORM_WINDOWS
57 using WideStringData = std::pair<std::unique_ptr<wchar_t[]>, int>;
58 CPP_UTILITIES_EXPORT WideStringData convertMultiByteToWide(std::error_code &ec, const char *inputBuffer, int inputBufferSize = -1);
59 CPP_UTILITIES_EXPORT WideStringData convertMultiByteToWide(std::error_code &ec, const std::string &inputBuffer);
60 CPP_UTILITIES_EXPORT WideStringData convertMultiByteToWide(const char *inputBuffer, int inputBufferSize = -1);
61 CPP_UTILITIES_EXPORT WideStringData convertMultiByteToWide(const std::string &inputBuffer);
62 #endif
63 
64 CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar = '\0');
65 
67 namespace Detail {
68 #if __cplusplus >= 201709
69 template <class Container>
70 using ContainerValueType = typename std::conditional_t<std::ranges::range<Container>,
71  std::iterator_traits<std::remove_cvref_t<std::ranges::iterator_t<Container>>>, Container>::value_type;
72 #else
73 template <class Container> using ContainerValueType = typename Container::value_type;
74 #endif
75 template <class Container> using DefaultReturnTypeForContainer = ContainerValueType<Container>;
76 template <class Container> using StringParamForContainer = std::basic_string_view<typename ContainerValueType<Container>::value_type>;
77 } // namespace Detail
79 
94 template <class Container = std::initializer_list<std::string>, class ReturnType = Detail::DefaultReturnTypeForContainer<Container>>
95 ReturnType joinStrings(const Container &strings, Detail::StringParamForContainer<Container> delimiter = Detail::StringParamForContainer<Container>(),
96  bool omitEmpty = false, Detail::StringParamForContainer<Container> leftClosure = Detail::StringParamForContainer<Container>(),
97  Detail::StringParamForContainer<Container> rightClosure = Detail::StringParamForContainer<Container>())
98 {
99  ReturnType res;
100  if (!strings.size()) {
101  return res;
102  }
103  std::size_t entries = 0, size = 0;
104  for (const auto &str : strings) {
105  if (omitEmpty && str.empty()) {
106  continue;
107  }
108  size += str.size();
109  ++entries;
110  }
111  if (!entries) {
112  return res;
113  }
114  size += (entries * leftClosure.size()) + (entries * rightClosure.size()) + ((entries - 1) * delimiter.size());
115  res.reserve(size);
116  for (const auto &str : strings) {
117  if (omitEmpty && str.empty()) {
118  continue;
119  }
120  if (!res.empty()) {
121  res.append(delimiter);
122  }
123  res.append(leftClosure);
124  res.append(str);
125  res.append(rightClosure);
126  }
127  return res;
128 }
129 
133 template <class Container = std::initializer_list<std::string>> inline auto toMultiline(const Container &arrayOfLines)
134 {
135  return joinStrings(arrayOfLines, "\n", false);
136 }
137 
141 enum class EmptyPartsTreat {
142  Keep,
143  Omit,
144  Merge
145 };
146 
156 template <class Container = std::list<std::string>>
157 Container splitString(Detail::StringParamForContainer<Container> string, Detail::StringParamForContainer<Container> delimiter,
158  EmptyPartsTreat emptyPartsRole = EmptyPartsTreat::Keep, int maxParts = -1)
159 {
160  --maxParts;
161  Container res;
162  typename Container::value_type *last = nullptr;
163  bool merge = false;
164  typename Container::value_type::size_type i = 0, end = string.size();
165  for (typename Container::value_type::size_type delimPos; i < end; i = delimPos + delimiter.size()) {
166  delimPos = string.find(delimiter, i);
167  if (!merge && maxParts >= 0 && res.size() == static_cast<typename Container::value_type::size_type>(maxParts)) {
168  if (delimPos == i && emptyPartsRole == EmptyPartsTreat::Merge) {
169  if (last) {
170  merge = true;
171  continue;
172  }
173  }
174  delimPos = Container::value_type::npos;
175  }
176  if (delimPos == Container::value_type::npos) {
177  delimPos = string.size();
178  }
179  if (emptyPartsRole == EmptyPartsTreat::Keep || i != delimPos) {
180  if (merge) {
181  last->append(delimiter);
182  last->append(string, i, delimPos - i);
183  merge = false;
184  } else {
185  last = &res.emplace_back(string, i, delimPos - i);
186  }
187  } else if (emptyPartsRole == EmptyPartsTreat::Merge) {
188  if (last) {
189  merge = true;
190  }
191  }
192  }
193  if (i == end && emptyPartsRole == EmptyPartsTreat::Keep) {
194  res.emplace_back();
195  }
196  return res;
197 }
198 
208 template <class Container = std::list<std::string>>
210  Detail::StringParamForContainer<Container> string, Detail::StringParamForContainer<Container> delimiter, int maxParts = -1)
211 {
212  --maxParts;
213  Container res;
214  typename Container::value_type::size_type i = 0, end = string.size();
215  for (typename Container::value_type::size_type delimPos; i < end; i = delimPos + delimiter.size()) {
216  delimPos = string.find(delimiter, i);
217  if (maxParts >= 0 && res.size() == static_cast<typename Container::value_type::size_type>(maxParts)) {
218  delimPos = Container::value_type::npos;
219  }
220  if (delimPos == Container::value_type::npos) {
221  delimPos = string.size();
222  }
223 #if __cplusplus >= 201709
224  if constexpr (requires { res.emplace_back(string); }) {
225 #endif
226  res.emplace_back(string.data() + i, delimPos - i);
227 #if __cplusplus >= 201709
228  } else {
229  res.emplace(string.data() + i, delimPos - i);
230  }
231 #endif
232  }
233  if (i == end) {
234 #if __cplusplus >= 201709
235  if constexpr (requires { res.emplace_back(); }) {
236 #endif
237  res.emplace_back();
238 #if __cplusplus >= 201709
239  } else {
240  res.emplace();
241  }
242 #endif
243  }
244  return res;
245 }
246 
250 template <class Container = std::vector<std::string>> inline auto toArrayOfLines(const std::string &multilineString)
251 {
252  return splitString<Container>(multilineString, "\n", EmptyPartsTreat::Keep);
253 }
254 
258 template <typename StringType> bool startsWith(const StringType &str, const StringType &phrase)
259 {
260  if (str.size() < phrase.size()) {
261  return false;
262  }
263  for (auto stri = str.cbegin(), strend = str.cend(), phrasei = phrase.cbegin(), phraseend = phrase.cend();; ++stri, ++phrasei) {
264  if (phrasei == phraseend) {
265  return true;
266  } else if (stri == strend) {
267  return false;
268  } else if (*stri != *phrasei) {
269  return false;
270  }
271  }
272  return false;
273 }
274 
278 template <typename StringType> bool startsWith(const StringType &str, const typename StringType::value_type *phrase)
279 {
280  for (auto stri = str.cbegin(), strend = str.cend();; ++stri, ++phrase) {
281  if (!*phrase) {
282  return true;
283  } else if (stri == strend) {
284  return false;
285  } else if (*stri != *phrase) {
286  return false;
287  }
288  }
289  return false;
290 }
291 
295 template <typename StringType> bool endsWith(const StringType &str, const StringType &phrase)
296 {
297  if (str.size() < phrase.size()) {
298  return false;
299  }
300  for (auto stri = str.cend() - static_cast<typename StringType::difference_type>(phrase.size()), strend = str.cend(), phrasei = phrase.cbegin();
301  stri != strend; ++stri, ++phrasei) {
302  if (*stri != *phrasei) {
303  return false;
304  }
305  }
306  return true;
307 }
308 
312 template <typename StringType> bool endsWith(const StringType &str, const typename StringType::value_type *phrase)
313 {
314  const auto phraseSize = std::strlen(phrase);
315  if (str.size() < phraseSize) {
316  return false;
317  }
318  for (auto stri = str.cend() - static_cast<typename StringType::difference_type>(phraseSize), strend = str.cend(); stri != strend;
319  ++stri, ++phrase) {
320  if (*stri != *phrase) {
321  return false;
322  }
323  }
324  return true;
325 }
326 
331 template <typename StringType> bool containsSubstrings(const StringType &str, std::initializer_list<StringType> substrings)
332 {
333  typename StringType::size_type currentPos = 0;
334  for (const auto &substr : substrings) {
335  if ((currentPos = str.find(substr, currentPos)) == StringType::npos) {
336  return false;
337  }
338  currentPos += substr.size();
339  }
340  return true;
341 }
342 
347 template <typename StringType>
348 bool containsSubstrings(const StringType &str, std::initializer_list<const typename StringType::value_type *> substrings)
349 {
350  typename StringType::size_type currentPos = 0;
351  for (const auto *substr : substrings) {
352  if ((currentPos = str.find(substr, currentPos)) == StringType::npos) {
353  return false;
354  }
355  currentPos += std::strlen(substr);
356  }
357  return true;
358 }
359 
363 template <typename StringType1, typename StringType2, typename StringType3>
364 void findAndReplace(StringType1 &str, const StringType2 &find, const StringType3 &replace)
365 {
366  for (typename StringType1::size_type i = 0; (i = str.find(find, i)) != StringType1::npos; i += replace.size()) {
367  str.replace(i, find.size(), replace);
368  }
369 }
370 
374 template <typename StringType>
375 inline void findAndReplace(StringType &str, const typename StringType::value_type *find, const typename StringType::value_type *replace)
376 {
378  str, std::basic_string_view<typename StringType::value_type>(find), std::basic_string_view<typename StringType::value_type>(replace));
379 }
380 
384 template <typename StringType1, typename StringType2>
385 inline void findAndReplace(StringType1 &str, const StringType2 &find, const typename StringType1::value_type *replace)
386 {
387  findAndReplace(str, find, std::basic_string_view<typename StringType1::value_type>(replace));
388 }
389 
393 template <typename StringType1, typename StringType2>
394 inline void findAndReplace(StringType1 &str, const typename StringType1::value_type *find, const StringType2 &replace)
395 {
396  findAndReplace(str, std::basic_string_view<typename StringType1::value_type>(find), replace);
397 }
398 
405 template <typename CharType> constexpr CharType digitToChar(CharType digit)
406 {
407  return digit <= 9 ? (digit + '0') : (digit + 'A' - 10);
408 }
409 
416 template <typename IntegralType, class StringType = std::string, typename BaseType = IntegralType,
417  CppUtilities::Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
418 StringType numberToString(IntegralType number, BaseType base = 10)
419 {
420  std::size_t resSize = 0;
421  for (auto n = number; n; n /= static_cast<IntegralType>(base), ++resSize)
422  ;
423  StringType res;
424  res.reserve(resSize);
425  do {
426  res.insert(res.begin(), digitToChar<typename StringType::value_type>(static_cast<typename StringType::value_type>(number % base)));
427  number /= static_cast<IntegralType>(base);
428  } while (number);
429  return res;
430 }
431 
438 template <typename IntegralType, class StringType = std::string, typename BaseType = IntegralType,
439  Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * = nullptr>
440 StringType numberToString(IntegralType number, BaseType base = 10)
441 {
442  const bool negative = number < 0;
443  std::size_t resSize;
444  if (negative) {
445  number = -number, resSize = 1;
446  } else {
447  resSize = 0;
448  }
449  for (auto n = number; n; n /= static_cast<IntegralType>(base), ++resSize)
450  ;
451  StringType res;
452  res.reserve(resSize);
453  do {
454  res.insert(res.begin(),
455  digitToChar<typename StringType::value_type>(static_cast<typename StringType::value_type>(number % static_cast<IntegralType>(base))));
456  number /= static_cast<IntegralType>(base);
457  } while (number);
458  if (negative) {
459  res.insert(res.begin(), '-');
460  }
461  return res;
462 }
463 
472 template <typename FloatingType, class StringType = std::string, Traits::EnableIf<std::is_floating_point<FloatingType>> * = nullptr>
473 StringType numberToString(FloatingType number, int base = 10)
474 {
475  std::basic_stringstream<typename StringType::value_type> ss;
476  ss << std::setbase(base) << number;
477  return ss.str();
478 }
479 
484 template <typename CharType> CharType charToDigit(CharType character, CharType base)
485 {
486  CharType res = base;
487  if (character >= '0' && character <= '9') {
488  res = character - '0';
489  } else if (character >= 'a' && character <= 'z') {
490  res = character - 'a' + 10;
491  } else if (character >= 'A' && character <= 'Z') {
492  res = character - 'A' + 10;
493  }
494  if (res < base) {
495  return res;
496  }
497  std::string errorMsg;
498  errorMsg.reserve(36);
499  errorMsg += "The character \"";
500  errorMsg += character >= ' ' && character <= '~' ? static_cast<std::string::value_type>(character) : '?';
501  errorMsg += "\" is no valid digit.";
502  throw ConversionException(std::move(errorMsg));
503 }
504 
512 template <typename IntegralType, class StringType, typename BaseType = IntegralType,
513  Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>, Traits::Not<std::is_scalar<std::decay_t<StringType>>>>
514  * = nullptr>
515 IntegralType stringToNumber(const StringType &string, BaseType base = 10)
516 {
517  IntegralType result = 0;
518  for (const auto &c : string) {
519  if (c == ' ') {
520  continue;
521  }
522  result *= static_cast<IntegralType>(base);
523  result += static_cast<IntegralType>(charToDigit<typename StringType::value_type>(c, static_cast<typename StringType::value_type>(base)));
524  }
525  return result;
526 }
527 
535 template <typename IntegralType, class StringType, typename BaseType = IntegralType,
536  Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>, Traits::Not<std::is_scalar<std::decay_t<StringType>>>> * = nullptr>
537 IntegralType stringToNumber(const StringType &string, IntegralType base = 10)
538 {
539  auto i = string.begin();
540  auto end = string.end();
541  for (; i != end && *i == ' '; ++i)
542  ;
543  if (i == end) {
544  return 0;
545  }
546  const bool negative = (*i == '-');
547  if (negative) {
548  ++i;
549  }
550  IntegralType result = 0;
551  for (; i != end; ++i) {
552  if (*i == ' ') {
553  continue;
554  }
555  result *= static_cast<IntegralType>(base);
556  result += static_cast<IntegralType>(charToDigit<typename StringType::value_type>(*i, static_cast<typename StringType::value_type>(base)));
557  }
558  return negative ? -result : result;
559 }
560 
570 template <typename FloatingType, class StringType,
571  Traits::EnableIf<std::is_floating_point<FloatingType>, Traits::Not<std::is_scalar<std::decay_t<StringType>>>> * = nullptr>
572 FloatingType stringToNumber(const StringType &string, int base = 10)
573 {
574  std::basic_stringstream<typename StringType::value_type> ss;
575  ss << std::setbase(base) << string;
576  FloatingType result;
577  if ((ss >> result) && ss.eof()) {
578  return result;
579  }
580  std::string errorMsg;
581  errorMsg.reserve(42 + string.size());
582  errorMsg += "The string \"";
583  errorMsg += string;
584  errorMsg += "\" is no valid floating number.";
585  throw ConversionException(errorMsg);
586 }
587 
595 template <typename IntegralType, typename CharType, typename BaseType = IntegralType,
596  Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
597 IntegralType stringToNumber(const CharType *string, BaseType base = 10)
598 {
599  IntegralType result = 0;
600  for (; *string; ++string) {
601  if (*string == ' ') {
602  continue;
603  }
604  result *= static_cast<IntegralType>(base);
605  result += static_cast<IntegralType>(charToDigit<CharType>(*string, static_cast<CharType>(base)));
606  }
607  return result;
608 }
609 
619 template <typename FloatingType, class CharType, Traits::EnableIf<std::is_floating_point<FloatingType>> * = nullptr>
620 FloatingType stringToNumber(const CharType *string, int base = 10)
621 {
622  std::basic_stringstream<CharType> ss;
623  ss << std::setbase(base) << string;
624  FloatingType result;
625  if ((ss >> result) && ss.eof()) {
626  return result;
627  }
628  std::string errorMsg;
629  errorMsg.reserve(42 + std::char_traits<CharType>::length(string));
630  errorMsg += "The string \"";
631  errorMsg += string;
632  errorMsg += "\" is no valid floating number.";
633  throw ConversionException(errorMsg);
634 }
635 
643 template <typename IntegralType, class CharType, typename BaseType = IntegralType,
644  Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
645 IntegralType bufferToNumber(const CharType *string, std::size_t size, BaseType base = 10)
646 {
647  IntegralType result = 0;
648  for (const CharType *end = string + size; string != end; ++string) {
649  if (*string == ' ') {
650  continue;
651  }
652  result *= static_cast<IntegralType>(base);
653  result += static_cast<IntegralType>(charToDigit<CharType>(*string, static_cast<CharType>(base)));
654  }
655  return result;
656 }
657 
665 template <typename IntegralType, typename CharType, typename BaseType = IntegralType,
666  Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * = nullptr>
667 IntegralType stringToNumber(const CharType *string, IntegralType base = 10)
668 {
669  if (!*string) {
670  return 0;
671  }
672  for (; *string && *string == ' '; ++string)
673  ;
674  if (!*string) {
675  return 0;
676  }
677  const bool negative = (*string == '-');
678  if (negative) {
679  ++string;
680  }
681  IntegralType result = 0;
682  for (; *string; ++string) {
683  if (*string == ' ') {
684  continue;
685  }
686  result *= static_cast<IntegralType>(base);
687  result += static_cast<IntegralType>(charToDigit<CharType>(*string, static_cast<CharType>(base)));
688  }
689  return negative ? -result : result;
690 }
691 
699 template <typename IntegralType, typename CharType, typename BaseType = IntegralType,
700  Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * = nullptr>
701 IntegralType bufferToNumber(const CharType *string, std::size_t size, BaseType base = 10)
702 {
703  if (!size) {
704  return 0;
705  }
706  const CharType *end = string + size;
707  for (; string != end && *string == ' '; ++string)
708  ;
709  if (string == end) {
710  return 0;
711  }
712  const bool negative = (*string == '-');
713  if (negative) {
714  ++string;
715  }
716  IntegralType result = 0;
717  for (; string != end; ++string) {
718  if (*string == ' ') {
719  continue;
720  }
721  result *= static_cast<IntegralType>(base);
722  result += static_cast<IntegralType>(charToDigit<CharType>(*string, static_cast<CharType>(base)));
723  }
724  return negative ? -result : result;
725 }
726 
736 template <typename T> std::string interpretIntegerAsString(T integer, int startOffset = 0)
737 {
738  char buffer[sizeof(T)];
739  BE::getBytes(integer, buffer);
740  return std::string(buffer + startOffset, sizeof(T) - static_cast<std::size_t>(startOffset));
741 }
742 
743 CPP_UTILITIES_EXPORT std::string dataSizeToString(std::uint64_t sizeInByte, bool includeByte = false);
744 CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits = false);
745 CPP_UTILITIES_EXPORT std::string encodeBase64(const std::uint8_t *data, std::uint32_t dataSize);
746 CPP_UTILITIES_EXPORT std::pair<std::unique_ptr<std::uint8_t[]>, std::uint32_t> decodeBase64(const char *encodedStr, const std::uint32_t strSize);
747 } // namespace CppUtilities
748 
749 #endif // CONVERSION_UTILITIES_STRINGCONVERSION_H
The ConversionException class is thrown by the various conversion functions of this library when a co...
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Shortcut for std::enable_if to omit ::value and ::type.
Definition: traits.h:51
Contains all utilities provides by the c++utilities library.
void findAndReplace(StringType1 &str, const StringType2 &find, const StringType3 &replace)
Replaces all occurences of find with relpace in the specified str.
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (big-endian).
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.
StringType numberToString(IntegralType number, BaseType base=10)
Converts the given number to its equivalent string representation using the specified base.
CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified Latin-1 string to UTF-8.
CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (little-endian) string to UTF-8.
EmptyPartsTreat
Specifies the role of empty parts when splitting strings.
CPP_UTILITIES_EXPORT std::pair< std::unique_ptr< std::uint8_t[]>, std::uint32_t > decodeBase64(const char *encodedStr, const std::uint32_t strSize)
Decodes the specified Base64 encoded string.
ReturnType joinStrings(const Container &strings, Detail::StringParamForContainer< Container > delimiter=Detail::StringParamForContainer< Container >(), bool omitEmpty=false, Detail::StringParamForContainer< Container > leftClosure=Detail::StringParamForContainer< Container >(), Detail::StringParamForContainer< Container > rightClosure=Detail::StringParamForContainer< Container >())
Joins the given strings using the specified delimiter.
bool startsWith(const StringType &str, const StringType &phrase)
Returns whether str starts with phrase.
IntegralType stringToNumber(const StringType &string, BaseType base=10)
Converts the given string to an unsigned number assuming string uses the specified base.
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...
std::pair< std::unique_ptr< char[], StringDataDeleter >, std::size_t > StringData
Type used to return string encoding conversion result.
CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (big-endian) string to UTF-8.
constexpr CharType digitToChar(CharType digit)
Returns the character representation of the specified digit.
Container splitStringSimple(Detail::StringParamForContainer< Container > string, Detail::StringParamForContainer< Container > delimiter, int maxParts=-1)
Splits the given string (which might also be a string view) at the specified delimiter.
auto toArrayOfLines(const std::string &multilineString)
Converts the specified multilineString to an array of lines.
bool containsSubstrings(const StringType &str, std::initializer_list< StringType > substrings)
Returns whether str contains the specified substrings.
CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to Latin-1.
std::string interpretIntegerAsString(T integer, int startOffset=0)
Interprets the given integer at the specified position as std::string using the specified byte order.
bool endsWith(const StringType &str, const StringType &phrase)
Returns whether str ends with phrase.
auto toMultiline(const Container &arrayOfLines)
Converts the specified arrayOfLines to a multiline string.
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (little-endian).
CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits=false)
Converts the specified bitrate in kbit/s to its equivalent std::string representation.
CharType charToDigit(CharType character, CharType base)
Returns number/digit of the specified character representation using the specified base.
CPP_UTILITIES_EXPORT std::string encodeBase64(const std::uint8_t *data, std::uint32_t dataSize)
Encodes the specified data to Base64.
CPP_UTILITIES_EXPORT std::string dataSizeToString(std::uint64_t sizeInByte, bool includeByte=false)
Converts the specified data size in byte to its equivalent std::string representation.
IntegralType bufferToNumber(const CharType *string, std::size_t size, BaseType base=10)
Converts the given string of size characters to an unsigned numeric value using the specified base.
Container splitString(Detail::StringParamForContainer< Container > string, Detail::StringParamForContainer< Container > delimiter, EmptyPartsTreat emptyPartsRole=EmptyPartsTreat::Keep, int maxParts=-1)
Splits the given string at the specified delimiter.
The StringDataDeleter struct deletes the data of a StringData instance.
void operator()(char *stringData)
Deletes the specified stringData with std::free(), because the memory has been allocated using std::m...
constexpr int i