Leviathan  0.8.0.0
Leviathan game engine
Leviathan::StringOperations Class Reference

Singleton class that has string processing functions. More...

#include <StringOperations.h>

Public Member Functions

template<>
DLLEXPORT void MakeString (std::wstring &str, const char *characters, size_t count)
 

Static Public Member Functions

template<typename CharType >
static bool IsCharacterWhitespace (CharType character)
 
template<typename CharType >
static bool IsCharacterQuote (CharType character)
 
template<typename CharType >
static bool IsCharacterPathSeparator (CharType character)
 
template<class StringTypeN >
static void MakeString (StringTypeN &str, const char *characters, size_t count)
 
template<class StringTypeN >
static StringTypeN RepeatCharacter (int character, size_t count)
 
template<class StringTypeN >
static const StringTypeN RemoveExtension (const StringTypeN &filepath, bool delpath=true)
 
template<class StringTypeN >
static const StringTypeN GetExtension (const StringTypeN &filepath)
 
template<class StringTypeN >
static const StringTypeN ChangeExtension (const StringTypeN &filepath, const StringTypeN &newext)
 
template<class StringTypeN >
static const StringTypeN RemovePath (const StringTypeN &filepath)
 
template<class StringTypeN >
static const StringTypeN GetPath (const StringTypeN &filepath)
 Returns the path part of a path+filename. More...
 
static DLLEXPORT std::string URLProtocol (const std::string &url)
 
static DLLEXPORT std::string BaseHostName (const std::string &url)
 
static DLLEXPORT std::string URLPath (const std::string &url, bool stripoptions=true)
 
static DLLEXPORT std::string CombineURL (const std::string &first, const std::string &second)
 
static DLLEXPORT std::string RemovePartsBeforeAbsoluteURLParts (const std::string &url)
 
static DLLEXPORT bool IsURLDomain (const std::string &str)
 Returns true if string looks like a top level domain. More...
 
template<class StringTypeN >
static const StringTypeN ChangeLineEndsToWindows (const StringTypeN &input)
 Changes all line separators to Windows line separators. More...
 
template<class StringTypeN >
static const StringTypeN ChangeLineEndsToUniversal (const StringTypeN &input)
 Changes all line separators to universal line separators. More...
 
template<class StringTypeN >
static size_t CutLines (const StringTypeN &input, std::vector< StringTypeN > &output)
 Splits a string on line separators. More...
 
template<class StringTypeN >
static bool CutString (const StringTypeN &strtocut, const StringTypeN &separator, std::vector< StringTypeN > &vec)
 
template<class StringTypeN >
static int CountOccuranceInString (const StringTypeN &data, const StringTypeN &lookfor)
 
template<class StringTypeN >
static StringTypeN Replace (const StringTypeN &data, const StringTypeN &toreplace, const StringTypeN &replacer)
 
template<class StringTypeN >
static StringTypeN ReplaceSingleCharacter (const StringTypeN &data, int toreplace, int replacer=' ')
 
template<class StringTypeN >
static void ReplaceSingleCharacterInPlace (StringTypeN &data, int toreplace, int replacer=' ')
 
template<class StringTypeN >
static StringTypeN RemoveCharacters (const StringTypeN &data, const StringTypeN &toremove)
 
template<class StringTypeN >
static StringTypeN RemoveFirstWords (const StringTypeN &data, int amount)
 
template<class StringTypeN >
static StringTypeN RemovePrefix (const StringTypeN &data, const StringTypeN &prefix)
 
template<class StringTypeN >
static StringTypeN StitchTogether (const std::vector< StringTypeN * > &data, const StringTypeN &separator)
 
template<class StringTypeN >
static StringTypeN StitchTogether (const std::vector< StringTypeN > &data, const StringTypeN &separator)
 
template<class StringTypeN >
static StringTypeN StitchTogether (const std::vector< std::shared_ptr< StringTypeN >> &data, const StringTypeN &separator)
 
template<class StringTypeN >
static void RemovePreceedingTrailingSpaces (StringTypeN &str)
 
template<class StringTypeN >
static bool CompareInsensitive (const StringTypeN &data, const StringTypeN &second)
 
template<class StringTypeN >
static bool StringStartsWith (const StringTypeN &data, const StringTypeN &tomatch)
 
template<class StringTypeN >
static bool StringEndsWith (const StringTypeN &data, const StringTypeN &tomatch)
 
template<class StringTypeN >
static bool IsStringNumeric (const StringTypeN &data)
 
template<class StringTypeN >
static StringTypeN ToUpperCase (const StringTypeN &data)
 
template<class StringTypeN >
static StringTypeN Indent (size_t numspaces)
 
template<class StringTypeN >
static StringTypeN IndentLines (const StringTypeN &str, size_t spaces)
 Appends spaces number of spaces to each line in str and returns the result. More...
 
template<class StringTypeN >
static StringTypeN RemoveEnding (const StringTypeN &str, const StringTypeN &ending)
 
static bool IsLineTerminator (int32_t codepoint)
 
static bool IsLineTerminator (int32_t codepoint1, int32_t codepoint2)
 

Detailed Description

Singleton class that has string processing functions.

Most functions work with any type of string, but it is recommended to only pass string or wstring to avoid headaches.

Todo:

Get rid of ElementType and just use ints for everything and hope that it is large enough

Drop wstring support

Definition at line 33 of file StringOperations.h.

Member Function Documentation

◆ BaseHostName()

DLLEXPORT std::string StringOperations::BaseHostName ( const std::string &  url)
static

Definition at line 28 of file StringOperations.cpp.

