duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

String.h (42167B)


      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 <Zycore/Allocator.h>
     36 #include <Zycore/Status.h>
     37 #include <Zycore/Types.h>
     38 #include <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