| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* GATE PROJECT LICENSE: | ||
| 2 | +----------------------------------------------------------------------------+ | ||
| 3 | | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> | | ||
| 4 | | All rights reserved. | | ||
| 5 | | | | ||
| 6 | | Redistribution and use in source and binary forms, with or without | | ||
| 7 | | modification, are permitted provided that the following conditions are met:| | ||
| 8 | | | | ||
| 9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
| 10 | | this list of conditions and the following disclaimer. | | ||
| 11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
| 12 | | notice, this list of conditions and the following disclaimer in the | | ||
| 13 | | documentation and/or other materials provided with the distribution. | | ||
| 14 | | | | ||
| 15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
| 16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
| 17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
| 18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
| 19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
| 20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
| 21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
| 22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
| 23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
| 24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
| 25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
| 26 | +----------------------------------------------------------------------------+ | ||
| 27 | */ | ||
| 28 | |||
| 29 | /** @file | ||
| 30 | * @brief Strings and text primitives | ||
| 31 | * @ingroup gatecore_cpp | ||
| 32 | */ | ||
| 33 | |||
| 34 | #ifndef GATE_STRINGS_HPP_INCLUDED | ||
| 35 | #define GATE_STRINGS_HPP_INCLUDED | ||
| 36 | |||
| 37 | #include "gate/gate_core_api.hpp" | ||
| 38 | #include "gate/strings.h" | ||
| 39 | #include "gate/gatetypes.hpp" | ||
| 40 | |||
| 41 | namespace gate | ||
| 42 | { | ||
| 43 | class StringBuilder; | ||
| 44 | |||
| 45 | /// @brief | ||
| 46 | class GATE_CORE_CPP_API Char | ||
| 47 | { | ||
| 48 | public: | ||
| 49 | static int toLower(int chr); | ||
| 50 | static int toUpper(int chr); | ||
| 51 | static bool_t isDigit(int chr); | ||
| 52 | static bool_t isWhitespace(int chr); | ||
| 53 | |||
| 54 | static size_t readUtf8(char_8_t const* utf8text, size_t length, char_32_t& chr32); | ||
| 55 | static size_t readUtf16(char_16_t const* utf16text, size_t length, char_32_t& chr32); | ||
| 56 | static size_t readUtf32(char_32_t const* utf32text, size_t length, char_32_t& chr32); | ||
| 57 | |||
| 58 | static size_t writeUtf8(char_32_t chr32, char_8_t* utf8text, size_t length); | ||
| 59 | static size_t writeUtf16(char_32_t chr32, char_16_t* utf16text, size_t length); | ||
| 60 | static size_t writeUtf32(char_32_t chr32, char_32_t* utf32text, size_t length); | ||
| 61 | }; | ||
| 62 | |||
| 63 | |||
| 64 | /// @brief | ||
| 65 | class GATE_CORE_CPP_API String : public SafeBoolBase<String> | ||
| 66 | { | ||
| 67 | public: | ||
| 68 | //typedef StrToken token_t; | ||
| 69 | |||
| 70 | static size_t const npos; | ||
| 71 | static size_t const NPOS; | ||
| 72 | typedef char_8_t const* const_iterator; | ||
| 73 | |||
| 74 | public: | ||
| 75 | String() noexcept; | ||
| 76 | String(char_8_t const* str); | ||
| 77 | String(char_8_t const* str, size_t len); | ||
| 78 | String(gate_string_t const& src); | ||
| 79 | String(String const& src) noexcept; | ||
| 80 | String(StringBuilder& strbuilder); | ||
| 81 | String(GATE_MOVEREF(String) src) noexcept; | ||
| 82 | String& operator=(String const& src) noexcept; | ||
| 83 | ~String() noexcept; | ||
| 84 | String& operator=(GATE_MOVEREF(String) src) noexcept; | ||
| 85 | |||
| 86 | static String createStatic(char_8_t const* str) noexcept; | ||
| 87 | static String createStatic(char_8_t const* str, size_t len) noexcept; | ||
| 88 | static String createFrom(gate_string_t& str) noexcept; // create C++ String and release originating C object | ||
| 89 | static String createFrom(char_16_t const* utf16, size_t len); | ||
| 90 | static String createFrom(char_32_t const* utf32, size_t len); | ||
| 91 | static String createFilled(size_t count, char_8_t content); | ||
| 92 | #if !defined(GATE_COMPILER_SUPPORTS_CPP_ARRAY_SIZE_DEDUCTION) | ||
| 93 | template<class T> static String createStaticFrom(T str) | ||
| 94 | { | ||
| 95 | return String::createStatic(&str[0], sizeof(str) / sizeof(str[0]) - 1); | ||
| 96 | } | ||
| 97 | #else | ||
| 98 | 10 | template<unsigned N> static String createStaticFrom(char const (&str)[N]) | |
| 99 | { | ||
| 100 | 10 | return String::createStatic(str, N - 1); | |
| 101 | } | ||
| 102 | #endif | ||
| 103 | static String createIntNum(int64_t num); | ||
| 104 | static String createRealNum(real64_t real, int32_t decimalCount = 3); | ||
| 105 | static void assign(gate_string_t& dst, String const& src); | ||
| 106 | static void assign(gate_string_t& dst, gate_string_t const& src); | ||
| 107 | |||
| 108 | void swap(String& that) noexcept; | ||
| 109 | void swap(gate_string_t& that) noexcept; | ||
| 110 | static void swap(gate_string_t& a, gate_string_t& b) noexcept; | ||
| 111 | |||
| 112 | size_t length() const noexcept; | ||
| 113 | static size_t length(char const* str) noexcept; | ||
| 114 | size_t size() const noexcept; | ||
| 115 | bool empty() const noexcept; | ||
| 116 | char_8_t const* c_str() const noexcept; | ||
| 117 | char_8_t const& at(size_t index) const noexcept; | ||
| 118 | gate_string_t const* c_impl() const noexcept; | ||
| 119 | |||
| 120 | const_iterator begin() const noexcept; | ||
| 121 | const_iterator cbegin() const noexcept; | ||
| 122 | const_iterator end() const noexcept; | ||
| 123 | const_iterator cend() const noexcept; | ||
| 124 | |||
| 125 | size_t positionOf(String const& text, size_t startAt = 0) const noexcept; | ||
| 126 | size_t positionOf(char const& chr, size_t startAt = 0) const noexcept; | ||
| 127 | size_t positionOfLast(String const& text) const noexcept; | ||
| 128 | size_t positionOfLast(char const& chr) const noexcept; | ||
| 129 | size_t findFirstOf(String const& text, size_t startAt = 0) const noexcept; | ||
| 130 | size_t findFirstNotOf(String const& text, size_t startAt = 0) const noexcept; | ||
| 131 | size_t findLastOf(String const& text) const noexcept; | ||
| 132 | size_t findLastNotOf(String const& text) const noexcept; | ||
| 133 | |||
| 134 | String substr(size_t offset, size_t len = GATE_STR_NPOS) const; | ||
| 135 | String left(size_t len) const; | ||
| 136 | String right(size_t len) const; | ||
| 137 | String readLine(String& tail) const; | ||
| 138 | String readLine(); | ||
| 139 | String toLower() const; | ||
| 140 | String toUpper() const; | ||
| 141 | |||
| 142 | String ltrim() const; | ||
| 143 | String rtrim() const; | ||
| 144 | String trim() const; | ||
| 145 | |||
| 146 | String copy() const; | ||
| 147 | String clone() const; | ||
| 148 | String duplicate() const noexcept; | ||
| 149 | static String copy(gate_string_t const& src); | ||
| 150 | static String clone(gate_string_t const& src); | ||
| 151 | static String duplicate(gate_string_t const& src) noexcept; | ||
| 152 | |||
| 153 | size_t copyTo(char_8_t* buffer, size_t capacity) const; | ||
| 154 | |||
| 155 | int compare(String const& str) const noexcept; | ||
| 156 | int compareIC(String const& str) const noexcept; | ||
| 157 | bool_t startsWith(String const& str) const noexcept; | ||
| 158 | bool_t startsWith(char const& chr) const noexcept; | ||
| 159 | bool_t startsWithIC(String const& str) const noexcept; | ||
| 160 | bool_t endsWith(String const& str) const noexcept; | ||
| 161 | bool_t endsWithIC(String const& str) const noexcept; | ||
| 162 | bool_t endsWith(char const& chr) const noexcept; | ||
| 163 | bool_t like(String const& str) const noexcept; | ||
| 164 | bool_t likeOneOf(String const& str, char_8_t separator = ';') const noexcept; | ||
| 165 | bool_t equals(String const& str) const noexcept; | ||
| 166 | bool_t equalsIC(String const& str) const noexcept; | ||
| 167 | |||
| 168 | int compare(char_8_t const* str) const noexcept; | ||
| 169 | int compareIC(char_8_t const* str) const noexcept; | ||
| 170 | bool_t startsWith(char_8_t const* str) const noexcept; | ||
| 171 | bool_t startsWithIC(char_8_t const* str) const noexcept; | ||
| 172 | bool_t endsWith(char_8_t const* str) const noexcept; | ||
| 173 | bool_t endsWithIC(char_8_t const* str) const noexcept; | ||
| 174 | bool_t equals(char_8_t const* str) const noexcept; | ||
| 175 | bool_t equalsIC(char_8_t const* str) const noexcept; | ||
| 176 | |||
| 177 | size_t parseNum(uint64_t& num) const noexcept; | ||
| 178 | size_t parseNum(int64_t& num) const noexcept; | ||
| 179 | size_t parseNum(real64_t& num) const noexcept; | ||
| 180 | size_t parseNum(real32_t& num) const noexcept; | ||
| 181 | size_t parseHex(uint64_t& num) const noexcept; | ||
| 182 | String parseHex() const noexcept; | ||
| 183 | int64_t parseInt() const noexcept; | ||
| 184 | real64_t parseReal() const noexcept; | ||
| 185 | uint8_t parseOctByte() const noexcept; | ||
| 186 | bool_t parseBool() const noexcept; | ||
| 187 | |||
| 188 | static size_t printValue(char* buffer, size_t bufferlen, int printType, void const* ptrValue); | ||
| 189 | |||
| 190 | String toHex() const; | ||
| 191 | static String toHex(char_8_t const* str, size_t len, bool_t upperCase = false); | ||
| 192 | |||
| 193 | bool_t operator==(String const& src) const noexcept; | ||
| 194 | bool_t operator!=(String const& src) const noexcept; | ||
| 195 | bool_t operator< (String const& src) const noexcept; | ||
| 196 | bool_t operator> (String const& src) const noexcept; | ||
| 197 | bool_t operator<=(String const& src) const noexcept; | ||
| 198 | bool_t operator>=(String const& src) const noexcept; | ||
| 199 | |||
| 200 | bool_t operator!() const noexcept; | ||
| 201 | gate_string_t const& operator*() const noexcept; | ||
| 202 | char_8_t const& operator[](size_t index) const noexcept; | ||
| 203 | |||
| 204 | size_t parse(String const& find, size_t startAt, String* ptrHead, String* ptrTail, bool_t separatorAsTail = false) const; | ||
| 205 | |||
| 206 | template<class N> size_t parseNum(N& num) const noexcept | ||
| 207 | { | ||
| 208 | int64_t num64 = 0; | ||
| 209 | size_t ret = this->parseNum(num64); | ||
| 210 | num = static_cast<N>(num64); | ||
| 211 | return ret; | ||
| 212 | } | ||
| 213 | template<class N> size_t parseHex(N& num) const noexcept | ||
| 214 | { | ||
| 215 | uint64_t num64 = 0; | ||
| 216 | size_t ret = this->parseHex(num64); | ||
| 217 | num = static_cast<N>(num64); | ||
| 218 | return ret; | ||
| 219 | } | ||
| 220 | |||
| 221 | private: | ||
| 222 | gate_string_t impl; | ||
| 223 | }; | ||
| 224 | |||
| 225 | GATE_CORE_CPP_API String operator+(String const& str1, String const& str2); | ||
| 226 | GATE_CORE_CPP_API String operator+(String const& str1, char const* str2); | ||
| 227 | GATE_CORE_CPP_API String operator+(char const* str1, String const& str2); | ||
| 228 | |||
| 229 | |||
| 230 | /// @brief | ||
| 231 | class GATE_CORE_CPP_API StaticString : public String | ||
| 232 | { | ||
| 233 | public: | ||
| 234 | explicit StaticString(char_8_t const* str) noexcept; | ||
| 235 | StaticString(char_8_t const* str, size_t len) noexcept; | ||
| 236 | #if !defined(GATE_COMPILER_SUPPORTS_CPP_ARRAY_SIZE_DEDUCTION) | ||
| 237 | template<class T> StaticString(T str) | ||
| 238 | : String(String::createStatic(&str[0], sizeof(str) / sizeof(str[0]) - 1)) | ||
| 239 | { | ||
| 240 | } | ||
| 241 | #else | ||
| 242 | 337 | template<unsigned N> StaticString(char const (&str)[N]) | |
| 243 | 337 | : String(String::createStatic(str, N - 1)) | |
| 244 | { | ||
| 245 | 337 | } | |
| 246 | #endif | ||
| 247 | StaticString(StaticString const& src) noexcept; | ||
| 248 | StaticString& operator=(StaticString const& src) noexcept; | ||
| 249 | ~StaticString() noexcept; | ||
| 250 | }; | ||
| 251 | |||
| 252 | |||
| 253 | /// @brief | ||
| 254 | class GATE_CORE_CPP_API StringBuilder : private NonCopyable | ||
| 255 | { | ||
| 256 | public: | ||
| 257 | StringBuilder(size_t capacity = 0); | ||
| 258 | StringBuilder(char* staticBuffer, size_t capacity, size_t alreadyUsed); | ||
| 259 | ~StringBuilder(); | ||
| 260 | |||
| 261 | gate_strbuilder_t const* c_impl() const noexcept; | ||
| 262 | gate_strbuilder_t* c_impl() noexcept; | ||
| 263 | |||
| 264 | char_8_t const* ptr(size_t pos = 0) const noexcept; | ||
| 265 | size_t length() const noexcept; | ||
| 266 | |||
| 267 | size_t resize(size_t sz); | ||
| 268 | size_t append(String const& text); | ||
| 269 | size_t append(char const* ptr, size_t len); | ||
| 270 | size_t append(char_16_t const* text16, size_t textlen); | ||
| 271 | size_t append(char_32_t const* text32, size_t textlen); | ||
| 272 | size_t append(int16_t const& num); | ||
| 273 | size_t append(uint16_t const& num); | ||
| 274 | size_t append(int32_t const& num); | ||
| 275 | size_t append(uint32_t const& num); | ||
| 276 | size_t append(int64_t const& num); | ||
| 277 | size_t append(uint64_t const& num); | ||
| 278 | size_t append(real64_t const& num, unsigned intlen = 0, unsigned decimallen = 3, unsigned grouplen = 0); | ||
| 279 | size_t appendHex(uint8_t const& num, bool_t upperCase = false); | ||
| 280 | size_t appendHex(uint16_t const& num, bool_t upperCase = false); | ||
| 281 | size_t appendHex(uint32_t const& num, bool_t upperCase = false); | ||
| 282 | size_t appendHex(uint64_t const& num, bool_t upperCase = false); | ||
| 283 | size_t appendHex(char const* txt, size_t len, bool_t upperCase = false); | ||
| 284 | size_t appendChars(size_t count, gate_char8_t chr); | ||
| 285 | size_t appendNewLine(); | ||
| 286 | size_t discard(size_t charCount = 1); | ||
| 287 | size_t discardBack(size_t charCount = 1); | ||
| 288 | String toString(); | ||
| 289 | String copyString() const; | ||
| 290 | String getView() const; | ||
| 291 | size_t insert(size_t pos, String const& text); | ||
| 292 | size_t positionOf(String const& token, size_t startAt = 0); | ||
| 293 | size_t positionOf(char const& chr, size_t startAt = 0); | ||
| 294 | size_t replace(String const& find, String const& replaceWith, size_t startAt = 0, size_t maxReplace = GATE_STR_NPOS); | ||
| 295 | size_t remove(size_t fromPos, size_t length = GATE_STR_NPOS); | ||
| 296 | |||
| 297 | StringBuilder& operator<<(String const& text); | ||
| 298 | StringBuilder& operator<<(char const* text); | ||
| 299 | StringBuilder& operator<<(int16_t const& num); | ||
| 300 | StringBuilder& operator<<(uint16_t const& num); | ||
| 301 | StringBuilder& operator<<(int32_t const& num); | ||
| 302 | StringBuilder& operator<<(uint32_t const& num); | ||
| 303 | StringBuilder& operator<<(int64_t const& num); | ||
| 304 | StringBuilder& operator<<(uint64_t const& num); | ||
| 305 | StringBuilder& operator<<(real64_t const& num); | ||
| 306 | |||
| 307 | char_8_t const& operator[](size_t index) const; | ||
| 308 | char_8_t& operator[](size_t index); | ||
| 309 | |||
| 310 | private: | ||
| 311 | gate_strbuilder_t impl; | ||
| 312 | }; | ||
| 313 | |||
| 314 | |||
| 315 | /// @brief | ||
| 316 | class GATE_CORE_CPP_API CstrBuffer : private NonCopyable | ||
| 317 | { | ||
| 318 | public: | ||
| 319 | CstrBuffer(char const* ptr, size_t length, bool_t copyNeeded = false); | ||
| 320 | CstrBuffer(wchar_t const* ptr, gate_size_t length); | ||
| 321 | CstrBuffer(String const& str, bool_t copyNeeded = false); | ||
| 322 | ~CstrBuffer() noexcept; | ||
| 323 | |||
| 324 | gate_cstrbuffer_t const* c_impl() const; | ||
| 325 | char const* get() const; | ||
| 326 | size_t length() const; | ||
| 327 | |||
| 328 | private: | ||
| 329 | gate_cstrbuffer_t impl; | ||
| 330 | }; | ||
| 331 | |||
| 332 | |||
| 333 | class GATE_CORE_CPP_API CstrBuffer16 : private NonCopyable | ||
| 334 | { | ||
| 335 | public: | ||
| 336 | CstrBuffer16(char_16_t const* ptr, size_t length, bool_t copyNeeded = false); | ||
| 337 | CstrBuffer16(String const& str); | ||
| 338 | ~CstrBuffer16() noexcept; | ||
| 339 | |||
| 340 | gate_cstrbuffer16_t const* c_impl() const; | ||
| 341 | char_16_t const* get() const; | ||
| 342 | size_t length() const; | ||
| 343 | |||
| 344 | private: | ||
| 345 | gate_cstrbuffer16_t impl; | ||
| 346 | }; | ||
| 347 | |||
| 348 | |||
| 349 | class GATE_CORE_CPP_API CstrBuffer32 : private NonCopyable | ||
| 350 | { | ||
| 351 | public: | ||
| 352 | CstrBuffer32(char_32_t const* ptr, size_t length, bool_t copyNeeded = false); | ||
| 353 | CstrBuffer32(String const& str); | ||
| 354 | ~CstrBuffer32() noexcept; | ||
| 355 | |||
| 356 | gate_cstrbuffer32_t const* c_impl() const; | ||
| 357 | char_32_t const* get() const; | ||
| 358 | size_t length() const; | ||
| 359 | |||
| 360 | private: | ||
| 361 | gate_cstrbuffer32_t impl; | ||
| 362 | }; | ||
| 363 | |||
| 364 | |||
| 365 | namespace strings | ||
| 366 | { | ||
| 367 | GATE_CORE_CPP_API extern String const NewLine; | ||
| 368 | GATE_CORE_CPP_API extern String const Cr; | ||
| 369 | GATE_CORE_CPP_API extern String const Lf; | ||
| 370 | GATE_CORE_CPP_API extern String const CrLf; | ||
| 371 | GATE_CORE_CPP_API extern String const Empty; | ||
| 372 | |||
| 373 | } // end of namespace strings | ||
| 374 | |||
| 375 | } // end of namespace gate | ||
| 376 | |||
| 377 | #endif | ||
| 378 |