29 {
30  if(url.empty())
31  return "";
32 
33  // Start scanning until a '/' is found that is not preceeded by ':' or '/'
34  size_t length = 0;
35 
36  for(size_t i = 0; i < url.size(); ++i) {
37 
38  length = i + 1;
39 
40  if(url[i] == '/') {
41 
42  if(i < 1)
43  continue;
44 
45  if(url[i - 1] == ':' || url[i - 1] == '/')
46  continue;
47 
48  // found it //
49  break;
50  }
51  }
52 
53  // Make sure it has an ending '/'
54  if(length == url.size() && url.back() != '/')
55  return url + "/";
56 
57  return url.substr(0, length);
58 }

◆ ChangeExtension()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::ChangeExtension ( const StringTypeN &  filepath,
const StringTypeN &  newext 
)
inlinestatic

Definition at line 154 of file StringOperations.h.

156  {
157  size_t startcopy = 0;
158  size_t endcopy = filepath.size() - 1;
159 
160  size_t lastdot = filepath.find_last_of(DOT_CHARACTER);
161 
162  if(lastdot != StringTypeN::npos) {
163  // dot found //
164  endcopy = lastdot;
165 
166  } else {
167  // No dot, so just append it //
168  return filepath + newext;
169  }
170 
171  // Return empty if no data is valid //
172  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
173  return StringTypeN();
174 
175  // Return the extension //
176  return filepath.substr(startcopy, endcopy - startcopy + 1) + newext;
177  }
constexpr int32_t DOT_CHARACTER

◆ ChangeLineEndsToUniversal()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::ChangeLineEndsToUniversal ( const StringTypeN &  input)
inlinestatic

Changes all line separators to universal line separators.

Definition at line 325 of file StringOperations.h.

326  {
327  StringTypeN results;
328 
329  // This is the line ending sequence //
330  StringTypeN separator;
332 
333  // Try to find path strings and replace them //
334  size_t copystart = 0;
335  size_t copyend = 0;
336 
337  for(size_t i = 0; i < input.size(); i++) {
338  if(input[i] == WINDOWS_LINE_SEPARATOR[0] && i + 1 < input.size() &&
339  input[i + 1] == WINDOWS_LINE_SEPARATOR[1]) {
340  // Found a line separator //
341  // Copy the current thing //
342  if(copyend >= copystart && copystart - copyend > 1)
343  results += input.substr(copystart, copyend - copystart + 1);
344 
345 
346  results += separator;
347 
348  copystart = i + 2 < input.size() ? i + 2 : i;
349  copyend = copystart;
350 
351  i += 2;
352 
353  continue;
354  }
355 
356  // Change the end copy //
357  copyend = i;
358  }
359 
360  if(copyend >= copystart && copystart - copyend > 1)
361  results += input.substr(copystart, copyend - copystart + 1);
362 
363 
364  return results;
365  }
constexpr char UNIVERSAL_LINE_SEPARATOR[]
constexpr char WINDOWS_LINE_SEPARATOR[]
static void MakeString(StringTypeN &str, const char *characters, size_t count)

◆ ChangeLineEndsToWindows()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::ChangeLineEndsToWindows ( const StringTypeN &  input)
inlinestatic

Changes all line separators to Windows line separators.

Definition at line 282 of file StringOperations.h.

283  {
284  StringTypeN results;
285 
286  // This is the line ending sequence //
287  StringTypeN separator;
289 
290  // Try to find path strings and replace them //
291  StartEndIndex copyparts;
292 
293  for(size_t i = 0; i < input.size(); i++) {
294  if(input[i] == UNIVERSAL_LINE_SEPARATOR[0]
295  // Previous character wasn't the first character of a windows line separator.
296  // If it was this is already the correct line separator and should be ignored
297  && (i == 0 || input[i - 1] != WINDOWS_LINE_SEPARATOR[0])) {
298  // Found a line separator //
299  // Copy the current thing //
300  if(copyparts.Start && copyparts.End)
301  results += input.substr(copyparts.Start, copyparts.Length());
302 
303  copyparts.Reset();
304 
305  results += separator;
306 
307  continue;
308  }
309 
310  if(!copyparts.Start)
311  copyparts.Start = i;
312 
313  // Change the end copy //
314  copyparts.End = i;
315  }
316 
317  if(copyparts.End && copyparts.Start)
318  results += input.substr(copyparts.Start, copyparts.Length());
319 
320  return results;
321  }
constexpr char UNIVERSAL_LINE_SEPARATOR[]
constexpr char WINDOWS_LINE_SEPARATOR[]
static void MakeString(StringTypeN &str, const char *characters, size_t count)

◆ CombineURL()

DLLEXPORT std::string StringOperations::CombineURL ( const std::string &  first,
const std::string &  second 
)
static

Definition at line 105 of file StringOperations.cpp.

107 {
108  // To fix messed up urls we always do this cleanup
109  const auto cleanedUpSecond = RemovePartsBeforeAbsoluteURLParts(second);
110 
111  if(first.empty())
112  return cleanedUpSecond;
113 
114  if(cleanedUpSecond.empty())
115  return first;
116 
117  // If second is an absolute URL just return it //
118  if(cleanedUpSecond.find("://") != std::string::npos)
119  return cleanedUpSecond;
120 
121  // If the other starts with double '//' then we just need to grab the protocol from the
122  // first and add the second
123  if(cleanedUpSecond.find("//") == 0)
124  return URLProtocol(first) + ":" + second;
125 
126  // Simplest case: first ends with '/' and second doesn't begin with '/'
127  if(first.back() == '/' && cleanedUpSecond.front() != '/')
128  return first + cleanedUpSecond;
129 
130  // Second begins with '/': trim the first to the base url and then append the second
131  if(cleanedUpSecond.front() == '/')
132  return BaseHostName(first) + cleanedUpSecond.substr(1);
133 
134  // An error catching function
135  // If first is the basehostname then just combine them
136  if(first.back() != '/' && BaseHostName(first).length() == first.length() + 1)
137  return first + "/" + cleanedUpSecond;
138 
139  // Most complex case: trim from the end of first until the last '/' and then append second
140  const auto lastpos = first.find_last_of('/');
141  return first.substr(0, lastpos + 1) + cleanedUpSecond;
142 }
static DLLEXPORT std::string BaseHostName(const std::string &url)
static DLLEXPORT std::string URLProtocol(const std::string &url)
static DLLEXPORT std::string RemovePartsBeforeAbsoluteURLParts(const std::string &url)

◆ CompareInsensitive()

template<class StringTypeN >
static bool Leviathan::StringOperations::CompareInsensitive ( const StringTypeN &  data,
const StringTypeN &  second 
)
inlinestatic

Definition at line 870 of file StringOperations.h.

871  {
872  if(data.size() != second.size())
873  return false;
874 
875  for(unsigned int i = 0; i < data.size(); i++) {
876  if(data[i] != second[i]) {
877 
878  // Check are they different case //
879  if(97 <= data[i] && data[i] <= 122) {
880 
881  if(data[i] - 32 != second[i]) {
882 
883  return false;
884  }
885  } else if(97 <= second[i] && second[i] <= 122) {
886 
887  if(second[i] - 32 != data[i]) {
888 
889  return false;
890  }
891  } else {
892 
893  return false;
894  }
895  }
896  }
897 
898  return true;
899  }

◆ CountOccuranceInString()

template<class StringTypeN >
static int Leviathan::StringOperations::CountOccuranceInString ( const StringTypeN &  data,
const StringTypeN &  lookfor 
)
inlinestatic

Definition at line 514 of file StringOperations.h.

515  {
516  int count = 0;
517 
518  for(size_t i = 0; i < data.length(); i++) {
519  if(data[i] == lookfor[0]) {
520  // Found a possible match //
521  // test further //
522  size_t modifier = 0;
523  bool WasMatch = false;
524  while(data[i + modifier] == lookfor[modifier]) {
525  // check can it increase without going out of bounds //
526  if((data.length() > i + modifier + 1) &&
527  (lookfor.length() > modifier + 1)) {
528  // increase modifier to move forward //
529  modifier++;
530  } else {
531  // check is it a match
532  if(modifier + 1 == lookfor.length()) {
533  // found match! //
534  count++;
535  WasMatch = true;
536  break;
537  }
538  break;
539  }
540  }
541  // skip the separator amount of characters, if it was found //
542  if(WasMatch)
543  // -1 here so that first character of next string won't be missing,
544  // because of the loop incrementation
545  i += lookfor.length() - 1;
546  }
547  }
548 
549  return count;
550  }

◆ CutLines()

template<class StringTypeN >
static size_t Leviathan::StringOperations::CutLines ( const StringTypeN &  input,
std::vector< StringTypeN > &  output 
)
inlinestatic

Splits a string on line separators.

Definition at line 369 of file StringOperations.h.

370  {
371  if(input.empty())
372  return 0;
373 
374  size_t copystart = 0;
375  size_t copyend = 0;
376 
377  for(size_t i = 0; i < input.size(); i++) {
378  // Check is at a line separator
379  bool windows = input[i] == WINDOWS_LINE_SEPARATOR[0] && i + 1 < input.size() &&
380  input[i + 1] == WINDOWS_LINE_SEPARATOR[1];
381 
382  if(windows || (input[i] == UNIVERSAL_LINE_SEPARATOR[0])) {
383  // Check that previous character wasn't the beginning of
384  // a windows line separator. If it was this is already added
385  // and should be ignored
386  if(i > 0 && input[i - 1] == WINDOWS_LINE_SEPARATOR[0]) {
387 
388  // Skip adding this
389  continue;
390  }
391 
392  // Found a line separator //
393  // Copy the current thing //
394  if(copyend >= copystart && copystart - copyend > 1) {
395 
396  output.push_back(input.substr(copystart, copyend - copystart + 1));
397 
398  } else {
399  // There was an empty line //
400  output.push_back(StringTypeN());
401  }
402 
403  copystart = windows ? i + 2 : i + 1;
404  copyend = 0;
405 
406  continue;
407  }
408 
409  copyend = i;
410  }
411 
412  if(copyend >= copystart)
413  output.push_back(input.substr(copystart, copyend - copystart + 1));
414 
415  return output.size();
416  }
constexpr char UNIVERSAL_LINE_SEPARATOR[]
constexpr char WINDOWS_LINE_SEPARATOR[]

◆ CutString()

template<class StringTypeN >
static bool Leviathan::StringOperations::CutString ( const StringTypeN &  strtocut,
const StringTypeN &  separator,
std::vector< StringTypeN > &  vec 
)
inlinestatic

Definition at line 421 of file StringOperations.h.

