Enigma 3.2.2
A Simple, Reliable and Efficient Encryption Tool
Loading...
Searching...
No Matches
StringUtils.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef ENIGMA_STRING_UTILS_H
3#define ENIGMA_STRING_UTILS_H
4
5#include <Core/Types.hpp> // Enigma Types
6
7#include <algorithm> // std::all_of
8#include <codecvt> // helps converting between UTF-X strings
9#include <locale> // required for Linux & Darwin causes error: �wstring_convert� is not a member of �std�
10#include <sstream> // std::stringstream
11#include <string> // std::string, std::string_view
12#include <utility> // std::transform
13#include <vector>
14
16/*
17* UTF-8 & UTF-16 std::string Utility
18*/
19class StringUtils final {
21
22public:
23 /*
24 * Removes leading and trailing spaces from a string
25 */
26 template<typename StringType>
27 static void Trim(StringType& str) {
28 TrimLeft(str);
29 TrimRight(str);
30 }
31
32
33 /*
34 * Trim string from left
35 */
36 template<typename StringType>
37 static void TrimLeft(StringType& str) {
38 if (std::empty(str)) return;
39 str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](const auto& c) {
40 return !std::isspace(c);
41 }));
42 }
43
44
45 /*
46 * Trim string from right
47 */
48 template<typename StringType>
49 static void TrimRight(StringType& str) {
50 if (std::empty(str)) return;
51 str.erase(std::find_if(str.rbegin(), str.rend(), [](const auto& c) {
52 return !std::isspace(c);
53 }).base(),
54 str.end());
55 }
56
57
58 /*
59 * Lowercase a string
60 */
61 template<typename StringType>
62 static void Lower(StringType& str) {
63 std::transform(str.begin(), str.end(), str.begin(), [](const auto& c) {
64 return static_cast<typename StringType::value_type>(std::tolower(c));
65 });
66 }
67
68
69 /*
70 * Lowercase a string and return a copy of it
71 */
72 template<typename StringType>
73 static auto LowerCopy(const StringType& str) {
74 StringType cstr = str;
75 std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](const auto& c) {
76 return static_cast<typename StringType::value_type>(std::tolower(c));
77 });
78 return cstr;
79 }
80
81
82 /*
83 * Uppercase a string
84 */
85 template<typename StringType>
86 static void Upper(StringType& str) {
87 std::transform(str.begin(), str.end(), str.begin(), [](const auto& c) {
88 return static_cast<typename StringType::value_type>(std::toupper(c));
89 });
90 }
91
92
93 /*
94 * Uppercase a string and return a copy of it
95 */
96 template<typename StringType>
97 static auto UpperCopy(const StringType& str) {
98 StringType cstr = str;
99 std::transform(cstr.begin(), cstr.end(), cstr.begin(), [](const auto& c) {
100 return static_cast<typename StringType::value_type>(std::toupper(c));
101 });
102 return cstr;
103 }
104
105
106 /*
107 * Check if a string starts with a prefix
108 */
109 template<typename StringType>
110 static bool StartsWith(const StringType& str, const StringType& prefix) {
111 return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0;
112 }
113
114
115 /*
116 * Check if a string ends with a suffix
117 */
118 template<typename StringType>
119 static bool EndsWith(const StringType& str, const StringType& suffix) {
120 return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
121 }
122
123 /*
124 * Splits string at a delimiter into parts
125 */
126 template<typename StringType>
127 static std::vector<StringType> Split(const StringType& str, const typename std::string::value_type delimiter) {
128 std::vector<StringType> parts{};
129 std::stringstream ss(str);
130 std::string line{};
131 while (std::getline(ss, line, delimiter)) {
132 parts.push_back(line);
133 }
134 return parts;
135 }
136
137 /*
138 * Check if a string contains another
139 */
140 template<typename StringType>
141 static bool Contains(const StringType& str, const StringType& other) {
142 return str.find(other) != StringType::npos;
143 }
144
145
146 /*
147 * Converts UTF-8 std::string to UTF-16 std::wstring
148 */
149 static std::wstring StringToWString(const std::string& str) {
150 using convert_type = std::codecvt_utf8<wchar_t>;
151 static std::wstring_convert<convert_type, wchar_t> converter;
152 return converter.from_bytes(str);
153 }
154
155
156 /*
157 * Converts UTF-16 std::wstring to UTF-8 std::string
158 */
159 static std::string WStringToString(const std::wstring& wstr) {
160 using convert_type = std::codecvt_utf8<wchar_t>;
161 static std::wstring_convert<convert_type, wchar_t> converter;
162 return converter.to_bytes(wstr);
163 }
164
165
166 /*
167 * Convert string to any other simple type
168 */
169 template<typename T, typename StringType>
170 static T To(const StringType& str) {
171 T t{};
172 std::basic_stringstream<typename StringType::value_type> ss(str);
173 ss >> t;
174 return t;
175 }
176
177#if 0
178
179 /*
180 * Cleanup a string (remove string from string)
181 */
182 static std::string Cleanup(const std::string& expr, const std::string& remove)
183 {
184 const std::size_t N = expr.size();
185 const std::size_t K = remove.size();
186 std::string result(N, '\000');
187 std::size_t srcIndex = 0;
188 std::size_t dstIndex = 0;
189 while (srcIndex < N)
190 {
191 std::size_t matchIndex = 0;
192 while (matchIndex < K - 1 && srcIndex + matchIndex < N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
193 {
194 matchIndex++;
195 if (matchIndex == K - 1)
196 srcIndex += matchIndex;
197 }
198 result[dstIndex++] = expr[srcIndex] == '"' ? '\'' : expr[srcIndex];
199 srcIndex++;
200 }
201 result.resize(dstIndex, '\000'); // resize to fit string after removing other str
202 return result;
203 }
204 static std::wstring Cleanup(const std::wstring& expr, const std::wstring& remove)
205 {
206 const std::size_t N = expr.size();
207 const std::size_t K = remove.size();
208 std::wstring result(N, L'\000');
209 std::size_t srcIndex = 0;
210 std::size_t dstIndex = 0;
211 while (srcIndex < N)
212 {
213 std::size_t matchIndex = 0;
214 while (matchIndex < K - 1 && srcIndex + matchIndex < N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
215 matchIndex++;
216 if (matchIndex == K - 1)
217 srcIndex += matchIndex;
218 result[dstIndex++] = expr[srcIndex] == '"' ? '\'' : expr[srcIndex];
219 srcIndex++;
220 }
221 result.resize(dstIndex, L'\000'); // resize to fit string after removing other str
222 return result;
223 }
224
225 template <std::size_t N>
226 struct CleanupResult // wrapper to keep data variable alive in the stack after going out of scope of Cleanup function
227 {
228 char data[N];
229 };
230 template <std::size_t N, std::size_t K>
231 static auto Cleanup(const char(&expr)[N], const char(&remove)[K])
232 {
233 CleanupResult<N> result{};
234 std::size_t srcIndex = 0;
235 std::size_t dstIndex = 0;
236 //while constexpr (srcIndex < N)
237 while (srcIndex < N)
238 {
239 std::size_t matchIndex = 0;
240 while (matchIndex < K - 1 && srcIndex + matchIndex < N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
241 matchIndex++;
242 if (matchIndex == K - 1)
243 srcIndex += matchIndex;
244 result.data[dstIndex++] = expr[srcIndex] == '"' ? '\'' : expr[srcIndex];
245 srcIndex++;
246 }
247 return result;
248 }
249#endif
250};
252
253#endif // !ENIGMA_STRING_UTILS_H
#define NS_ENIGMA_BEGIN
Enable/Disable Assertions.
Definition Macros.hpp:13
#define NS_ENIGMA_END
Definition Macros.hpp:14
#define ENIGMA_STATIC_CLASS(Class)
Makes a class static, which will prevent creating instances from it and only use it as Class::Func()....
Definition Macros.hpp:120
static T To(const StringType &str)
static void Upper(StringType &str)
static std::wstring StringToWString(const std::string &str)
static auto LowerCopy(const StringType &str)
static void Lower(StringType &str)
static auto UpperCopy(const StringType &str)
static std::vector< StringType > Split(const StringType &str, const typename std::string::value_type delimiter)
static std::string WStringToString(const std::wstring &wstr)
static void Trim(StringType &str)
static bool Contains(const StringType &str, const StringType &other)
static void TrimRight(StringType &str)
static bool EndsWith(const StringType &str, const StringType &suffix)
static void TrimLeft(StringType &str)
static bool StartsWith(const StringType &str, const StringType &prefix)