tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

String.h (42191B)


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