423  {
424  // scan the input and gather positions for string copying //
425  std::vector<StartEndIndex> CopyOperations;
426  bool PositionStarted = false;
427 
428  for(size_t i = 0; i < strtocut.length(); i++) {
429  if(!PositionStarted) {
430  PositionStarted = true;
431  // add new position index //
432  CopyOperations.push_back(StartEndIndex(i));
433  }
434 
435  if(strtocut[i] == separator[0]) {
436  // Found a possible match //
437  // test further //
438  size_t modifier = 0;
439  bool WasMatch = false;
440  while(strtocut[i + modifier] == separator[modifier]) {
441  // check can it increase without going out of bounds //
442  if((strtocut.length() > i + modifier + 1) &&
443  (separator.length() > modifier + 1)) {
444  // increase modifier to move forward //
445  modifier++;
446  } else {
447  // check is it a match
448  if(modifier + 1 == separator.length()) {
449  // found match! //
450 
451  // end old string to just before this position //
452  CopyOperations.back().End = i; /*-1;
453  not this because we would have to
454  add 1 in the copy phase anyway */
455 
456  PositionStarted = false;
457  // skip separator //
458  WasMatch = true;
459  break;
460  }
461  break;
462  }
463  }
464 
465  // skip the separator amount of characters, if it was found //
466  if(WasMatch)
467  // -1 here so that first character of next string won't be missing,
468  // because of the loop incrementation
469  i += separator.length() - 1;
470  }
471  }
472 
473  // Return empty string if there is nothing here //
474  if(CopyOperations.empty()) {
475 
476  vec.push_back(StringTypeN());
477  return false;
478  }
479 
480  // make sure final position has end //
481  if(!CopyOperations.back().End)
482  CopyOperations.back().End = strtocut.length();
483 
484  if(CopyOperations.size() < 2) {
485 
486  vec.push_back(strtocut.substr(CopyOperations.front().Start,
487  static_cast<size_t>(CopyOperations.front().End) -
488  static_cast<size_t>(CopyOperations.front().Start)));
489 
490  // would be just one string, for legacy
491  // (actually we don't want caller to think it got cut) reasons we return nothing //
492  return false;
493  }
494 
495  // length-1 is not used here, because it would have to be added in copy phase to the
496  // substring length, and we didn't add that earlier...
497 
498  // make space //
499  vec.reserve(CopyOperations.size());
500 
501  // loop through positions and copy substrings to result vector //
502  for(size_t i = 0; i < CopyOperations.size(); i++) {
503  // copy using std::wstring method for speed //
504  vec.push_back(strtocut.substr(
505  CopyOperations[i].Start, static_cast<size_t>(CopyOperations[i].End) -
506  static_cast<size_t>(CopyOperations[i].Start)));
507  }
508 
509  // cutting succeeded //
510  return true;
511  }

◆ GetExtension()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::GetExtension ( const StringTypeN &  filepath)
inlinestatic

Definition at line 131 of file StringOperations.h.

132  {
133  size_t startcopy = 0;
134  size_t endcopy = filepath.size() - 1;
135 
136  size_t lastdot = filepath.find_last_of(DOT_CHARACTER);
137 
138  if(lastdot == StringTypeN::npos) {
139  // no dot //
140  return StringTypeN();
141  }
142 
143  startcopy = lastdot + 1;
144 
145  // Return empty if no data is valid //
146  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
147  return StringTypeN();
148 
149  // Return the extension //
150  return filepath.substr(startcopy, endcopy - startcopy + 1);
151  }
constexpr int32_t DOT_CHARACTER

◆ GetPath()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::GetPath ( const StringTypeN &  filepath)
inlinestatic

Returns the path part of a path+filename.

Definition at line 212 of file StringOperations.h.

213  {
214  size_t startcopy = 0;
215  size_t endcopy = filepath.size() - 1;
216 
217  // Find last path character //
218  size_t lastpath;
219  bool found = false;
220 
221  for(size_t i = 0; i < filepath.size(); i++) {
222  if(filepath[i] == UNIVERSAL_PATHSEPARATOR ||
223  filepath[i] == WINDOWS_PATHSEPARATOR) {
224  // Currently last found path //
225  lastpath = i;
226  found = true;
227  }
228  }
229 
230  if(!found) {
231  // Set start //
232  return StringTypeN();
233  }
234 
235  // Set up copy //
236  endcopy = lastpath;
237 
238 
239  // Return empty if no data is valid //
240  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
241  return StringTypeN();
242 
243 
244  // return the wanted part //
245  return filepath.substr(startcopy, endcopy - startcopy + 1);
246  }
constexpr int32_t UNIVERSAL_PATHSEPARATOR
constexpr int32_t WINDOWS_PATHSEPARATOR

◆ Indent()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::Indent ( size_t  numspaces)
inlinestatic

Definition at line 968 of file StringOperations.h.

969  {
970  if(!numspaces)
971  return StringTypeN();
972 
973  return StringTypeN(numspaces, static_cast<int>(' '));
974  }

◆ IndentLines()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::IndentLines ( const StringTypeN &  str,
size_t  spaces 
)
inlinestatic

Appends spaces number of spaces to each line in str and returns the result.

Definition at line 978 of file StringOperations.h.

979  {
980  const auto indentstr = Indent<StringTypeN>(spaces);
981 
982  StringTypeN result;
983  result.reserve(str.size());
984 
985  StartEndIndex currentcut;
986 
987  for(size_t i = 0; i < str.size(); ++i) {
988 
989  // Check for line change //
990  if(IsLineTerminator(str[i])) {
991 
992  result += indentstr;
993 
994  if(currentcut.Start)
995  result += str.substr(
996  currentcut.Start, i - static_cast<size_t>(currentcut.Start));
997 
998  result += "\n";
999  currentcut = StartEndIndex();
1000 
1001  // Multi character line terminator //
1002  if(i + 1 < str.length() && IsLineTerminator(str[i], str[i + 1]))
1003  ++i;
1004  }
1005 
1006  if(!currentcut.Start && !IsCharacterWhitespace(str[i])) {
1007 
1008  // Started a line //
1009  currentcut.Start = i;
1010  }
1011  }
1012 
1013  if(currentcut.Start) {
1014 
1015  currentcut.End = str.size();
1016 
1017  result += indentstr + str.substr(currentcut.Start, currentcut.Length());
1018  }
1019 
1020  return result;
1021  }
static bool IsLineTerminator(int32_t codepoint)
static bool IsCharacterWhitespace(CharType character)

◆ IsCharacterPathSeparator()

template<typename CharType >
static bool Leviathan::StringOperations::IsCharacterPathSeparator ( CharType  character)
inlinestatic

Definition at line 57 of file StringOperations.h.

58  {
59  if(character == UNIVERSAL_PATHSEPARATOR || character == WINDOWS_PATHSEPARATOR)
60  return true;
61 
62  return false;
63  }
constexpr int32_t UNIVERSAL_PATHSEPARATOR
constexpr int32_t WINDOWS_PATHSEPARATOR

◆ IsCharacterQuote()

template<typename CharType >
static bool Leviathan::StringOperations::IsCharacterQuote ( CharType  character)
inlinestatic

Definition at line 48 of file StringOperations.h.

49  {
50  if(character == '"' || character == '\'')
51  return true;
52 
53  return false;
54  }

◆ IsCharacterWhitespace()

template<typename CharType >
static bool Leviathan::StringOperations::IsCharacterWhitespace ( CharType  character)
inlinestatic

Definition at line 36 of file StringOperations.h.

37  {
38  if((int)character <= 32)
39  return true;
40 
41  if(IsLineTerminator(character))
42  return true;
43 
44  return false;
45  }
static bool IsLineTerminator(int32_t codepoint)

◆ IsLineTerminator() [1/2]

static bool Leviathan::StringOperations::IsLineTerminator ( int32_t  codepoint)
inlinestatic
Returns
True if a character is a line terminating character

Definition at line 1035 of file StringOperations.h.

1036  {
1037  if(codepoint == '\r' || codepoint == '\n' ||
1038  // Unicode newlines //
1039  codepoint == 0x0085 || codepoint == 0x2028 || codepoint == 0x2029 ||
1040  codepoint == 0x000B || codepoint == 0x000C) {
1041  return true;
1042  }
1043 
1044  return false;
1045  }

◆ IsLineTerminator() [2/2]

static bool Leviathan::StringOperations::IsLineTerminator ( int32_t  codepoint1,
int32_t  codepoint2 
)
inlinestatic
Returns
True if two characters are a line terminating sequence

Definition at line 1048 of file StringOperations.h.

1049  {
1050  if(codepoint1 == '\r' && codepoint2 == '\n') {
1051  return true;
1052  }
1053 
1054  return false;
1055  }

◆ IsStringNumeric()

template<class StringTypeN >
static bool Leviathan::StringOperations::IsStringNumeric ( const StringTypeN &  data)
inlinestatic

Definition at line 930 of file StringOperations.h.

931  {
932  for(size_t i = 0; i < data.size(); i++) {
933  if((data[i] < FIRST_NUMBER || data[i] > LAST_NUMBER) &&
934  data[i] != DASH_CHARACTER && data[i] != DOT_CHARACTER &&
935  data[i] != PLUS_SYMBOL) {
936  return false;
937  }
938  }
939  return true;
940  }
constexpr int32_t LAST_NUMBER
constexpr int32_t DOT_CHARACTER
constexpr int32_t DASH_CHARACTER
constexpr int32_t PLUS_SYMBOL
constexpr int32_t FIRST_NUMBER

◆ IsURLDomain()

DLLEXPORT bool StringOperations::IsURLDomain ( const std::string &  str)
static

Returns true if string looks like a top level domain.

Definition at line 176 of file StringOperations.cpp.

177 {
178  // Must have a dot
179  bool dotSeen = false;
180 
181  for(char c : str) {
182  if(c == '.') {
183  dotSeen = true;
184  continue;
185  }
186 
187  if(c >= '0' && c <= '9')
188  continue;
189 
190  if(c >= 'A' && c <= 'Z')
191  continue;
192 
193  if(c >= 'a' && c <= 'z')
194  continue;
195 
196  return false;
197  }
198 
199  return dotSeen;
200 }

◆ MakeString() [1/2]

DLLEXPORT void Leviathan::StringOperations::MakeString ( std::wstring &  str,
const char *  characters,
size_t  count 
)

Definition at line 7 of file StringOperations.cpp.

9 {
10  // Skip copying null terminator
11  const size_t copysize = count - 1;
12  str.resize(copysize);
13 
14  for(size_t i = 0; i < copysize; ++i)
15  str[i] = (wchar_t)characters[i];
16 }

◆ MakeString() [2/2]

template<class StringTypeN >
static void Leviathan::StringOperations::MakeString ( StringTypeN &  str,
const char *  characters,
size_t  count 
)
inlinestatic

Definition at line 68 of file StringOperations.h.

69  {
70  // Skip the null terminator //
71  str = StringTypeN(characters, count - 1);
72  }

◆ RemoveCharacters()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::RemoveCharacters ( const StringTypeN &  data,
const StringTypeN &  toremove 
)
inlinestatic

Definition at line 649 of file StringOperations.h.

650  {
651  StringTypeN out;
652  out.reserve(data.size());
653 
654  for(auto iter = data.begin(); iter != data.end(); ++iter) {
655 
656  // Check does it contain //
657  bool ignore = false;
658 
659  for(auto iter2 = toremove.begin(); iter2 != toremove.end(); ++iter2) {
660 
661  if((*iter2) == (*iter)) {
662 
663  ignore = true;
664  break;
665  }
666  }
667 
668  if(ignore)
669  continue;
670 
671  out.push_back(*iter);
672  }
673 
674  return out;
675  }

