Interface for operating on a sequence of characters.
A FACE_string is defined by three characteristics:
- length - the current number of characters (excluding NUL) in the FACE_string
- bound - the maximum number of characters (excluding NUL) the FACE_string can ever hold. This bound is logical, and is independent from the size of any underlying memory. A FACE_string's bound is fixed throughout the lifetime of the FACE_string. An "unbounded" FACE_string has an infinite bound, represented by FACE_STRING_UNBOUNDED_SENTINEL.
- capacity - the number of characters (excluding NUL) a FACE_string has currently allocated memory for. This may vary by implementation, but length <= capacity <= bound is always true.
A "managed" FACE_string is responsible for and manages the lifetime of the memory for the data it represents. An "unmanaged" FACE_string essentially wraps a pointer to memory whose lifetime is managed elsewhere.
A FACE_string is "initialized" if it is in a state that could have resulted from successful initialization by one of the "_init" functions. Any other state makes the FACE_string "uninitialized".
When a memory allocation failure or precondition violation occurs, a FACE_string is put into a known "invalid state". In this invalid state:
- length, capacity, and bound are 0
- FACE_string_buffer() will return NULL
- FACE_string_is_managed() and FACE_string_is_bounded() will return FALSE The FACE_string_is_valid() function indicates whether or not a FACE_string is in this state.
Global preconditions:
- In every function, if the
this_obj
parameter is NULL, the function does nothing and returns FACE_STRING_NULL_THIS.
- In every _init function, if this_obj is already initialized, FACE_STRING_PRECONDITION_VIOLATED is returned and the state of this_obj is not modified.
- In every non _init function, if this_obj has not been initialized, FACE_STRING_PRECONDITION_VIOLATED is returned and the state of this_obj is not modified.