| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* GATE PROJECT LICENSE: | ||
| 2 | +----------------------------------------------------------------------------+ | ||
| 3 | | Copyright(c) 2018-2025, 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 createFilled(size_t count, char_8_t content); | ||
| 90 | #if !defined(GATE_COMPILER_SUPPORTS_CPP_ARRAY_SIZE_DEDUCTION) | ||
| 91 | template<class T> static String createStaticFrom(T str) | ||
| 92 | { | ||
| 93 | return String::createStatic(&str[0], sizeof(str) / sizeof(str[0]) - 1); | ||
| 94 | } | ||
| 95 | #else | ||
| 96 | 10 | template<unsigned N> static String createStaticFrom(char const (&str)[N]) | |
| 97 | { | ||
| 98 | 10 | return String::createStatic(str, N - 1); | |
| 99 | } | ||
| 100 | #endif | ||
| 101 | static String createIntNum(int64_t num); | ||
| 102 | static String createRealNum(real64_t real, int32_t decimalCount = 3); | ||
| 103 | static void assign(gate_string_t& dst, String const& src); | ||
| 104 | static void assign(gate_string_t& dst, gate_string_t const& src); | ||
| 105 | |||
| 106 | void swap(String& that) noexcept; | ||
| 107 | void swap(gate_string_t& that) noexcept; | ||
| 108 | static void swap(gate_string_t& a, gate_string_t& b) noexcept; | ||
| 109 | |||
| 110 | size_t length() const noexcept; | ||
| 111 | static size_t length(char const* str) noexcept; | ||
| 112 | size_t size() const noexcept; | ||
| 113 | bool empty() const noexcept; | ||
| 114 | char_8_t const* c_str() const noexcept; | ||
| 115 | char_8_t const& at(size_t index) const noexcept; | ||
| 116 | gate_string_t const* c_impl() const noexcept; | ||
| 117 | |||
| 118 | const_iterator begin() const noexcept; | ||
| 119 | const_iterator cbegin() const noexcept; | ||
| 120 | const_iterator end() const noexcept; | ||
| 121 | const_iterator cend() const noexcept; | ||
| 122 | |||
| 123 | size_t positionOf(String const& text, size_t startAt = 0) const noexcept; | ||
| 124 | size_t positionOf(char const& chr, size_t startAt = 0) const noexcept; | ||
| 125 | size_t positionOfLast(String const& text) const noexcept; | ||
| 126 | size_t positionOfLast(char const& chr) const noexcept; | ||
| 127 | size_t findFirstOf(String const& text, size_t startAt = 0) const noexcept; | ||
| 128 | size_t findFirstNotOf(String const& text, size_t startAt = 0) const noexcept; | ||
| 129 | size_t findLastOf(String const& text) const noexcept; | ||
| 130 | size_t findLastNotOf(String const& text) const noexcept; | ||
| 131 | |||
| 132 | String substr(size_t offset, size_t len = GATE_STR_NPOS) const; | ||
| 133 | String left(size_t len) const; | ||
| 134 | String right(size_t len) const; | ||
| 135 | String readLine(String& tail) const; | ||
| 136 | String readLine(); | ||
| 137 | String toLower() const; | ||
| 138 | String toUpper() const; | ||
| 139 | |||
| 140 | String ltrim() const; | ||
| 141 | String rtrim() const; | ||
| 142 | String trim() const; | ||
| 143 | |||
| 144 | String copy() const; | ||
| 145 | String clone() const; | ||
| 146 | String duplicate() const noexcept; | ||
| 147 | static String copy(gate_string_t const& src); | ||
| 148 | static String clone(gate_string_t const& src); | ||
| 149 | static String duplicate(gate_string_t const& src) noexcept; | ||
| 150 | |||
| 151 | size_t copyTo(char_8_t* buffer, size_t capacity) const; | ||
| 152 | |||
| 153 | int compare(String const& str) const noexcept; | ||
| 154 | int compareIC(String const& str) const noexcept; | ||
| 155 | bool_t startsWith(String const& str) const noexcept; | ||
| 156 | bool_t startsWith(char const& chr) const noexcept; | ||
| 157 | bool_t startsWithIC(String const& str) const noexcept; | ||
| 158 | bool_t endsWith(String const& str) const noexcept; | ||
| 159 | bool_t endsWithIC(String const& str) const noexcept; | ||
| 160 | bool_t endsWith(char const& chr) const noexcept; | ||
| 161 | bool_t like(String const& str) const noexcept; | ||
| 162 | bool_t likeOneOf(String const& str, char_8_t separator = ';') const noexcept; | ||
| 163 | bool_t equals(String const& str) const noexcept; | ||
| 164 | bool_t equalsIC(String const& str) const noexcept; | ||
| 165 | |||
| 166 | int compare(char_8_t const* str) const noexcept; | ||
| 167 | int compareIC(char_8_t const* str) const noexcept; | ||
| 168 | bool_t startsWith(char_8_t const* str) const noexcept; | ||
| 169 | bool_t startsWithIC(char_8_t const* str) const noexcept; | ||
| 170 | bool_t endsWith(char_8_t const* str) const noexcept; | ||
| 171 | bool_t endsWithIC(char_8_t const* str) const noexcept; | ||
| 172 | bool_t equals(char_8_t const* str) const noexcept; | ||
| 173 | bool_t equalsIC(char_8_t const* str) const noexcept; | ||
| 174 | |||
| 175 | size_t parseNum(uint64_t& num) const noexcept; | ||
| 176 | size_t parseNum(int64_t& num) const noexcept; | ||
| 177 | size_t parseNum(real64_t& num) const noexcept; | ||
| 178 | size_t parseNum(real32_t& num) const noexcept; | ||
| 179 | size_t parseHex(uint64_t& num) const noexcept; | ||
| 180 | String parseHex() const noexcept; | ||
| 181 | int64_t parseInt() const noexcept; | ||
| 182 | real64_t parseReal() const noexcept; | ||
| 183 | |||
| 184 | String toHex() const; | ||
| 185 | static String toHex(char_8_t const* str, size_t len, bool_t upperCase = false); | ||
| 186 | |||
| 187 | bool_t operator==(String const& src) const noexcept; | ||
| 188 | bool_t operator!=(String const& src) const noexcept; | ||
| 189 | bool_t operator< (String const& src) const noexcept; | ||
| 190 | bool_t operator> (String const& src) const noexcept; | ||
| 191 | bool_t operator<=(String const& src) const noexcept; | ||
| 192 | bool_t operator>=(String const& src) const noexcept; | ||
| 193 | |||
| 194 | bool_t operator!() const noexcept; | ||
| 195 | gate_string_t const& operator*() const noexcept; | ||
| 196 | char_8_t const& operator[](size_t index) const noexcept; | ||
| 197 | |||
| 198 | size_t parse(String const& find, size_t startAt, String* ptrHead, String* ptrTail, bool_t separatorAsTail = false) const; | ||
| 199 | |||
| 200 | template<class N> size_t parseNum(N& num) const noexcept | ||
| 201 | { | ||
| 202 | int64_t num64 = 0; | ||
| 203 | size_t ret = this->parseNum(num64); | ||
| 204 | num = static_cast<N>(num64); | ||
| 205 | return ret; | ||
| 206 | } | ||
| 207 | template<class N> size_t parseHex(N& num) const noexcept | ||
| 208 | { | ||
| 209 | uint64_t num64 = 0; | ||
| 210 | size_t ret = this->parseHex(num64); | ||
| 211 | num = static_cast<N>(num64); | ||
| 212 | return ret; | ||
| 213 | } | ||
| 214 | |||
| 215 | private: | ||
| 216 | gate_string_t impl; | ||
| 217 | }; | ||
| 218 | |||
| 219 | GATE_CORE_CPP_API String operator+(String const& str1, String const& str2); | ||
| 220 | GATE_CORE_CPP_API String operator+(String const& str1, char const* str2); | ||
| 221 | GATE_CORE_CPP_API String operator+(char const* str1, String const& str2); | ||
| 222 | |||
| 223 | |||
| 224 | /// @brief | ||
| 225 | class GATE_CORE_CPP_API StaticString : public String | ||
| 226 | { | ||
| 227 | public: | ||
| 228 | explicit StaticString(char_8_t const* str) noexcept; | ||
| 229 | StaticString(char_8_t const* str, size_t len) noexcept; | ||
| 230 | #if !defined(GATE_COMPILER_SUPPORTS_CPP_ARRAY_SIZE_DEDUCTION) | ||
| 231 | template<class T> StaticString(T str) | ||
| 232 | : String(String::createStatic(&str[0], sizeof(str) / sizeof(str[0]) - 1)) | ||
| 233 | { | ||
| 234 | } | ||
| 235 | #else | ||
| 236 | 293 | template<unsigned N> StaticString(char const (&str)[N]) | |
| 237 | 293 | : String(String::createStatic(str, N - 1)) | |
| 238 | { | ||
| 239 | 293 | } | |
| 240 | #endif | ||
| 241 | StaticString(StaticString const& src) noexcept; | ||
| 242 | StaticString& operator=(StaticString const& src) noexcept; | ||
| 243 | ~StaticString() noexcept; | ||
| 244 | }; | ||
| 245 | |||
| 246 | |||
| 247 | /// @brief | ||
| 248 | class GATE_CORE_CPP_API StringBuilder : private NonCopyable | ||
| 249 | { | ||
| 250 | public: | ||
| 251 | StringBuilder(size_t capacity = 0); | ||
| 252 | StringBuilder(char* staticBuffer, size_t capacity, size_t alreadyUsed); | ||
| 253 | ~StringBuilder(); | ||
| 254 | |||
| 255 | gate_strbuilder_t const* c_impl() const noexcept; | ||
| 256 | gate_strbuilder_t* c_impl() noexcept; | ||
| 257 | |||
| 258 | char_8_t const* ptr(size_t pos = 0) const noexcept; | ||
| 259 | size_t length() const noexcept; | ||
| 260 | |||
| 261 | size_t resize(size_t sz); | ||
| 262 | size_t append(String const& text); | ||
| 263 | size_t append(char const* ptr, size_t len); | ||
| 264 | size_t append(char_16_t const* text16, size_t textlen); | ||
| 265 | size_t append(char_32_t const* text32, size_t textlen); | ||
| 266 | size_t append(int16_t const& num); | ||
| 267 | size_t append(uint16_t const& num); | ||
| 268 | size_t append(int32_t const& num); | ||
| 269 | size_t append(uint32_t const& num); | ||
| 270 | size_t append(int64_t const& num); | ||
| 271 | size_t append(uint64_t const& num); | ||
| 272 | size_t append(real64_t const& num, unsigned intlen = 0, unsigned decimallen = 3, unsigned grouplen = 0); | ||
| 273 | size_t appendHex(uint8_t const& num, bool_t upperCase = false); | ||
| 274 | size_t appendHex(uint16_t const& num, bool_t upperCase = false); | ||
| 275 | size_t appendHex(uint32_t const& num, bool_t upperCase = false); | ||
| 276 | size_t appendHex(uint64_t const& num, bool_t upperCase = false); | ||
| 277 | size_t appendHex(char const* txt, size_t len, bool_t upperCase = false); | ||
| 278 | size_t appendChars(size_t count, gate_char8_t chr); | ||
| 279 | size_t appendNewLine(); | ||
| 280 | size_t discard(size_t charCount = 1); | ||
| 281 | size_t discardBack(size_t charCount = 1); | ||
| 282 | String toString(); | ||
| 283 | String copyString() const; | ||
| 284 | String getView() const; | ||
| 285 | |||
| 286 | StringBuilder& operator<<(String const& text); | ||
| 287 | StringBuilder& operator<<(char const* text); | ||
| 288 | StringBuilder& operator<<(int16_t const& num); | ||
| 289 | StringBuilder& operator<<(uint16_t const& num); | ||
| 290 | StringBuilder& operator<<(int32_t const& num); | ||
| 291 | StringBuilder& operator<<(uint32_t const& num); | ||
| 292 | StringBuilder& operator<<(int64_t const& num); | ||
| 293 | StringBuilder& operator<<(uint64_t const& num); | ||
| 294 | StringBuilder& operator<<(real64_t const& num); | ||
| 295 | |||
| 296 | char_8_t const& operator[](size_t index) const; | ||
| 297 | char_8_t& operator[](size_t index); | ||
| 298 | |||
| 299 | private: | ||
| 300 | gate_strbuilder_t impl; | ||
| 301 | }; | ||
| 302 | |||
| 303 | |||
| 304 | /// @brief | ||
| 305 | class GATE_CORE_CPP_API CstrBuffer : private NonCopyable | ||
| 306 | { | ||
| 307 | public: | ||
| 308 | CstrBuffer(char const* ptr, size_t length, bool_t copyNeeded = false); | ||
| 309 | CstrBuffer(String const& str, bool_t copyNeeded = false); | ||
| 310 | ~CstrBuffer() noexcept; | ||
| 311 | |||
| 312 | char const* get() const; | ||
| 313 | size_t length() const; | ||
| 314 | |||
| 315 | private: | ||
| 316 | gate_cstrbuffer_t impl; | ||
| 317 | }; | ||
| 318 | |||
| 319 | namespace strings | ||
| 320 | { | ||
| 321 | GATE_CORE_CPP_API extern String const NewLine; | ||
| 322 | GATE_CORE_CPP_API extern String const Cr; | ||
| 323 | GATE_CORE_CPP_API extern String const Lf; | ||
| 324 | GATE_CORE_CPP_API extern String const CrLf; | ||
| 325 | GATE_CORE_CPP_API extern String const Empty; | ||
| 326 | |||
| 327 | } // end of namespace strings | ||
| 328 | |||
| 329 | } // end of namespace gate | ||
| 330 | |||
| 331 | #endif | ||
| 332 |