◆ RemoveEnding()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::RemoveEnding ( const StringTypeN &  str,
const StringTypeN &  ending 
)
inlinestatic

Definition at line 1024 of file StringOperations.h.

1025  {
1026  const auto pos = str.rfind(ending);
1027 
1028  if(pos != StringTypeN::npos && str.length() - pos == ending.length())
1029  return str.substr(0, pos);
1030 
1031  return str;
1032  }

◆ RemoveExtension()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::RemoveExtension ( const StringTypeN &  filepath,
bool  delpath = true 
)
inlinestatic

Definition at line 89 of file StringOperations.h.

90  {
91  size_t startcopy = 0;
92  size_t endcopy;
93 
94  size_t lastdot = filepath.find_last_of(DOT_CHARACTER);
95 
96  if(lastdot == StringTypeN::npos) {
97  // no dot //
98  endcopy = filepath.size() - 1;
99  } else {
100  endcopy = lastdot - 1;
101  }
102 
103  // Potentially erase from beginning //
104  if(delpath) {
105  // Find last path character //
106  size_t lastpath = 0;
107 
108  for(size_t i = 0; i < filepath.size(); i++) {
109  if(filepath[i] == UNIVERSAL_PATHSEPARATOR ||
110  filepath[i] == WINDOWS_PATHSEPARATOR) {
111  // Currently last found path //
112  lastpath = i;
113  }
114  }
115 
116  if(lastpath != 0) {
117  // Set start //
118  startcopy = lastpath + 1;
119  }
120  }
121 
122  // Return empty if no data is valid //
123  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
124  return StringTypeN();
125 
126  // return the wanted part //
127  return filepath.substr(startcopy, endcopy - startcopy + 1);
128  }
constexpr int32_t UNIVERSAL_PATHSEPARATOR
constexpr int32_t WINDOWS_PATHSEPARATOR
constexpr int32_t DOT_CHARACTER

◆ RemoveFirstWords()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::RemoveFirstWords ( const StringTypeN &  data,
int  amount 
)
inlinestatic

Definition at line 678 of file StringOperations.h.

679  {
680  size_t firstpos = 0;
681  // Find the copy start position //
682  int spaces = 0;
683  int words = 0;
684 
685  for(size_t i = 0; i < data.length(); i++) {
686  if(data[i] == SPACE_CHARACTER) {
687  spaces++;
688  continue;
689  }
690  if(spaces > 0) {
691  words++;
692  if(words == amount) {
693  // This is the spot we want to start from //
694  firstpos = i;
695  break;
696  }
697  spaces = 0;
698  }
699  }
700 
701  if(firstpos == 0) {
702  // Didn't remove anything? //
703  return data;
704  }
705 
706  // Generate sub string from start to end //
707  return data.substr(firstpos, data.size() - firstpos);
708  }
constexpr int32_t SPACE_CHARACTER

◆ RemovePartsBeforeAbsoluteURLParts()

DLLEXPORT std::string StringOperations::RemovePartsBeforeAbsoluteURLParts ( const std::string &  url)
static

Definition at line 144 of file StringOperations.cpp.

146 {
147  // Detect two '//'s in a path
148  const auto colonPos = url.find_first_of(':');
149 
150  if(colonPos != std::string::npos) {
151 
152  // First double slash
153  auto firstDouble = url.find("//", colonPos + 3);
154  // Second
155  const auto secondDouble = url.find("//", firstDouble + 2);
156 
157  if(firstDouble != std::string::npos && secondDouble != std::string::npos) {
158 
159  // If the part between the double slashes looks like a
160  // domain then we cut the part between the protocol and
161  // the first double slash
162  firstDouble += 2;
163 
164  if(IsURLDomain(url.substr(firstDouble, secondDouble - firstDouble))) {
165 
166  return URLProtocol(url) + "://" +
167  url.substr(firstDouble, secondDouble - firstDouble) + "/" +
168  url.substr(secondDouble + 2);
169  }
170  }
171  }
172 
173  return url;
174 }
static DLLEXPORT std::string URLProtocol(const std::string &url)
static DLLEXPORT bool IsURLDomain(const std::string &str)
Returns true if string looks like a top level domain.

◆ RemovePath()

template<class StringTypeN >
static const StringTypeN Leviathan::StringOperations::RemovePath ( const StringTypeN &  filepath)
inlinestatic

Definition at line 180 of file StringOperations.h.

181  {
182  size_t startcopy = 0;
183  size_t endcopy = filepath.size() - 1;
184 
185  // Find last path character //
186  size_t lastpath = 0;
187 
188  for(size_t i = 0; i < filepath.size(); i++) {
189  if(filepath[i] == UNIVERSAL_PATHSEPARATOR ||
190  filepath[i] == WINDOWS_PATHSEPARATOR) {
191  // Currently last found path //
192  lastpath = i;
193  }
194  }
195 
196  if(lastpath != 0) {
197  // Set start //
198  startcopy = lastpath + 1;
199  }
200 
201  // Return empty if no data is valid //
202  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
203  return StringTypeN();
204 
205 
206  // return the wanted part //
207  return filepath.substr(startcopy, endcopy - startcopy + 1);
208  }
constexpr int32_t UNIVERSAL_PATHSEPARATOR
constexpr int32_t WINDOWS_PATHSEPARATOR

◆ RemovePreceedingTrailingSpaces()

template<class StringTypeN >
static void Leviathan::StringOperations::RemovePreceedingTrailingSpaces ( StringTypeN &  str)
inlinestatic

Definition at line 811 of file StringOperations.h.

