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<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, const StringTypeN &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 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 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 146 of file StringOperations.h.

148  {
149  size_t startcopy = 0;
150  size_t endcopy = filepath.size() - 1;
151 
152  size_t lastdot = filepath.find_last_of(DOT_CHARACTER);
153 
154  if(lastdot != StringTypeN::npos) {
155  // dot found //
156  endcopy = lastdot;
157 
158  } else {
159  // No dot, so just append it //
160  return filepath + newext;
161  }
162 
163  // Return empty if no data is valid //
164  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
165  return StringTypeN();
166 
167  // Return the extension //
168  return filepath.substr(startcopy, endcopy - startcopy + 1) + newext;
169  }
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 317 of file StringOperations.h.

318  {
319  StringTypeN results;
320 
321  // This is the line ending sequence //
322  StringTypeN separator;
324 
325  // Try to find path strings and replace them //
326  size_t copystart = 0;
327  size_t copyend = 0;
328 
329  for(size_t i = 0; i < input.size(); i++) {
330  if(input[i] == WINDOWS_LINE_SEPARATOR[0] && i + 1 < input.size() &&
331  input[i + 1] == WINDOWS_LINE_SEPARATOR[1]) {
332  // Found a line separator //
333  // Copy the current thing //
334  if(copyend >= copystart && copystart - copyend > 1)
335  results += input.substr(copystart, copyend - copystart + 1);
336 
337 
338  results += separator;
339 
340  copystart = i + 2 < input.size() ? i + 2 : i;
341  copyend = copystart;
342 
343  i += 2;
344 
345  continue;
346  }
347 
348  // Change the end copy //
349  copyend = i;
350  }
351 
352  if(copyend >= copystart && copystart - copyend > 1)
353  results += input.substr(copystart, copyend - copystart + 1);
354 
355 
356  return results;
357  }
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 274 of file StringOperations.h.

275  {
276  StringTypeN results;
277 
278  // This is the line ending sequence //
279  StringTypeN separator;
281 
282  // Try to find path strings and replace them //
283  StartEndIndex copyparts;
284 
285  for(size_t i = 0; i < input.size(); i++) {
286  if(input[i] == UNIVERSAL_LINE_SEPARATOR[0]
287  // Previous character wasn't the first character of a windows line separator.
288  // If it was this is already the correct line separator and should be ignored
289  && (i == 0 || input[i - 1] != WINDOWS_LINE_SEPARATOR[0])) {
290  // Found a line separator //
291  // Copy the current thing //
292  if(copyparts.Start && copyparts.End)
293  results += input.substr(copyparts.Start, copyparts.Length());
294 
295  copyparts.Reset();
296 
297  results += separator;
298 
299  continue;
300  }
301 
302  if(!copyparts.Start)
303  copyparts.Start = i;
304 
305  // Change the end copy //
306  copyparts.End = i;
307  }
308 
309  if(copyparts.End && copyparts.Start)
310  results += input.substr(copyparts.Start, copyparts.Length());
311 
312  return results;
313  }
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 859 of file StringOperations.h.

860  {
861  if(data.size() != second.size())
862  return false;
863 
864  for(unsigned int i = 0; i < data.size(); i++) {
865  if(data[i] != second[i]) {
866 
867  // Check are they different case //
868  if(97 <= data[i] && data[i] <= 122) {
869 
870  if(data[i] - 32 != second[i]) {
871 
872  return false;
873  }
874  } else if(97 <= second[i] && second[i] <= 122) {
875 
876  if(second[i] - 32 != data[i]) {
877 
878  return false;
879  }
880  } else {
881 
882  return false;
883  }
884  }
885  }
886 
887  return true;
888  }

◆ CountOccuranceInString()

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

Definition at line 506 of file StringOperations.h.

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

◆ 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 361 of file StringOperations.h.

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

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

◆ GetExtension()

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

Definition at line 123 of file StringOperations.h.

124  {
125  size_t startcopy = 0;
126  size_t endcopy = filepath.size() - 1;
127 
128  size_t lastdot = filepath.find_last_of(DOT_CHARACTER);
129 
130  if(lastdot == StringTypeN::npos) {
131  // no dot //
132  return StringTypeN();
133  }
134 
135  startcopy = lastdot + 1;
136 
137  // Return empty if no data is valid //
138  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
139  return StringTypeN();
140 
141  // Return the extension //
142  return filepath.substr(startcopy, endcopy - startcopy + 1);
143  }
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 204 of file StringOperations.h.

