typedef struct
{ const char* cstr; /* pointer to C style null terminated string */
} xstring;
The xstring structure is binary
compatible to a C style pointer to a constant string. The structure is
only used to provide type safety.
You may read the cstr member safely as long as the xstring
instance does not change asynchronously.
There is no such function for performance reasons. Simply initialize all xstrings with the constant xstring_NULL or use memset(..., 0, ...). But don't forget to do so and do not assign xstring_NULL to used xstrings.
xstring DLLENTRY xstring_create( const char* cstr );
Initialize a new xstring from a C style string. The return value can be directly assigned to a new xstring and might be used for constant xstrings. You must not use this function to assign existing, used xstrings. Use xstring_assign instead.
void DLLENTRY xstring_free( volatile xstring* dst );
Set the xstring to NULL and release the storage where dst points to if it is not used by another xstring instance. If *dst is NULL this is a no-op.
Calling xstring_free twice for the same object will not be an error and it is allowed to use the xstring instance afterwards normally. In fact xstring_free is equivalent to call xstring_assign with NULL.
unsigned DLLENTRY xstring_length( const xstring* src );
char DLLENTRY xstring_equal( const xstring* src1, const xstring* src2 );
Compares two instances of xstring binary. NULL strings are only equal to them self. Both strings must not change asynchronously.
Note that the result may be not the same than comparing the two strings with strcmp since xstrings may contain null bytes and be different afterwards.
The comparison only takes O(n) if both strings have the same length and do not share the same storage as copies made with xstring_copy do.
int DLLENTRY xstring_compare( const xstring* src1, const xstring* src2 );
Compares two instances of xstring binary. NULL strings are less than anything else including "". Both strings must not change asynchronously.
Note that the result may be not the same than comparing the two strings with strcmp since xstrings may contain null bytes and be different afterwards.
void DLLENTRY xstring_copy( volatile xstring* dst, const xstring* src );
Release the old value of *dst and place a new reference to *src into *dst.
Note that xstring_copy will never copy the content of *src. It will only increment the reference count.
void DLLENTRY xstring_copy_safe( volatile xstring* dst, volatile const xstring* src );
xstring_copy_safe is strongly thread-safe version of xstring_copy. Fetching the value of *src and placing a strong reference to it in *dst is atomic.
Note that xstring_copy_safe will never copy the content of *src. It will only increment the reference count.
void DLLENTRY xstring_assign( volatile xstring* dst, const char* cstr );
Release the old value of *dst, allocate a new xstring, initialize it with the content of cstr and assign it to *dst. If cstr is NULL *dst is cleared.
char DLLENTRY xstring_cmpassign( xstring* dst, const char* cstr );
Copies the value of cstr into *dst if and only if the strings are different. This is useful to keep track of changes. Furthermore if the storage of *dst is shared with other xstring instances, an assignment of an identical string will not destroy the storage sharing.
void DLLENTRY xstring_append( xstring* dst, const char* cstr );
Appends the string *src to *dst. Both must not be NULL. The operation is not atomic.
You should avoid repeated calls to xstring_append to concatenate multiple strings for performance reasons. This will in total perform O(n2). It is better to allocate the required storage at once with xstring_alloc and fill the content afterwards.
char* DLLENTRY xstring_allocate( xstring* dst, unsigned int len );
Allocate a new xstring with uninitialized storage of len characters and assign it to *dst. The old value of *dst is freed. The returned value is always the same as the new value of dst->cstr except for constness.
You may then write up to len characters to the memory where the return value points to. It is allowed to write one additional \0 byte behind the len characters, but no other value must be placed there. The null byte is initialized by xstring_alloc anyway.
You may modify the returned memory until the next xstring API function call for *dst.
void DLLENTRY xstring_sprintf( volatile xstring* dst, const char* fmt, ... );
void DLLENTRY xstring_vsprintf( volatile xstring* dst, const char* fmt, va_list va );
Release the old value of *dst and place a formatted output into *dst. The behavior of this functions is similar to sprintf/vsprintf but unlike the C library functions these functions are safe with respect to the length of the returned string. They will always allocate enough memory automatically.