812  {
813  StartEndIndex CutPositions;
814 
815  // search the right part of the string //
816  for(size_t i = 0; i < str.size(); i++) {
817  if(!IsCharacterWhitespace(str[i])) {
818  if(!CutPositions.Start) {
819  // beginning ended //
820  CutPositions.Start = i;
821  } else {
822  // set last pos as this //
823  }
824  continue;
825  }
826  if(!CutPositions.Start) {
827  // still haven't found a character //
828  continue;
829  }
830  // check is this last character //
831  size_t a = str.size() - 1;
832  bool found = false;
833  for(; a > i; a--) {
834  if(!IsCharacterWhitespace(str[a])) {
835  // there is still valid characters //
836  found = true;
837  break;
838  }
839  }
840  if(found) {
841  // skip to the found non-space character //
842  i = a - 1;
843  continue;
844  }
845  // end found //
846  CutPositions.End = i - 1;
847  break;
848  }
849 
850  if(!CutPositions.Start) {
851  // nothing in the string //
852  str.clear();
853  return;
854  }
855  if(!CutPositions.End) {
856  if(!CutPositions.Start) {
857  // just the first character required //
858  CutPositions.End = CutPositions.Start;
859  } else {
860  // no need to cut from the end //
861  CutPositions.End = str.length() - 1;
862  }
863  }
864 
865  // set the wstring as it's sub string //
866  str = str.substr(CutPositions.Start, CutPositions.Length());
867  }
static bool IsCharacterWhitespace(CharType character)

◆ RemovePrefix()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::RemovePrefix ( const StringTypeN &  data,
const StringTypeN &  prefix 
)
inlinestatic

Definition at line 711 of file StringOperations.h.

712  {
713  if(data.find(prefix) == 0) {
714  return data.substr(prefix.size());
715  } else {
716  return data;
717  }
718  }

◆ RepeatCharacter()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::RepeatCharacter ( int  character,
size_t  count 
)
inlinestatic

Definition at line 75 of file StringOperations.h.

76  {
77  StringTypeN result;
78 
79  result.resize(count);
80 
81  for(size_t i = 0; i < count; ++i)
82  result[i] = character;
83 
84  return result;
85  }

◆ Replace()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::Replace ( const StringTypeN &  data,
const StringTypeN &  toreplace,
const StringTypeN &  replacer 
)
inlinestatic

Definition at line 553 of file StringOperations.h.

555  {
556  // We construct an output string from the wanted bits //
557  StringTypeN out;
558 
559  if(toreplace.size() < 1) {
560  // Don't replace anything //
561  return data;
562  }
563 
564  PotentiallySetIndex copystart;
565  PotentiallySetIndex copyend;
566 
567  // loop through data and copy final characters to out string //
568  for(size_t i = 0; i < data.size(); i++) {
569  // check for replaced part //
570  if(data[i] == toreplace[0]) {
571  // check for match //
572  bool IsMatch = false;
573  for(size_t checkind = 0;
574  (checkind < toreplace.size()) && (checkind < data.size()); checkind++) {
575  if(data[i + checkind] != toreplace[checkind]) {
576  // didn't match //
577  break;
578  }
579  // check is final iteration //
580  if(!((checkind + 1 < toreplace.size()) && (checkind + 1 < data.size()))) {
581  // is a match //
582  IsMatch = true;
583  break;
584  }
585  }
586 
587  if(IsMatch || toreplace.size() == 1) {
588 
589  if(copystart && !copyend)
590  copyend = copystart;
591 
592  // First add proper characters //
593  if(copystart && copyend)
594  out += data.substr(copystart,
595  static_cast<size_t>(copyend) - static_cast<size_t>(copystart) + 1);
596 
597  copystart.ValueSet = false;
598  copyend.ValueSet = false;
599 
600  // it is a match, copy everything in replacer and
601  // add toreplace length to i
602  out += replacer;
603 
604  i += toreplace.length() - 1;
605  continue;
606  }
607  }
608 
609  // non matching character mark as to copy //
610  if(!copystart) {
611  copystart = i;
612  } else {
613  copyend = i;
614  }
615  }
616 
617  // Copy rest to out //
618  if(copystart && copyend)
619  out += data.substr(
620  copystart, static_cast<size_t>(copyend) - static_cast<size_t>(copystart) + 1);
621 
622  // Return finished string //
623  return out;
624  }

◆ ReplaceSingleCharacter()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::ReplaceSingleCharacter ( const StringTypeN &  data,
int  toreplace,
int  replacer = ' ' 
)
inlinestatic

Definition at line 628 of file StringOperations.h.

630  {
631  // Copy the string and then modify it //
632  StringTypeN out(data);
633  ReplaceSingleCharacterInPlace(out, toreplace, replacer);
634 
635  return out;
636  }
static void ReplaceSingleCharacterInPlace(StringTypeN &data, int toreplace, int replacer=' ')

◆ ReplaceSingleCharacterInPlace()

template<class StringTypeN >
static void Leviathan::StringOperations::ReplaceSingleCharacterInPlace ( StringTypeN &  data,
int  toreplace,
int  replacer = ' ' 
)
inlinestatic

Definition at line 639 of file StringOperations.h.

641  {
642  for(auto iter = data.begin(); iter != data.end(); ++iter) {
643  if((*iter) == toreplace)
644  (*iter) = replacer;
645  }
646  }

◆ StitchTogether() [1/3]

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::StitchTogether ( const std::vector< StringTypeN * > &  data,
const StringTypeN &  separator 
)
inlinestatic

Definition at line 721 of file StringOperations.h.

723  {
724  StringTypeN ret;
725  bool first = true;
726  // reserve space //
727  int totalcharacters = 0;
728 
729  // This might be faster than not reserving space //
730  for(size_t i = 0; i < data.size(); i++) {
731  totalcharacters += data[i]->length();
732  }
733 
734  totalcharacters += separator.length() * data.size();
735 
736  // By reserving space we don't have to allocate more memory
737  // during copying which might be faster
738  ret.reserve(totalcharacters);
739 
740  for(size_t i = 0; i < data.size(); i++) {
741  if(!first)
742  ret += separator;
743  ret += *data[i];
744  first = false;
745  }
746 
747  return ret;
748  }

◆ StitchTogether() [2/3]

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::StitchTogether ( const std::vector< StringTypeN > &  data,
const StringTypeN &  separator 
)
inlinestatic

Definition at line 751 of file StringOperations.h.

753  {
754  StringTypeN ret;
755  bool first = true;
756  // reserve space //
757  int totalcharacters = 0;
758 
759  // This might be faster than not reserving space //
760  for(size_t i = 0; i < data.size(); i++) {
761  totalcharacters += data[i].length();
762  }
763 
764  totalcharacters += separator.length() * data.size();
765 
766  // By reserving space we don't have to allocate more memory
767  // during copying which might be faster
768  ret.reserve(totalcharacters);
769 
770  for(size_t i = 0; i < data.size(); i++) {
771  if(!first)
772  ret += separator;
773  ret += data[i];
774  first = false;
775  }
776 
777  return ret;
778  }

◆ StitchTogether() [3/3]

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::StitchTogether ( const std::vector< std::shared_ptr< StringTypeN >> &  data,
const StringTypeN &  separator 
)
inlinestatic

Definition at line 782 of file StringOperations.h.

784  {
785  StringTypeN ret;
786  bool first = true;
787  // reserve space //
788  int totalcharacters = 0;
789 
790  // This might be faster than not reserving space //
791  for(size_t i = 0; i < data.size(); i++) {
792  totalcharacters += data[i]->length();
793  }
794  totalcharacters += separator.length() * data.size();
795 
796  // By reserving space we don't have to allocate more memory during
797  // copying which might be faster
798  ret.reserve(totalcharacters);
799 
800  for(size_t i = 0; i < data.size(); i++) {
801  if(!first)
802  ret += separator;
803  ret += *data[i].get();
804  first = false;
805  }
806 
807  return ret;
808  }

◆ StringEndsWith()

template<class StringTypeN >
static bool Leviathan::StringOperations::StringEndsWith ( const StringTypeN &  data,
const StringTypeN &  tomatch 
)
inlinestatic

Definition at line 908 of file StringOperations.h.

909  {
910  if(data.size() < tomatch.size())
911  return false;
912 
913  if(data.empty())
914  return true;
915 
916  for(size_t i = data.size() - 1, checkIndex = 0; checkIndex < tomatch.size();
917  --i, ++checkIndex) {
918 
919  if(data[i] != tomatch[tomatch.size() - 1 - checkIndex])
920  return false;
921 
922  if(i == 0)
923  return true;
924  }
925 
926  return true;
927  }

◆ StringStartsWith()

template<class StringTypeN >
static bool Leviathan::StringOperations::StringStartsWith ( const StringTypeN &  data,
const StringTypeN &  tomatch 
)
inlinestatic

Definition at line 902 of file StringOperations.h.

903  {
904  return data.find(tomatch) == 0;
905  }

◆ ToUpperCase()

template<class StringTypeN >
static StringTypeN Leviathan::StringOperations::ToUpperCase ( const StringTypeN &  data)
inlinestatic
Todo:
Make this work with any unicode characters

Definition at line 944 of file StringOperations.h.

945  {
946  StringTypeN result;
947  result.reserve(data.size());
948 
949  for(size_t i = 0; i < data.size(); i++) {
950 
951  // Not actually unicode decoding...
952  auto const codepoint = data[i];
953 
954  if(97 <= codepoint && codepoint <= 122) {
955 
956  result.push_back(codepoint - 32);
957 
958  } else {
959 
960  result.push_back(codepoint);
961  }
962  }
963 
964  return result;
965  }

◆ URLPath()

DLLEXPORT std::string StringOperations::URLPath ( const std::string &  url,
bool  stripoptions = true 
)
static

Definition at line 60 of file StringOperations.cpp.

62 {
63  if(url.empty())
64  return "";
65 
66  // Start scanning until a '/' is found that is not preceeded by ':' or '/'
67  size_t startCopy = 0;
68 
69  for(size_t i = 0; i < url.size(); ++i) {
70 
71  if(url[i] == '/') {
72 
73  if(i < 1)
74  continue;
75 
76  if(url[i - 1] == ':' || url[i - 1] == '/')
77  continue;
78 
79  // found it //
80  startCopy = i + 1;
81  break;
82  }
83  }
84 
85  // Make sure the string doesn't end there
86  if(startCopy >= url.size())
87  return "";
88 
89  size_t endCopy = url.size();
90 
91  // Scan backwards for cutting options
92  if(stripoptions) {
93  for(size_t cut = endCopy; cut > startCopy; --cut) {
94  if(url[cut] == '?') {
95  // Found options
96  endCopy = cut;
97  break;
98  }
99  }
100  }
101 
102  return url.substr(startCopy, endCopy - startCopy);
103 }

◆ URLProtocol()

DLLEXPORT std::string StringOperations::URLProtocol ( const std::string &  url)
static

Definition at line 18 of file StringOperations.cpp.

19 {
20  const auto colonpos = url.find_first_of(':');
21 
22  if(colonpos == std::string::npos)
23  return "";
24 
25  return url.substr(0, colonpos);
26 }

The documentation for this class was generated from the following files: