Last active
February 20, 2024 15:43
-
-
Save HoShiMin/a343dfea70239073832b6c4b10427b39 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define WIN32_LEAN_AND_MEAN | |
#define WIN32_NO_STATUS | |
#include <windows.h> | |
#undef WIN32_NO_STATUS | |
#include <string> | |
#include <sstream> | |
#include <iomanip> | |
#include <algorithm> | |
#include <vector> | |
#include <set> | |
#include <winternl.h> | |
namespace StringsAPI { | |
std::string AnsiStringToString(PCANSI_STRING AnsiString) { | |
if (!AnsiString | |
|| !AnsiString->Buffer | |
|| !AnsiString->Length | |
|| !AnsiString->MaximumLength | |
|| AnsiString->MaximumLength < AnsiString->Length | |
) return std::string(); | |
return std::string(AnsiString->Buffer, AnsiString->Length / sizeof(CHAR)); | |
} | |
std::wstring UnicodeStringToString(PCUNICODE_STRING UnicodeString) { | |
if (!UnicodeString | |
|| !UnicodeString->Buffer | |
|| !UnicodeString->Length | |
|| !UnicodeString->MaximumLength | |
|| UnicodeString->MaximumLength < UnicodeString->Length | |
) return std::wstring(); | |
return std::wstring(UnicodeString->Buffer, UnicodeString->Length / sizeof(WCHAR)); | |
} | |
std::string LowerCase(std::string String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower); | |
return String; | |
} | |
std::wstring LowerCase(std::wstring String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower); | |
return String; | |
} | |
void LowerCaseRef(std::string& String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower); | |
} | |
void LowerCaseRef(std::wstring& String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::tolower); | |
} | |
std::string UpperCase(std::string String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper); | |
return String; | |
} | |
std::wstring UpperCase(std::wstring String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper); | |
return String; | |
} | |
void UpperCaseRef(std::string& String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper); | |
} | |
void UpperCaseRef(std::wstring& String) { | |
std::transform(String.cbegin(), String.cend(), String.begin(), ::toupper); | |
} | |
bool StartsWith(const std::string& String, const std::string& Beginning) { | |
return (Beginning.size() <= String.size()) && std::equal(Beginning.begin(), Beginning.end(), String.begin()); | |
} | |
bool StartsWith(const std::wstring& String, const std::wstring& Beginning) { | |
return (Beginning.size() <= String.size()) && std::equal(Beginning.begin(), Beginning.end(), String.begin()); | |
} | |
bool EndsWith(const std::string& String, const std::string& Ending) { | |
return (Ending.size() <= String.size()) && std::equal(Ending.rbegin(), Ending.rend(), String.rbegin()); | |
} | |
bool EndsWith(const std::wstring& String, const std::wstring& Ending) { | |
return (Ending.size() <= String.size()) && std::equal(Ending.rbegin(), Ending.rend(), String.rbegin()); | |
} | |
std::string FillLeft(const std::string& String, unsigned char Length, char Filler) { | |
std::ostringstream OutputStringStream; | |
OutputStringStream << std::right << std::setfill(Filler) << std::setw(Length) << String; | |
return std::string(OutputStringStream.str()); | |
} | |
std::wstring FillLeft(const std::wstring& String, unsigned char Length, wchar_t Filler) { | |
std::wostringstream OutputStringStream; | |
OutputStringStream << std::right << std::setfill(Filler) << std::setw(Length) << String; | |
return OutputStringStream.str(); | |
} | |
std::string FillRight(const std::string& String, unsigned char Length, char Filler) { | |
std::ostringstream OutputStringStream; | |
OutputStringStream << std::left << std::setfill(Filler) << std::setw(Length) << String; | |
return OutputStringStream.str(); | |
} | |
std::wstring FillRight(const std::wstring& String, unsigned char Length, wchar_t Filler) { | |
std::wostringstream OutputStringStream; | |
OutputStringStream << std::left << std::setfill(Filler) << std::setw(Length) << String; | |
return OutputStringStream.str(); | |
} | |
std::wstring AnsiToWide(const std::string& Ansi) { | |
if (Ansi.empty()) return std::wstring(); | |
int BufferSize = MultiByteToWideChar( | |
CP_ACP, | |
MB_PRECOMPOSED, | |
Ansi.c_str(), | |
-1, | |
NULL, | |
0 | |
); | |
if (BufferSize < 2) return std::wstring(); | |
std::wstring Wide(BufferSize, NULL); | |
BufferSize = MultiByteToWideChar( | |
CP_ACP, | |
MB_PRECOMPOSED, | |
Ansi.c_str(), | |
-1, | |
&Wide[0], | |
BufferSize | |
); | |
if (BufferSize < 2) return std::wstring(); | |
Wide.resize(static_cast<size_t>(BufferSize) - 1); | |
return Wide; | |
} | |
std::string WideToAnsi(const std::wstring& Wide) { | |
if (Wide.empty()) return std::string(); | |
int BufferSize = WideCharToMultiByte( | |
CP_ACP, | |
WC_COMPOSITECHECK | WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR, | |
Wide.c_str(), | |
-1, | |
NULL, | |
0, | |
NULL, | |
NULL | |
); | |
if (BufferSize < 2) return std::string(); | |
std::string Ansi(BufferSize, NULL); | |
BufferSize = WideCharToMultiByte( | |
CP_ACP, | |
WC_COMPOSITECHECK | WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR, | |
Wide.c_str(), | |
-1, | |
&Ansi[0], | |
BufferSize, | |
NULL, | |
NULL | |
); | |
if (BufferSize < 2) return std::string(); | |
Ansi.resize(static_cast<size_t>(BufferSize) - 1); | |
return Ansi; | |
} | |
std::string IntToAnsi(int Value, int Radix) { | |
char Buf[34]; | |
Buf[0] = 0x00; | |
_itoa_s(Value, Buf, sizeof(Buf), Radix); | |
return Buf; | |
} | |
std::string Int64ToAnsi(long long Value, int Radix) { | |
char Buf[66]; | |
Buf[0] = 0x00; | |
_i64toa_s(Value, Buf, sizeof(Buf), Radix); | |
return Buf; | |
} | |
std::string UInt64ToAnsi(unsigned long long Value, int Radix) { | |
char Buf[66]; | |
Buf[0] = 0x00; | |
_ui64toa_s(Value, Buf, sizeof(Buf), Radix); | |
return Buf; | |
} | |
std::wstring IntToWide(int Value, int Radix) { | |
wchar_t Buf[34]; | |
Buf[0] = 0x00; | |
_itow_s(Value, Buf, sizeof(Buf) / sizeof(*Buf), Radix); | |
return Buf; | |
} | |
std::wstring Int64ToWide(long long Value, int Radix) { | |
wchar_t Buf[66]; | |
Buf[0] = 0x00; | |
_i64tow_s(Value, Buf, sizeof(Buf) / sizeof(*Buf), Radix); | |
return Buf; | |
} | |
std::wstring UInt64ToWide(unsigned long long Value, int Radix) { | |
wchar_t Buf[66]; | |
Buf[0] = 0x00; | |
_ui64tow_s(Value, Buf, sizeof(Buf) / sizeof(*Buf), Radix); | |
return Buf; | |
} | |
std::string PtrToAnsi(const void* Ptr) { | |
#ifdef _AMD64_ | |
return UInt64ToAnsi(reinterpret_cast<unsigned long long>(Ptr), 16); | |
#else | |
return IntToAnsi(reinterpret_cast<int>(Ptr), 16); | |
#endif | |
} | |
std::wstring PtrToWide(const void* Ptr) { | |
#ifdef _AMD64_ | |
return UInt64ToWide(reinterpret_cast<unsigned long long>(Ptr), 16); | |
#else | |
return IntToWide(reinterpret_cast<int>(Ptr), 16); | |
#endif | |
} | |
std::string BufToAnsiHex(const void* Ptr, size_t Size, bool InsertSpaces) { | |
char Buf[4]; | |
std::string Result; | |
Result.reserve(Size * (InsertSpaces ? 3 : 2)); | |
for (size_t i = 0; i < Size; ++i) { | |
unsigned char c = *(reinterpret_cast<const unsigned char*>(Ptr) + i); | |
_itoa_s(c, Buf, sizeof(Buf), 16); | |
if (Buf[1] == 0x00) { | |
Buf[1] = Buf[0]; | |
Buf[0] = '0'; | |
} | |
Buf[2] = 0x00; | |
if (InsertSpaces && i != 0) Result.append(" ", 1); | |
Result.append(Buf, 2); | |
} | |
return Result; | |
} | |
std::wstring BufToWideHex(const void* Ptr, size_t Size, bool InsertSpaces) { | |
wchar_t Buf[4]; | |
std::wstring Result; | |
Result.reserve(Size * (InsertSpaces ? 3 : 2)); | |
for (size_t i = 0; i < Size; ++i) { | |
unsigned char c = *(reinterpret_cast<const unsigned char*>(Ptr) + i); | |
_itow_s(c, Buf, sizeof(Buf) / sizeof(*Buf), 16); | |
if (Buf[1] == 0x00) { | |
Buf[1] = Buf[0]; | |
Buf[0] = L'0'; | |
} | |
Buf[2] = 0x00; | |
if (InsertSpaces && i != 0) Result.append(L" ", 1); | |
Result.append(Buf, 2); | |
} | |
return Result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/* | |
Depends on: | |
- string | |
- vector (optional) | |
- set (optional) | |
- winternl.h (optional) | |
*/ | |
#define DECLARE_TSTRING | |
#ifdef DECLARE_TSTRING | |
namespace std { | |
typedef basic_string<TCHAR> tstring; | |
} | |
#endif | |
namespace StringsAPI { | |
#ifdef _WINTERNL_ | |
std::string AnsiStringToString(PCANSI_STRING AnsiString); | |
std::wstring UnicodeStringToString(PCUNICODE_STRING UnicodeString); | |
#endif | |
std::string LowerCase(__in std::string String); | |
std::wstring LowerCase(__in std::wstring String); | |
void LowerCaseRef(__inout std::string& String); | |
void LowerCaseRef(__inout std::wstring& String); | |
std::string UpperCase(__in std::string String); | |
std::wstring UpperCase(__in std::wstring String); | |
void UpperCaseRef(__inout std::string& String); | |
void UpperCaseRef(__inout std::wstring& String); | |
bool StartsWith(const std::string& String, const std::string& Beginning); | |
bool StartsWith(const std::wstring& String, const std::wstring& Beginning); | |
bool EndsWith(const std::string& String, const std::string& Ending); | |
bool EndsWith(const std::wstring& String, const std::wstring& Ending); | |
std::string FillLeft(const std::string& String, unsigned char Length, char Filler); | |
std::wstring FillLeft(const std::wstring& String, unsigned char Length, wchar_t Filler); | |
std::string FillRight(const std::string& String, unsigned char Length, char Filler); | |
std::wstring FillRight(const std::wstring& String, unsigned char Length, wchar_t Filler); | |
std::wstring AnsiToWide(const std::string& Wide); | |
std::string WideToAnsi(const std::wstring& Ansi); | |
std::string IntToAnsi(int Value, int Radix = 10); | |
std::string Int64ToAnsi(long long Value, int Radix = 10); | |
std::string UInt64ToAnsi(unsigned long long Value, int Radix = 10); | |
std::wstring IntToWide(int Value, int Radix = 10); | |
std::wstring Int64ToWide(long long Value, int Radix = 10); | |
std::wstring UInt64ToWide(unsigned long long Value, int Radix = 10); | |
inline std::string IntToAnsiHex(int Value) { return IntToAnsi(Value, 16); } | |
inline std::string Int64ToAnsiHex(__int64 Value) { return Int64ToAnsi(Value, 16); } | |
inline std::string UInt64ToAnsiHex(unsigned __int64 Value) { return UInt64ToAnsi(Value, 16); } | |
inline std::wstring IntToWideHex(int Value) { return IntToWide(Value, 16); } | |
inline std::wstring Int64ToWideHex(__int64 Value) { return Int64ToWide(Value, 16); } | |
inline std::wstring UInt64ToWideHex(unsigned __int64 Value) { return UInt64ToWide(Value, 16); } | |
inline std::string IntToAnsiBin(int Value) { return IntToAnsi(Value, 2); } | |
inline std::string Int64ToAnsiBin(__int64 Value) { return Int64ToAnsi(Value, 2); } | |
inline std::string UInt64ToAnsiBin(unsigned __int64 Value) { return UInt64ToAnsi(Value, 2); } | |
inline std::wstring IntToWideBin(int Value) { return IntToWide(Value, 2); } | |
inline std::wstring Int64ToWideBin(__int64 Value) { return Int64ToWide(Value, 2); } | |
inline std::wstring UInt64ToWideBin(unsigned __int64 Value) { return UInt64ToWide(Value, 2); } | |
std::string BufToAnsiHex(const void* Ptr, size_t Size, bool InsertSpaces = false); | |
std::wstring BufToWideHex(const void* Ptr, size_t Size, bool InsertSpaces = false); | |
#ifdef _UNICODE | |
inline std::wstring IntToStr(int Value, int Radix = 10) { return IntToWide(Value, Radix); } | |
inline std::wstring Int64ToStr(long long Value, int Radix = 10) { return Int64ToWide(Value, Radix); } | |
inline std::wstring UInt64ToStr(unsigned long long Value, int Radix = 10) { return UInt64ToWide(Value, Radix); } | |
inline std::wstring IntToHex(int Value) { return IntToWide(Value, 16); } | |
inline std::wstring Int64ToHex(__int64 Value) { return Int64ToWide(Value, 16); } | |
inline std::wstring UInt64ToHex(unsigned __int64 Value) { return UInt64ToWide(Value, 16); } | |
inline std::wstring IntToBin(int Value) { return IntToWide(Value, 2); } | |
inline std::wstring Int64ToBin(__int64 Value) { return Int64ToWide(Value, 2); } | |
inline std::wstring UInt64ToBin(unsigned __int64 Value) { return UInt64ToWide(Value, 2); } | |
inline std::wstring BufToHex(const void* Ptr, size_t Size, bool InsertSpaces = false) { return BufToWideHex(Ptr, Size, InsertSpaces); } | |
#else | |
inline std::string IntToStr(int Value, int Radix = 10) { return IntToAnsi(Value, Radix); } | |
inline std::string Int64ToStr(long long Value, int Radix = 10) { return Int64ToAnsi(Value, Radix); } | |
inline std::string UInt64ToStr(unsigned long long Value, int Radix = 10) { return UInt64ToAnsi(Value, Radix); } | |
inline std::string IntToHex(int Value) { return IntToAnsi(Value, 16); } | |
inline std::string Int64ToHex(__int64 Value) { return Int64ToAnsi(Value, 16); } | |
inline std::string UInt64ToHex(unsigned __int64 Value) { return UInt64ToAnsi(Value, 16); } | |
inline std::string IntToBin(int Value) { return IntToAnsi(Value, 2); } | |
inline std::string Int64ToBin(__int64 Value) { return Int64ToAnsi(Value, 2); } | |
inline std::string UInt64ToBin(unsigned __int64 Value) { return UInt64ToAnsi(Value, 2); } | |
inline std::string BufToHex(const void* Ptr, size_t Size, bool InsertSpaces = false) { return BufToAnsiHex(Ptr, Size, InsertSpaces); } | |
#endif | |
template <typename T> | |
inline std::string ValToAnsi(T Value) { return std::to_string(Value); } | |
template <typename T> | |
inline std::wstring ValToWide(T Value) { return std::to_wstring(Value); } | |
template <typename T> | |
inline int StrToInt(const T& Str) { return std::stoi(Str, nullptr, 0); } | |
template <typename T> | |
inline int StrToUInt(const T& Str) { return std::stoul(Str, nullptr, 0); } | |
template <typename T> | |
inline __int64 StrToInt64(const T& Str) { return std::stoll(Str, nullptr, 0); } | |
template <typename T> | |
inline unsigned __int64 StrToUInt64(const T& Str) { return std::stoull(Str, nullptr, 0); } | |
template <typename T> | |
inline int HexToInt(const T& Str) { return std::stoi(Str, nullptr, 16); } | |
template <typename T> | |
inline unsigned int HexToUInt(const T& Str) { return std::stoul(Str, nullptr, 16); } | |
template <typename T> | |
inline __int64 HexToInt64(const T& Str) { return std::stoll(Str, nullptr, 16); } | |
template <typename T> | |
inline unsigned __int64 HexToUInt64(const T& Str) { return std::stoull(Str, nullptr, 16); } | |
template <typename T> | |
inline int BinToInt(const T& Str) { return std::stoi(Str, nullptr, 2); } | |
template <typename T> | |
inline unsigned int BinToUInt(const T& Str) { return std::stoul(Str, nullptr, 2); } | |
template <typename T> | |
inline __int64 BinToInt64(const T& Str) { return std::stoll(Str, nullptr, 2); } | |
template <typename T> | |
inline unsigned __int64 BinToUInt64(const T& Str) { return std::stoull(Str, nullptr, 2); } | |
template <typename T> | |
inline float StrToFloat(const T& Str) { return std::stof(Str, nullptr); } | |
template <typename T> | |
inline double StrToDouble(const T& Str) { return std::stod(Str, nullptr); } | |
std::string PtrToAnsi(const void* Ptr); | |
std::wstring PtrToWide(const void* Ptr); | |
template <typename T> | |
T TrimLeft(const T& Str) { | |
if (Str.empty()) return T(); | |
for (size_t i = 0; i < Str.length(); ++i) { | |
typename T::value_type c = Str[i]; | |
if (c != static_cast<typename T::value_type>(' ') && c != static_cast<typename T::value_type>('\t')) | |
return Str.substr(i); | |
} | |
return T(); | |
} | |
template <typename T> | |
T TrimRight(const T& Str) { | |
if (Str.empty()) return T(); | |
for (size_t i = Str.length() - 1; i >= 0; --i) { | |
typename T::value_type c = Str[i]; | |
if (c != static_cast<typename T::value_type>(' ') && c != static_cast<typename T::value_type>('\t')) | |
return Str.substr(0, i + 1); | |
} | |
return T(); | |
} | |
template <typename T> | |
T Trim(const T& Str) { | |
return TrimRight(TrimLeft(Str)); | |
} | |
template <typename T> | |
bool IsStrMatches(const T* Str, const T* Mask) { | |
/* | |
Dr.Dobb's Algorithm: | |
http://www.drdobbs.com/architecture-and-design/matching-wildcards-an-empirical-way-to-t/240169123?queryText=path%2Bmatches | |
*/ | |
const T* TameText = Str; | |
const T* WildText = Mask; | |
const T* TameBookmark = static_cast<T*>(0x00); | |
const T* WildBookmark = static_cast<T*>(0x00); | |
while (true) { | |
if (*WildText == static_cast<T>('*')) { | |
while (*(++WildText) == static_cast<T>('*')); // "xy" matches "x**y" | |
if (!*WildText) return true; // "x" matches "*" | |
if (*WildText != static_cast<T>('?')) { | |
while (*TameText != *WildText) { | |
if (!(*(++TameText))) | |
return false; // "x" doesn't match "*y*" | |
} | |
} | |
WildBookmark = WildText; | |
TameBookmark = TameText; | |
} | |
else if (*TameText != *WildText && *WildText != static_cast<T>('?')) { | |
if (WildBookmark) { | |
if (WildText != WildBookmark) { | |
WildText = WildBookmark; | |
if (*TameText != *WildText) { | |
TameText = ++TameBookmark; | |
continue; // "xy" matches "*y" | |
} | |
else { | |
WildText++; | |
} | |
} | |
if (*TameText) { | |
TameText++; | |
continue; // "mississippi" matches "*sip*" | |
} | |
} | |
return false; // "xy" doesn't match "x" | |
} | |
TameText++; | |
WildText++; | |
if (!*TameText) { | |
while (*WildText == static_cast<T>('*')) WildText++; // "x" matches "x*" | |
if (!*WildText) return true; // "x" matches "x" | |
return false; // "x" doesn't match "xy" | |
} | |
} | |
} | |
// SimpleReplaceString("a ab abc", "a", "abc") -> "abc abcb abcbc" | |
template <typename T> | |
unsigned int SimpleReplaceString(__inout T& Text, const T& Source, const T& Destination) { | |
size_t SourceLength = Source.length(); | |
size_t DestinationLength = Destination.length(); | |
unsigned int ReplacingsCount = 0; | |
for (size_t Index = 0; Index = Text.find(Source, Index), Index != T::npos;) { | |
Text.replace(Index, SourceLength, Destination); | |
Index += DestinationLength; | |
++ReplacingsCount; | |
} | |
return ReplacingsCount; | |
} | |
// SelectiveReplaceString("a ab abc", "a", "abc") -> "abc abcb abc" | |
template <typename T> | |
unsigned int SelectiveReplaceString(__inout T& Text, const T& Source, const T& Destination) { | |
size_t TextLength = Text.length(); | |
size_t SourceLength = Source.length(); | |
size_t DestinationLength = Destination.length(); | |
unsigned int ReplacingsCount = 0; | |
T Environment(DestinationLength, NULL); | |
typename T::value_type* EnvironmentPtr = &Environment[0]; | |
for (size_t Index = 0; Index = Text.find(Source, Index), Index != T::npos;) { | |
if (DestinationLength <= TextLength - Index) { | |
memcpy(EnvironmentPtr, &Text[Index], DestinationLength * sizeof(typename T::value_type)); | |
if (Environment == Destination) { | |
Index += DestinationLength; | |
continue; | |
} | |
} | |
Text.replace(Index, SourceLength, Destination); | |
Index += DestinationLength; | |
TextLength = Text.length(); | |
++ReplacingsCount; | |
} | |
return ReplacingsCount; | |
}; | |
template <typename T> | |
T ReplaceString(const T& Text, const T& Source, const T& Destination, bool Selective = false) { | |
T Result(Text); | |
if (Selective) | |
SelectiveReplaceString(Result, Source, Destination); | |
else | |
SimpleReplaceString(Result, Source, Destination); | |
return Result; | |
} | |
template <typename T> | |
T FixWin32PathSlashes(const T& String) { | |
static const typename T::value_type ForwardSlash[] = { '/', NULL }; | |
static const typename T::value_type BackwardSlash[] = { '\\', NULL }; | |
static const typename T::value_type DoubleBackwardSlashes[] = { '\\', '\\', NULL }; | |
T Result(String); | |
SimpleReplaceString(Result, T(ForwardSlash), T(BackwardSlash)); | |
while (SimpleReplaceString(Result, T(DoubleBackwardSlashes), T(BackwardSlash))); | |
return Result; | |
} | |
template <typename T> | |
T FixUnixPathSlashes(const T& String) { | |
static const typename T::value_type ForwardSlash[] = { '/', NULL }; | |
static const typename T::value_type BackwardSlash[] = { '\\', NULL }; | |
static const typename T::value_type DoubleForwardSlashes[] = { '/', '/', NULL }; | |
T Result(String); | |
SimpleReplaceString(Result, T(BackwardSlash), T(ForwardSlash)); | |
while (SimpleReplaceString(Result, T(DoubleForwardSlashes), T(ForwardSlash))); | |
return Result; | |
} | |
template <typename T> | |
T FixUrlSlashes(const T& String) { | |
static const typename T::value_type ForwardSlash[] = { '/', NULL }; | |
static const typename T::value_type BackwardSlash[] = { '\\', NULL }; | |
static const typename T::value_type DoubleForwardSlashes[] = { '/', '/', NULL }; | |
static const typename T::value_type UrlBrokenSlashes[] = { ':', '/', NULL }; | |
static const typename T::value_type UrlBaseSlashes[] = { ':', '/', '/', NULL }; | |
T Result(String); | |
SimpleReplaceString(Result, T(BackwardSlash), T(ForwardSlash)); | |
while (SimpleReplaceString(Result, T(DoubleForwardSlashes), T(ForwardSlash))); | |
SimpleReplaceString(Result, T(UrlBrokenSlashes), T(UrlBaseSlashes)); | |
return Result; | |
} | |
#ifdef _VECTOR_ | |
template <typename T> | |
size_t Tokenize(const T& Str, const T& Delimiters, __out std::vector<T>& Tokens) { | |
Tokens.clear(); | |
size_t Start = Str.find_first_not_of(Delimiters); | |
size_t End = Start; | |
while (Start != T::npos) { | |
End = Str.find(Delimiters, Start); | |
Tokens.emplace_back(Str.substr(Start, End - Start)); | |
Start = Str.find_first_not_of(Delimiters, End); | |
} | |
return Tokens.size(); | |
} | |
template <typename T> | |
size_t Split(const T& Str, const T& Delimiter, __out std::vector<T>& Tokens) { | |
Tokens.clear(); | |
size_t Start = 0; | |
size_t End = Str.find(Delimiter); | |
size_t DelimLength = Delimiter.length(); | |
while (End != T::npos) { | |
Tokens.emplace_back(Str.substr(Start, End - Start)); | |
Start = End + DelimLength; | |
End = Str.find(Delimiter, Start); | |
} | |
Tokens.emplace_back(Str.substr(Start)); | |
return Tokens.size(); | |
} | |
#endif | |
#ifdef _SET_ | |
template <typename T> | |
size_t Tokenize(const T& Str, const T& Delimiters, __out std::set<T>& Tokens) { | |
Tokens.clear(); | |
size_t Start = Str.find_first_not_of(Delimiters); | |
size_t End = Start; | |
while (Start != T::npos) { | |
End = Str.find(Delimiters, Start); | |
Tokens.emplace(Str.substr(Start, End - Start)); | |
Start = Str.find_first_not_of(Delimiters, End); | |
} | |
return Tokens.size(); | |
} | |
template <typename T> | |
size_t Split(const T& Str, const T& Delimiter, __out std::set<T>& Tokens) { | |
Tokens.clear(); | |
size_t Start = 0; | |
size_t End = Str.find(Delimiter); | |
size_t DelimLength = Delimiter.length(); | |
while (End != T::npos) { | |
Tokens.emplace(Str.substr(Start, End - Start)); | |
Start = End + DelimLength; | |
End = Str.find(Delimiter, Start); | |
} | |
Tokens.emplace(Str.substr(Start)); | |
return Tokens.size(); | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment