1 /*************************************************************************************************** 2 3 Zyan Core Library (Zycore-C) 4 5 Original Author : Florian Bernd 6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 25 ***************************************************************************************************/ 26 27 /** 28 * @file 29 * @brief Implements a string type. 30 */ 31 32 #ifndef ZYCORE_STRING_H 33 #define ZYCORE_STRING_H 34 35 #include "zydis/ZycoreExportConfig.h" 36 #include "zydis/Zycore/Allocator.h" 37 #include "zydis/Zycore/Status.h" 38 #include "zydis/Zycore/Types.h" 39 #include "zydis/Zycore/Vector.h" 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 /* ============================================================================================== */ 46 /* Constants */ 47 /* ============================================================================================== */ 48 49 /** 50 * @brief The initial minimum capacity (number of characters) for all dynamically allocated 51 * string instances - not including the terminating '\0'-character. 52 */ 53 #define ZYAN_STRING_MIN_CAPACITY 32 54 55 /** 56 * @brief The default growth factor for all string instances. 57 */ 58 #define ZYAN_STRING_DEFAULT_GROWTH_FACTOR 2.00f 59 60 /** 61 * @brief The default shrink threshold for all string instances. 62 */ 63 #define ZYAN_STRING_DEFAULT_SHRINK_THRESHOLD 0.25f 64 65 /* ============================================================================================== */ 66 /* Enums and types */ 67 /* ============================================================================================== */ 68 69 /* ---------------------------------------------------------------------------------------------- */ 70 /* String flags */ 71 /* ---------------------------------------------------------------------------------------------- */ 72 73 /** 74 * @brief Defines the `ZyanStringFlags` datatype. 75 */ 76 typedef ZyanU8 ZyanStringFlags; 77 78 /** 79 * @brief The string uses a custom user-defined buffer with a fixed capacity. 80 */ 81 #define ZYAN_STRING_HAS_FIXED_CAPACITY 0x01 // (1 << 0) 82 83 /* ---------------------------------------------------------------------------------------------- */ 84 /* String */ 85 /* ---------------------------------------------------------------------------------------------- */ 86 87 /** 88 * @brief Defines the `ZyanString` struct. 89 * 90 * The `ZyanString` type is implemented as a size-prefixed string - which allows for a lot of 91 * performance optimizations. 92 * Nevertheless null-termination is guaranteed at all times to provide maximum compatibility with 93 * default C-style strings (use `ZyanStringGetData` to access the C-style string). 94 * 95 * All fields in this struct should be considered as "private". Any changes may lead to unexpected 96 * behavior. 97 */ 98 typedef struct ZyanString_ 99 { 100 /** 101 * @brief String flags. 102 */ 103 ZyanStringFlags flags; 104 /** 105 * @brief The vector that contains the actual string. 106 */ 107 ZyanVector vector; 108 } ZyanString; 109 110 /* ---------------------------------------------------------------------------------------------- */ 111 /* View */ 112 /* ---------------------------------------------------------------------------------------------- */ 113 114 /** 115 * @brief Defines the `ZyanStringView` struct. 116 * 117 * The `ZyanStringView` type provides a view inside a string (`ZyanString` instances, null- 118 * terminated C-style strings, or even not-null-terminated custom strings). A view is immutable 119 * by design and can't be directly converted to a C-style string. 120 * 121 * Views might become invalid (e.g. pointing to invalid memory), if the underlying string gets 122 * destroyed or resized. 123 * 124 * The `ZYAN_STRING_TO_VIEW` macro can be used to cast a `ZyanString` to a `ZyanStringView` pointer 125 * without any runtime overhead. 126 * Casting a view to a normal string is not supported and will lead to unexpected behavior (use 127 * `ZyanStringDuplicate` to create a deep-copy instead). 128 * 129 * All fields in this struct should be considered as "private". Any changes may lead to unexpected 130 * behavior. 131 */ 132 typedef struct ZyanStringView_ 133 { 134 /** 135 * @brief The string data. 136 * 137 * The view internally re-uses the normal string struct to allow casts without any runtime 138 * overhead. 139 */ 140 ZyanString string; 141 } ZyanStringView; 142 143 /* ---------------------------------------------------------------------------------------------- */ 144 145 /* ============================================================================================== */ 146 /* Macros */ 147 /* ============================================================================================== */ 148 149 /* ---------------------------------------------------------------------------------------------- */ 150 /* General */ 151 /* ---------------------------------------------------------------------------------------------- */ 152 153 /** 154 * @brief Defines an uninitialized `ZyanString` instance. 155 */ 156 #define ZYAN_STRING_INITIALIZER \ 157 { \ 158 /* flags */ 0, \ 159 /* vector */ ZYAN_VECTOR_INITIALIZER \ 160 } 161 162 /* ---------------------------------------------------------------------------------------------- */ 163 /* Helper macros */ 164 /* ---------------------------------------------------------------------------------------------- */ 165 166 /** 167 * @brief Casts a `ZyanString` pointer to a constant `ZyanStringView` pointer. 168 */ 169 #define ZYAN_STRING_TO_VIEW(string) (const ZyanStringView*)(string) 170 171 /** 172 * @brief Defines a `ZyanStringView` struct that provides a view into a static C-style string. 173 * 174 * @param string The C-style string. 175 */ 176 #define ZYAN_DEFINE_STRING_VIEW(string) \ 177 { \ 178 /* string */ \ 179 { \ 180 /* flags */ 0, \ 181 /* vector */ \ 182 { \ 183 /* allocator */ ZYAN_NULL, \ 184 /* growth_factor */ 1.0f, \ 185 /* shrink_threshold */ 0.0f, \ 186 /* size */ sizeof(string), \ 187 /* capacity */ sizeof(string), \ 188 /* element_size */ sizeof(char), \ 189 /* destructor */ ZYAN_NULL, \ 190 /* data */ (char*)(string) \ 191 } \ 192 } \ 193 } 194 195 /* ---------------------------------------------------------------------------------------------- */ 196 197 /* ============================================================================================== */ 198 /* Exported functions */ 199 /* ============================================================================================== */ 200 201 /* ---------------------------------------------------------------------------------------------- */ 202 /* Constructor and destructor */ 203 /* ---------------------------------------------------------------------------------------------- */ 204 205 #ifndef ZYAN_NO_LIBC 206 207 /** 208 * @brief Initializes the given `ZyanString` instance. 209 * 210 * @param string A pointer to the `ZyanString` instance. 211 * @param capacity The initial capacity (number of characters). 212 * 213 * @return A zyan status code. 214 * 215 * The memory for the string is dynamically allocated by the default allocator using the default 216 * growth factor of `2.0f` and the default shrink threshold of `0.25f`. 217 * 218 * The allocated buffer will be at least one character larger than the given `capacity`, to reserve 219 * space for the terminating '\0'. 220 * 221 * Finalization with `ZyanStringDestroy` is required for all strings created by this function. 222 */ 223 ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringInit(ZyanString* string, ZyanUSize capacity); 224 225 #endif // ZYAN_NO_LIBC 226 227 /** 228 * @brief Initializes the given `ZyanString` instance and sets a custom `allocator` and memory 229 * allocation/deallocation parameters. 230 * 231 * @param string A pointer to the `ZyanString` instance. 232 * @param capacity The initial capacity (number of characters). 233 * @param allocator A pointer to a `ZyanAllocator` instance. 234 * @param growth_factor The growth factor (from `1.0f` to `x.xf`). 235 * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). 236 * 237 * @return A zyan status code. 238 * 239 * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables 240 * dynamic shrinking. 241 * 242 * The allocated buffer will be at least one character larger than the given `capacity`, to reserve 243 * space for the terminating '\0'. 244 * 245 * Finalization with `ZyanStringDestroy` is required for all strings created by this function. 246 */ 247 ZYCORE_EXPORT ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity, 248 ZyanAllocator* allocator, float growth_factor, float shrink_threshold); 249 250 /** 251 * @brief Initializes the given `ZyanString` instance and configures it to use a custom user 252 * defined buffer with a fixed size. 253 * 254 * @param string A pointer to the `ZyanString` instance. 255 * @param buffer A pointer to the buffer that is used as storage for the string. 256 * @param capacity The maximum capacity (number of characters) of the buffer, including 257 * the terminating '\0'. 258 * 259 * @return A zyan status code. 260 * 261 * Finalization is not required for strings created by this function. 262 */ 263 ZYCORE_EXPORT ZyanStatus ZyanStringInitCustomBuffer(ZyanString* string, char* buffer, 264 ZyanUSize capacity); 265 266 /** 267 * @brief Destroys the given `ZyanString` instance. 268 * 269 * @param string A pointer to the `ZyanString` instance. 270 * 271 * @return A zyan status code. 272 * 273 */ 274 ZYCORE_EXPORT ZyanStatus ZyanStringDestroy(ZyanString* string); 275 276 /* ---------------------------------------------------------------------------------------------- */ 277 /* Duplication */ 278 /* ---------------------------------------------------------------------------------------------- */ 279 280 #ifndef ZYAN_NO_LIBC 281 282 /** 283 * @brief Initializes a new `ZyanString` instance by duplicating an existing string. 284 * 285 * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. 286 * @param source A pointer to the source string. 287 * @param capacity The initial capacity (number of characters). 288 * 289 * This value is automatically adjusted to the size of the source string, if 290 * a smaller value was passed. 291 * 292 * @return A zyan status code. 293 * 294 * The behavior of this function is undefined, if `source` is a view into the `destination` 295 * string or `destination` points to an already initialized `ZyanString` instance. 296 * 297 * The memory for the string is dynamically allocated by the default allocator using the default 298 * growth factor of `2.0f` and the default shrink threshold of `0.25f`. 299 * 300 * The allocated buffer will be at least one character larger than the given `capacity`, to reserve 301 * space for the terminating '\0'. 302 * 303 * Finalization with `ZyanStringDestroy` is required for all strings created by this function. 304 */ 305 ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringDuplicate(ZyanString* destination, 306 const ZyanStringView* source, ZyanUSize capacity); 307 308 #endif // ZYAN_NO_LIBC 309 310 /** 311 * @brief Initializes a new `ZyanString` instance by duplicating an existing string and sets a 312 * custom `allocator` and memory allocation/deallocation parameters. 313 * 314 * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. 315 * @param source A pointer to the source string. 316 * @param capacity The initial capacity (number of characters). 317 318 * This value is automatically adjusted to the size of the source 319 * string, if a smaller value was passed. 320 * @param allocator A pointer to a `ZyanAllocator` instance. 321 * @param growth_factor The growth factor (from `1.0f` to `x.xf`). 322 * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). 323 * 324 * @return A zyan status code. 325 * 326 * The behavior of this function is undefined, if `source` is a view into the `destination` 327 * string or `destination` points to an already initialized `ZyanString` instance. 328 * 329 * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables 330 * dynamic shrinking. 331 * 332 * The allocated buffer will be at least one character larger than the given `capacity`, to reserve 333 * space for the terminating '\0'. 334 * 335 * Finalization with `ZyanStringDestroy` is required for all strings created by this function. 336 */ 337 ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateEx(ZyanString* destination, 338 const ZyanStringView* source, ZyanUSize capacity, ZyanAllocator* allocator, 339 float growth_factor, float shrink_threshold); 340 341 /** 342 * @brief Initializes a new `ZyanString` instance by duplicating an existing string and 343 * configures it to use a custom user defined buffer with a fixed size. 344 * 345 * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. 346 * @param source A pointer to the source string. 347 * @param buffer A pointer to the buffer that is used as storage for the string. 348 * @param capacity The maximum capacity (number of characters) of the buffer, including the 349 * terminating '\0'. 350 351 * This function will fail, if the capacity of the buffer is less or equal to 352 * the size of the source string. 353 * 354 * @return A zyan status code. 355 * 356 * The behavior of this function is undefined, if `source` is a view into the `destination` 357 * string or `destination` points to an already initialized `ZyanString` instance. 358 * 359 * Finalization is not required for strings created by this function. 360 */ 361 ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateCustomBuffer(ZyanString* destination, 362 const ZyanStringView* source, char* buffer, ZyanUSize capacity); 363 364 /* ---------------------------------------------------------------------------------------------- */ 365 /* Concatenation */ 366 /* ---------------------------------------------------------------------------------------------- */ 367 368 #ifndef ZYAN_NO_LIBC 369 370 /** 371 * @brief Initializes a new `ZyanString` instance by concatenating two existing strings. 372 * 373 * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. 374 * 375 * This function will fail, if the destination `ZyanString` instance equals 376 * one of the source strings. 377 * @param s1 A pointer to the first source string. 378 * @param s2 A pointer to the second source string. 379 * @param capacity The initial capacity (number of characters). 380 381 * This value is automatically adjusted to the combined size of the source 382 * strings, if a smaller value was passed. 383 * 384 * @return A zyan status code. 385 * 386 * The behavior of this function is undefined, if `s1` or `s2` are views into the `destination` 387 * string or `destination` points to an already initialized `ZyanString` instance. 388 * 389 * The memory for the string is dynamically allocated by the default allocator using the default 390 * growth factor of `2.0f` and the default shrink threshold of `0.25f`. 391 * 392 * The allocated buffer will be at least one character larger than the given `capacity`, to reserve 393 * space for the terminating '\0'. 394 * 395 * Finalization with `ZyanStringDestroy` is required for all strings created by this function. 396 */ 397 ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringConcat(ZyanString* destination, 398 const ZyanStringView* s1, const ZyanStringView* s2, ZyanUSize capacity); 399 400 #endif // ZYAN_NO_LIBC 401 402 /** 403 * @brief Initializes a new `ZyanString` instance by concatenating two existing strings and sets 404 * a custom `allocator` and memory allocation/deallocation parameters. 405 * 406 * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. 407 * 408 * This function will fail, if the destination `ZyanString` instance 409 * equals one of the source strings. 410 * @param s1 A pointer to the first source string. 411 * @param s2 A pointer to the second source string. 412 * @param capacity The initial capacity (number of characters). 413 * 414 * This value is automatically adjusted to the combined size of the 415 * source strings, if a smaller value was passed. 416 * @param allocator A pointer to a `ZyanAllocator` instance. 417 * @param growth_factor The growth factor (from `1.0f` to `x.xf`). 418 * @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`). 419 * 420 * @return A zyan status code. 421 * 422 * The behavior of this function is undefined, if `s1` or `s2` are views into the `destination` 423 * string or `destination` points to an already initialized `ZyanString` instance. 424 * 425 * A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables 426 * dynamic shrinking. 427 * 428 * The allocated buffer will be at least one character larger than the given `capacity`, to reserve 429 * space for the terminating '\0'. 430 * 431 * Finalization with `ZyanStringDestroy` is required for all strings created by this function. 432 */ 433 ZYCORE_EXPORT ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1, 434 const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor, 435 float shrink_threshold); 436 437 /** 438 * @brief Initializes a new `ZyanString` instance by concatenating two existing strings and 439 * configures it to use a custom user defined buffer with a fixed size. 440 * 441 * @param destination A pointer to the (uninitialized) destination `ZyanString` instance. 442 * 443 * This function will fail, if the destination `ZyanString` instance equals 444 * one of the source strings. 445 * @param s1 A pointer to the first source string. 446 * @param s2 A pointer to the second source string. 447 * @param buffer A pointer to the buffer that is used as storage for the string. 448 * @param capacity The maximum capacity (number of characters) of the buffer. 449 * 450 * This function will fail, if the capacity of the buffer is less or equal to 451 * the combined size of the source strings. 452 * 453 * @return A zyan status code. 454 * 455 * The behavior of this function is undefined, if `s1` or `s2` are views into the `destination` 456 * string or `destination` points to an already initialized `ZyanString` instance. 457 * 458 * Finalization is not required for strings created by this function. 459 */ 460 ZYCORE_EXPORT ZyanStatus ZyanStringConcatCustomBuffer(ZyanString* destination, 461 const ZyanStringView* s1, const ZyanStringView* s2, char* buffer, ZyanUSize capacity); 462 463 /* ---------------------------------------------------------------------------------------------- */ 464 /* Views */ 465 /* ---------------------------------------------------------------------------------------------- */ 466 467 /** 468 * @brief Returns a view inside an existing view/string. 469 * 470 * @param view A pointer to the `ZyanStringView` instance. 471 * @param source A pointer to the source string. 472 * 473 * @return A zyan status code. 474 * 475 * The `ZYAN_STRING_TO_VEW` macro can be used to pass any `ZyanString` instance as value for the 476 * `source` string. 477 */ 478 ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideView(ZyanStringView* view, 479 const ZyanStringView* source); 480 481 /** 482 * @brief Returns a view inside an existing view/string starting from the given `index`. 483 * 484 * @param view A pointer to the `ZyanStringView` instance. 485 * @param source A pointer to the source string. 486 * @param index The start index. 487 * @param count The number of characters. 488 * 489 * @return A zyan status code. 490 * 491 * The `ZYAN_STRING_TO_VEW` macro can be used to pass any `ZyanString` instance as value for the 492 * `source` string. 493 */ 494 ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideViewEx(ZyanStringView* view, 495 const ZyanStringView* source, ZyanUSize index, ZyanUSize count); 496 497 /** 498 * @brief Returns a view inside a null-terminated C-style string. 499 * 500 * @param view A pointer to the `ZyanStringView` instance. 501 * @param string The C-style string. 502 * 503 * @return A zyan status code. 504 */ 505 ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideBuffer(ZyanStringView* view, const char* string); 506 507 /** 508 * @brief Returns a view inside a character buffer with custom length. 509 * 510 * @param view A pointer to the `ZyanStringView` instance. 511 * @param buffer A pointer to the buffer containing the string characters. 512 * @param length The length of the string (number of characters). 513 * 514 * @return A zyan status code. 515 */ 516 ZYCORE_EXPORT ZyanStatus ZyanStringViewInsideBufferEx(ZyanStringView* view, const char* buffer, 517 ZyanUSize length); 518 519 /** 520 * @brief Returns the size (number of characters) of the view. 521 * 522 * @param view A pointer to the `ZyanStringView` instance. 523 * @param size Receives the size (number of characters) of the view. 524 * 525 * @return A zyan status code. 526 */ 527 ZYCORE_EXPORT ZyanStatus ZyanStringViewGetSize(const ZyanStringView* view, ZyanUSize* size); 528 529 /** 530 * @brief Returns the C-style string of the given `ZyanString` instance. 531 * 532 * @warning The string is not guaranteed to be null terminated! 533 * 534 * @param string A pointer to the `ZyanStringView` instance. 535 * @param value Receives a pointer to the C-style string. 536 * 537 * @return A zyan status code. 538 */ 539 ZYCORE_EXPORT ZyanStatus ZyanStringViewGetData(const ZyanStringView* view, const char** buffer); 540 541 /* ---------------------------------------------------------------------------------------------- */ 542 /* Character access */ 543 /* ---------------------------------------------------------------------------------------------- */ 544 545 /** 546 * @brief Returns the character at the given `index`. 547 * 548 * @param string A pointer to the `ZyanStringView` instance. 549 * @param index The character index. 550 * @param value Receives the desired character of the string. 551 * 552 * @return A zyan status code. 553 */ 554 ZYCORE_EXPORT ZyanStatus ZyanStringGetChar(const ZyanStringView* string, ZyanUSize index, 555 char* value); 556 557 /** 558 * @brief Returns a pointer to the character at the given `index`. 559 * 560 * @param string A pointer to the `ZyanString` instance. 561 * @param index The character index. 562 * @param value Receives a pointer to the desired character in the string. 563 * 564 * @return A zyan status code. 565 */ 566 ZYCORE_EXPORT ZyanStatus ZyanStringGetCharMutable(ZyanString* string, ZyanUSize index, 567 char** value); 568 569 /** 570 * @brief Assigns a new value to the character at the given `index`. 571 * 572 * @param string A pointer to the `ZyanString` instance. 573 * @param index The character index. 574 * @param value The character to assign. 575 * 576 * @return A zyan status code. 577 */ 578 ZYCORE_EXPORT ZyanStatus ZyanStringSetChar(ZyanString* string, ZyanUSize index, char value); 579 580 /* ---------------------------------------------------------------------------------------------- */ 581 /* Insertion */ 582 /* ---------------------------------------------------------------------------------------------- */ 583 584 /** 585 * @brief Inserts the content of the source string in the destination string at the given `index`. 586 * 587 * @param destination The destination string. 588 * @param index The insert index. 589 * @param source The source string. 590 * 591 * @return A zyan status code. 592 */ 593 ZYCORE_EXPORT ZyanStatus ZyanStringInsert(ZyanString* destination, ZyanUSize index, 594 const ZyanStringView* source); 595 596 /** 597 * @brief Inserts `count` characters of the source string in the destination string at the given 598 * `index`. 599 * 600 * @param destination The destination string. 601 * @param destination_index The insert index. 602 * @param source The source string. 603 * @param source_index The index of the first character to be inserted from the source 604 * string. 605 * @param count The number of chars to insert from the source string. 606 * 607 * @return A zyan status code. 608 */ 609 ZYCORE_EXPORT ZyanStatus ZyanStringInsertEx(ZyanString* destination, ZyanUSize destination_index, 610 const ZyanStringView* source, ZyanUSize source_index, ZyanUSize count); 611 612 /* ---------------------------------------------------------------------------------------------- */ 613 /* Appending */ 614 /* ---------------------------------------------------------------------------------------------- */ 615 616 /** 617 * @brief Appends the content of the source string to the end of the destination string. 618 * 619 * @param destination The destination string. 620 * @param source The source string. 621 * 622 * @return A zyan status code. 623 */ 624 ZYCORE_EXPORT ZyanStatus ZyanStringAppend(ZyanString* destination, const ZyanStringView* source); 625 626 /** 627 * @brief Appends `count` characters of the source string to the end of the destination string. 628 * 629 * @param destination The destination string. 630 * @param source The source string. 631 * @param source_index The index of the first character to be appended from the source string. 632 * @param count The number of chars to append from the source string. 633 * 634 * @return A zyan status code. 635 */ 636 ZYCORE_EXPORT ZyanStatus ZyanStringAppendEx(ZyanString* destination, const ZyanStringView* source, 637 ZyanUSize source_index, ZyanUSize count); 638 639 /* ---------------------------------------------------------------------------------------------- */ 640 /* Deletion */ 641 /* ---------------------------------------------------------------------------------------------- */ 642 643 /** 644 * @brief Deletes characters from the given string, starting at `index`. 645 * 646 * @param string A pointer to the `ZyanString` instance. 647 * @param index The index of the first character to delete. 648 * @param count The number of characters to delete. 649 * 650 * @return A zyan status code. 651 */ 652 ZYCORE_EXPORT ZyanStatus ZyanStringDelete(ZyanString* string, ZyanUSize index, ZyanUSize count); 653 654 /** 655 * @brief Deletes all remaining characters from the given string, starting at `index`. 656 * 657 * @param string A pointer to the `ZyanString` instance. 658 * @param index The index of the first character to delete. 659 * 660 * @return A zyan status code. 661 */ 662 ZYCORE_EXPORT ZyanStatus ZyanStringTruncate(ZyanString* string, ZyanUSize index); 663 664 /** 665 * @brief Erases the given string. 666 * 667 * @param string A pointer to the `ZyanString` instance. 668 * 669 * @return A zyan status code. 670 */ 671 ZYCORE_EXPORT ZyanStatus ZyanStringClear(ZyanString* string); 672 673 /* ---------------------------------------------------------------------------------------------- */ 674 /* Searching */ 675 /* ---------------------------------------------------------------------------------------------- */ 676 677 /** 678 * @brief Searches for the first occurrence of `needle` in the given `haystack` starting from the 679 * left. 680 * 681 * @param haystack The string to search in. 682 * @param needle The sub-string to search for. 683 * @param found_index A pointer to a variable that receives the index of the first occurrence of 684 * `needle`. 685 * 686 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 687 * zyan status code, if an error occured. 688 * 689 * The `found_index` is set to `-1`, if the needle was not found. 690 */ 691 ZYCORE_EXPORT ZyanStatus ZyanStringLPos(const ZyanStringView* haystack, 692 const ZyanStringView* needle, ZyanISize* found_index); 693 694 /** 695 * @brief Searches for the first occurrence of `needle` in the given `haystack` starting from the 696 * left. 697 * 698 * @param haystack The string to search in. 699 * @param needle The sub-string to search for. 700 * @param found_index A pointer to a variable that receives the index of the first occurrence of 701 * `needle`. 702 * @param index The start index. 703 * @param count The maximum number of characters to iterate, beginning from the start 704 * `index`. 705 * 706 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 707 * zyan status code, if an error occured. 708 * 709 * The `found_index` is set to `-1`, if the needle was not found. 710 */ 711 ZYCORE_EXPORT ZyanStatus ZyanStringLPosEx(const ZyanStringView* haystack, 712 const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); 713 714 /** 715 * @brief Performs a case-insensitive search for the first occurrence of `needle` in the given 716 * `haystack` starting from the left. 717 * 718 * @param haystack The string to search in. 719 * @param needle The sub-string to search for. 720 * @param found_index A pointer to a variable that receives the index of the first occurrence of 721 * `needle`. 722 * 723 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 724 * zyan status code, if an error occured. 725 * 726 * The `found_index` is set to `-1`, if the needle was not found. 727 */ 728 ZYCORE_EXPORT ZyanStatus ZyanStringLPosI(const ZyanStringView* haystack, 729 const ZyanStringView* needle, ZyanISize* found_index); 730 731 /** 732 * @brief Performs a case-insensitive search for the first occurrence of `needle` in the given 733 * `haystack` starting from the left. 734 * 735 * @param haystack The string to search in. 736 * @param needle The sub-string to search for. 737 * @param found_index A pointer to a variable that receives the index of the first occurrence of 738 * `needle`. 739 * @param index The start index. 740 * @param count The maximum number of characters to iterate, beginning from the start 741 * `index`. 742 * 743 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 744 * zyan status code, if an error occured. 745 * 746 * The `found_index` is set to `-1`, if the needle was not found. 747 */ 748 ZYCORE_EXPORT ZyanStatus ZyanStringLPosIEx(const ZyanStringView* haystack, 749 const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); 750 751 /** 752 * @brief Searches for the first occurrence of `needle` in the given `haystack` starting from the 753 * right. 754 * 755 * @param haystack The string to search in. 756 * @param needle The sub-string to search for. 757 * @param found_index A pointer to a variable that receives the index of the first occurrence of 758 * `needle`. 759 * 760 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 761 * zyan status code, if an error occured. 762 * 763 * The `found_index` is set to `-1`, if the needle was not found. 764 */ 765 ZYCORE_EXPORT ZyanStatus ZyanStringRPos(const ZyanStringView* haystack, 766 const ZyanStringView* needle, ZyanISize* found_index); 767 768 /** 769 * @brief Searches for the first occurrence of `needle` in the given `haystack` starting from the 770 * right. 771 * 772 * @param haystack The string to search in. 773 * @param needle The sub-string to search for. 774 * @param found_index A pointer to a variable that receives the index of the first occurrence of 775 * `needle`. 776 * @param index The start index. 777 * @param count The maximum number of characters to iterate, beginning from the start 778 * `index`. 779 * 780 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 781 * zyan status code, if an error occured. 782 * 783 * The `found_index` is set to `-1`, if the needle was not found. 784 */ 785 ZYCORE_EXPORT ZyanStatus ZyanStringRPosEx(const ZyanStringView* haystack, 786 const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); 787 788 /** 789 * @brief Performs a case-insensitive search for the first occurrence of `needle` in the given 790 * `haystack` starting from the right. 791 * 792 * @param haystack The string to search in. 793 * @param needle The sub-string to search for. 794 * @param found_index A pointer to a variable that receives the index of the first occurrence of 795 * `needle`. 796 * 797 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 798 * zyan status code, if an error occured. 799 * 800 * The `found_index` is set to `-1`, if the needle was not found. 801 */ 802 ZYCORE_EXPORT ZyanStatus ZyanStringRPosI(const ZyanStringView* haystack, 803 const ZyanStringView* needle, ZyanISize* found_index); 804 805 /** 806 * @brief Performs a case-insensitive search for the first occurrence of `needle` in the given 807 * `haystack` starting from the right. 808 * 809 * @param haystack The string to search in. 810 * @param needle The sub-string to search for. 811 * @param found_index A pointer to a variable that receives the index of the first occurrence of 812 * `needle`. 813 * @param index The start index. 814 * @param count The maximum number of characters to iterate, beginning from the start 815 * `index`. 816 * 817 * @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another 818 * zyan status code, if an error occured. 819 * 820 * The `found_index` is set to `-1`, if the needle was not found. 821 */ 822 ZYCORE_EXPORT ZyanStatus ZyanStringRPosIEx(const ZyanStringView* haystack, 823 const ZyanStringView* needle, ZyanISize* found_index, ZyanUSize index, ZyanUSize count); 824 825 /* ---------------------------------------------------------------------------------------------- */ 826 /* Comparing */ 827 /* ---------------------------------------------------------------------------------------------- */ 828 829 /** 830 * @brief Compares two strings. 831 * 832 * @param s1 The first string 833 * @param s2 The second string. 834 * @param result Receives the comparison result. 835 * 836 * Values: 837 * - `result < 0` -> The first character that does not match has a lower value 838 * in `s1` than in `s2`. 839 * - `result == 0` -> The contents of both strings are equal. 840 * - `result > 0` -> The first character that does not match has a greater value 841 * in `s1` than in `s2`. 842 * 843 * @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another 844 * zyan status code, if an error occured. 845 */ 846 ZYCORE_EXPORT ZyanStatus ZyanStringCompare(const ZyanStringView* s1, const ZyanStringView* s2, 847 ZyanI32* result); 848 849 /** 850 * @brief Performs a case-insensitive comparison of two strings. 851 * 852 * @param s1 The first string 853 * @param s2 The second string. 854 * @param result Receives the comparison result. 855 * 856 * Values: 857 * - `result < 0` -> The first character that does not match has a lower value 858 * in `s1` than in `s2`. 859 * - `result == 0` -> The contents of both strings are equal. 860 * - `result > 0` -> The first character that does not match has a greater value 861 * in `s1` than in `s2`. 862 * 863 * @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another 864 * zyan status code, if an error occured. 865 */ 866 ZYCORE_EXPORT ZyanStatus ZyanStringCompareI(const ZyanStringView* s1, const ZyanStringView* s2, 867 ZyanI32* result); 868 869 /* ---------------------------------------------------------------------------------------------- */ 870 /* Case conversion */ 871 /* ---------------------------------------------------------------------------------------------- */ 872 873 /** 874 * @brief Converts the given string to lowercase letters. 875 * 876 * @param string A pointer to the `ZyanString` instance. 877 * 878 * @return A zyan status code. 879 * 880 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 881 * `ZyanString` instance. 882 */ 883 ZYCORE_EXPORT ZyanStatus ZyanStringToLowerCase(ZyanString* string); 884 885 /** 886 * @brief Converts `count` characters of the given string to lowercase letters. 887 * 888 * @param string A pointer to the `ZyanString` instance. 889 * @param index The start index. 890 * @param count The number of characters to convert, beginning from the start `index`. 891 * 892 * @return A zyan status code. 893 * 894 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 895 * `ZyanString` instance. 896 */ 897 ZYCORE_EXPORT ZyanStatus ZyanStringToLowerCaseEx(ZyanString* string, ZyanUSize index, 898 ZyanUSize count); 899 900 /** 901 * @brief Converts the given string to uppercase letters. 902 * 903 * @param string A pointer to the `ZyanString` instance. 904 * 905 * @return A zyan status code. 906 * 907 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 908 * `ZyanString` instance. 909 */ 910 ZYCORE_EXPORT ZyanStatus ZyanStringToUpperCase(ZyanString* string); 911 912 /** 913 * @brief Converts `count` characters of the given string to uppercase letters. 914 * 915 * @param string A pointer to the `ZyanString` instance. 916 * @param index The start index. 917 * @param count The number of characters to convert, beginning from the start `index`. 918 * 919 * @return A zyan status code. 920 * 921 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 922 * `ZyanString` instance. 923 */ 924 ZYCORE_EXPORT ZyanStatus ZyanStringToUpperCaseEx(ZyanString* string, ZyanUSize index, 925 ZyanUSize count); 926 927 /* ---------------------------------------------------------------------------------------------- */ 928 /* Memory management */ 929 /* ---------------------------------------------------------------------------------------------- */ 930 931 /** 932 * @brief Resizes the given `ZyanString` instance. 933 * 934 * @param string A pointer to the `ZyanString` instance. 935 * @param size The new size of the string. 936 * 937 * @return A zyan status code. 938 * 939 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 940 * `ZyanString` instance. 941 */ 942 ZYCORE_EXPORT ZyanStatus ZyanStringResize(ZyanString* string, ZyanUSize size); 943 944 /** 945 * @brief Changes the capacity of the given `ZyanString` instance. 946 * 947 * @param string A pointer to the `ZyanString` instance. 948 * @param capacity The new minimum capacity of the string. 949 * 950 * @return A zyan status code. 951 * 952 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 953 * `ZyanString` instance. 954 */ 955 ZYCORE_EXPORT ZyanStatus ZyanStringReserve(ZyanString* string, ZyanUSize capacity); 956 957 /** 958 * @brief Shrinks the capacity of the given string to match it's size. 959 * 960 * @param string A pointer to the `ZyanString` instance. 961 * 962 * @return A zyan status code. 963 * 964 * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified 965 * `ZyanString` instance. 966 */ 967 ZYCORE_EXPORT ZyanStatus ZyanStringShrinkToFit(ZyanString* string); 968 969 /* ---------------------------------------------------------------------------------------------- */ 970 /* Information */ 971 /* ---------------------------------------------------------------------------------------------- */ 972 973 /** 974 * @brief Returns the current capacity of the string. 975 * 976 * @param string A pointer to the `ZyanString` instance. 977 * @param capacity Receives the size of the string. 978 * 979 * @return A zyan status code. 980 */ 981 ZYCORE_EXPORT ZyanStatus ZyanStringGetCapacity(const ZyanString* string, ZyanUSize* capacity); 982 983 /** 984 * @brief Returns the current size (number of characters) of the string (excluding the 985 * terminating zero character). 986 * 987 * @param string A pointer to the `ZyanString` instance. 988 * @param size Receives the size (number of characters) of the string. 989 * 990 * @return A zyan status code. 991 */ 992 ZYCORE_EXPORT ZyanStatus ZyanStringGetSize(const ZyanString* string, ZyanUSize* size); 993 994 /** 995 * @brief Returns the C-style string of the given `ZyanString` instance. 996 * 997 * @param string A pointer to the `ZyanString` instance. 998 * @param value Receives a pointer to the C-style string. 999 * 1000 * @return A zyan status code. 1001 */ 1002 ZYCORE_EXPORT ZyanStatus ZyanStringGetData(const ZyanString* string, const char** value); 1003 1004 /* ---------------------------------------------------------------------------------------------- */ 1005 1006 /* ============================================================================================== */ 1007 1008 #ifdef __cplusplus 1009 } 1010 #endif 1011 1012 #endif // ZYCORE_STRING_H 1013