205  {
206  size_t startcopy = 0;
207  size_t endcopy = filepath.size() - 1;
208 
209  // Find last path character //
210  size_t lastpath;
211  bool found = false;
212 
213  for(size_t i = 0; i < filepath.size(); i++) {
214  if(filepath[i] == UNIVERSAL_PATHSEPARATOR ||
215  filepath[i] == WINDOWS_PATHSEPARATOR) {
216  // Currently last found path //
217  lastpath = i;
218  found = true;
219  }
220  }
221 
222  if(!found) {
223  // Set start //
224  return StringTypeN();
225  }
226 
227  // Set up copy //
228  endcopy = lastpath;
229 
230 
231  // Return empty if no data is valid //
232  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
233  return StringTypeN();
234 
235 
236  // return the wanted part //
237  return filepath.substr(startcopy, endcopy - startcopy + 1);
238  }
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 935 of file StringOperations.h.

936  {
937  if(!numspaces)
938  return StringTypeN();
939 
940  return StringTypeN(numspaces, static_cast<int>(' '));
941  }

◆ 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 945 of file StringOperations.h.

946  {
947  const auto indentstr = Indent<StringTypeN>(spaces);
948 
949  StringTypeN result;
950  result.reserve(str.size());
951 
952  StartEndIndex currentcut;
953 
954  for(size_t i = 0; i < str.size(); ++i) {
955 
956  // Check for line change //
957  if(IsLineTerminator(str[i])) {
958 
959  result += indentstr;
960 
961  if(currentcut.Start)
962  result += str.substr(
963  currentcut.Start, i - static_cast<size_t>(currentcut.Start));
964 
965  result += "\n";
966  currentcut = StartEndIndex();
967 
968  // Multi character line terminator //
969  if(i + 1 < str.length() && IsLineTerminator(str[i], str[i + 1]))
970  ++i;
971  }
972 
973  if(!currentcut.Start && !IsCharacterWhitespace(str[i])) {
974 
975  // Started a line //
976  currentcut.Start = i;
977  }
978  }
979 
980  if(currentcut.Start) {
981 
982  currentcut.End = str.size();
983 
984  result += indentstr + str.substr(currentcut.Start, currentcut.Length());
985  }
986 
987  return result;
988  }
static bool IsLineTerminator(int32_t codepoint)
static bool IsCharacterWhitespace(CharType character)

◆ IsCharacterQuote()

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

Definition at line 48 of file StringOperations.h.

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

◆ 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 1002 of file StringOperations.h.

1003  {
1004  if(codepoint == '\r' || codepoint == '\n' ||
1005  // Unicode newlines //
1006  codepoint == 0x0085 || codepoint == 0x2028 || codepoint == 0x2029 ||
1007  codepoint == 0x000B || codepoint == 0x000C) {
1008  return true;
1009  }
1010 
1011  return false;
1012  }

◆ 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 1015 of file StringOperations.h.

1016  {
1017  if(codepoint1 == '\r' && codepoint2 == '\n') {
1018  return true;
1019  }
1020 
1021  return false;
1022  }

◆ IsStringNumeric()

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

Definition at line 897 of file StringOperations.h.

898  {
899  for(size_t i = 0; i < data.size(); i++) {
900  if((data[i] < FIRST_NUMBER || data[i] > LAST_NUMBER) &&
901  data[i] != DASH_CHARACTER && data[i] != DOT_CHARACTER &&
902  data[i] != PLUS_SYMBOL) {
903  return false;
904  }
905  }
906  return true;
907  }
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 60 of file StringOperations.h.

61  {
62  // Skip the null terminator //
63  str = StringTypeN(characters, count - 1);
64  }

◆ RemoveCharacters()

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

Definition at line 648 of file StringOperations.h.

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

◆ RemoveEnding()

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

Definition at line 991 of file StringOperations.h.

992  {
993  const auto pos = str.rfind(ending);
994 
995  if(pos != StringTypeN::npos && str.length() - pos == ending.length())
996  return str.substr(0, pos);
997 
998  return str;
999  }

◆ RemoveExtension()

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

Definition at line 81 of file StringOperations.h.

82  {
83  size_t startcopy = 0;
84  size_t endcopy;
85 
86  size_t lastdot = filepath.find_last_of(DOT_CHARACTER);
87 
88  if(lastdot == StringTypeN::npos) {
89  // no dot //
90  endcopy = filepath.size() - 1;
91  } else {
92  endcopy = lastdot - 1;
93  }
94 
95  // Potentially erase from beginning //
96  if(delpath) {
97  // Find last path character //
98  size_t lastpath = 0;
99 
100  for(size_t i = 0; i < filepath.size(); i++) {
101  if(filepath[i] == UNIVERSAL_PATHSEPARATOR ||
102  filepath[i] == WINDOWS_PATHSEPARATOR) {
103  // Currently last found path //
104  lastpath = i;
105  }
106  }
107 
108  if(lastpath != 0) {
109  // Set start //
110  startcopy = lastpath + 1;
111  }
112  }
113 
114  // Return empty if no data is valid //
115  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
116  return StringTypeN();
117 
118  // return the wanted part //
119  return filepath.substr(startcopy, endcopy - startcopy + 1);
120  }
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 677 of file StringOperations.h.

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

173  {
174  size_t startcopy = 0;
175  size_t endcopy = filepath.size() - 1;
176 
177  // Find last path character //
178  size_t lastpath = 0;
179 
180  for(size_t i = 0; i < filepath.size(); i++) {
181  if(filepath[i] == UNIVERSAL_PATHSEPARATOR ||
182  filepath[i] == WINDOWS_PATHSEPARATOR) {
183  // Currently last found path //
184  lastpath = i;
185  }
186  }
187 
188  if(lastpath != 0) {
189  // Set start //
190  startcopy = lastpath + 1;
191  }
192 
193  // Return empty if no data is valid //
194  if(startcopy > endcopy || startcopy >= filepath.size() || endcopy >= filepath.size())
195  return StringTypeN();
196 
197 
198  // return the wanted part //
199  return filepath.substr(startcopy, endcopy - startcopy + 1);
200  }
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 800 of file StringOperations.h.

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

◆ RepeatCharacter()

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

Definition at line 67 of file StringOperations.h.

68  {
69  StringTypeN result;
70 
71  result.resize(count);
72 
73  for(size_t i = 0; i < count; ++i)
74  result[i] = character;
75 
76  return result;
77  }

◆ Replace()

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

Definition at line 545 of file StringOperations.h.

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

◆ ReplaceSingleCharacter()

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

Definition at line 620 of file StringOperations.h.

622  {
623  // Copy the string and then modify it //
624  StringTypeN out(data);
625 
626  for(auto iter = out.begin(); iter != out.end(); ++iter) {
627 
628  // Check does it contain //
629  bool replace = false;
630 
631  for(auto iter2 = toreplace.begin(); iter2 != toreplace.end(); ++iter2) {
632 
633  if((*iter2) == (*iter)) {
634 
635  replace = true;
636  break;
637  }
638  }
639 
640  if(replace)
641  (*iter) = replacer;
642  }
643 
644  return out;
645  }

◆ StitchTogether() [1/3]

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

Definition at line 710 of file StringOperations.h.

712  {
713  StringTypeN ret;
714  bool first = true;
715  // reserve space //
716  int totalcharacters = 0;
717 
718  // This might be faster than not reserving space //
719  for(size_t i = 0; i < data.size(); i++) {
720  totalcharacters += data[i]->length();
721  }
722 
723  totalcharacters += separator.length() * data.size();
724 
725  // By reserving space we don't have to allocate more memory
726  // during copying which might be faster
727  ret.reserve(totalcharacters);
728 
729  for(size_t i = 0; i < data.size(); i++) {
730  if(!first)
731  ret += separator;
732  ret += *data[i];
733  first = false;
734  }
735 
736  return ret;
737  }

◆ StitchTogether() [2/3]

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

Definition at line 740 of file StringOperations.h.

742  {
743  StringTypeN ret;
744  bool first = true;
745  // reserve space //
746  int totalcharacters = 0;
747 
748  // This might be faster than not reserving space //
749  for(size_t i = 0; i < data.size(); i++) {
750  totalcharacters += data[i].length();
751  }
752 
753  totalcharacters += separator.length() * data.size();
754 
755  // By reserving space we don't have to allocate more memory
756  // during copying which might be faster
757  ret.reserve(totalcharacters);
758 
759  for(size_t i = 0; i < data.size(); i++) {
760  if(!first)
761  ret += separator;
762  ret += data[i];
763  first = false;
764  }
765 
766  return ret;
767  }

◆ 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 771 of file StringOperations.h.

773  {
774  StringTypeN ret;
775  bool first = true;
776  // reserve space //
777  int totalcharacters = 0;
778 
779  // This might be faster than not reserving space //
780  for(size_t i = 0; i < data.size(); i++) {
781  totalcharacters += data[i]->length();
782  }
783  totalcharacters += separator.length() * data.size();
784 
785  // By reserving space we don't have to allocate more memory during
786  // copying which might be faster
787  ret.reserve(totalcharacters);
788 
789  for(size_t i = 0; i < data.size(); i++) {
790  if(!first)
791  ret += separator;
792  ret += *data[i].get();
793  first = false;
794  }
795 
796  return ret;
797  }

◆ StringStartsWith()

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

Definition at line 891 of file StringOperations.h.

892  {
893  return data.find(tomatch) == 0;
894  }

◆ ToUpperCase()

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

Definition at line 911 of file StringOperations.h.

912  {
913  StringTypeN result;
914  result.reserve(data.size());
915 
916  for(size_t i = 0; i < data.size(); i++) {
917 
918  // Not actually unicode decoding...
919  auto const codepoint = data[i];
920 
921  if(97 <= codepoint && codepoint <= 122) {
922 
923  result.push_back(codepoint - 32);
924 
925  } else {
926 
927  result.push_back(codepoint);
928  }
929  }
930 
931  return result;
932  }

◆ 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: