A xstring is a dynamically allocated string of unlimited length. Different instances of xstrings may share the same storage for the string data. xstrings can be NULL.
The xstring API reference is accessible through the PLUGIN_CONTEXT parameter of the plugin_init call.
In case you have C++ you will automatically have a more convenient implementation. You should prefer the C++ syntax where available, because its implementation provides better performance. Note that you must link against the utils/cpputil_plugin library for this API to work properly within plugins. The utils/cpputil library may cause undefined behavior in plugin code!
Function | Description |
---|---|
xstring_create | Create a new instance of a xstring from a C string. |
xstring_free | Release a xstring and set it to NULL. |
xstring_length | Return the length of a xstring. |
xstring_equal | Test two strings for equality. |
xstring_compare | Compare two xstrings. |
xstring_copy | Assign a xstring with another instance. |
xstring_copy_safe | Same as xstring_copy but access to the source string is atomic. |
xstring_assign | Assign a xstring with the value of a C string. |
xstring_cmpassign | Assign a xstring with a new string only if they are different. |
xstring_append | Append the value of a C string to a xstring. |
xstring_allocate | Allocate new storage for a xstring instance. |
xstring_sprintf xstring_vsprintf |
Like sprintf/vsprintf into a xstring. |
xstring_deduplicate | Deduplicate value of xstring instance in memory. |
There are some guidelines you should follow when dealing with xstrings:
All new xstring structures MUST be initialized to NULL or xstring_NULL or with xstring_create.
Free all xstring instances when they go out of scope with xstring_free.
Do not manipulate xstrings other than by the xstring
API functions.
You must neither modify the string (therefore it is const)
nor you should modify the xstring structure directly.
You should not copy xstrings binary. Use xstring_copy
instead.
The difference is, when you use xstring_copy both instances
must be freed while when you make a binary copy exactly one of them
must be freed. But who keeps track of that which one to free?
Furthermore all xstring API functions will implicitly free the old
content when assigning a new value to a xstring. This will
not take care of whether you made a binary copy before.
You cannot modify the content existing xstrings without allocating new storage.
You must not access volatile xstring instances directly.
To achieve strong thread safety always assign local instances of xstring with xstring_copy_safe to access the content of volatile strings.
Only exchanging the binary content of two non-volatile xstring structures is safe without calling a xstring API function.
Furthermore there are guarantees:
Reading the embedded C style string pointer of the xstring structure and the content which it points to is always safe as long as the instance is not modify meanwhile. This implies that you cannot do this with volatile instances.
The string content where a xstring points to is always \0 terminated.
If two xstring instances are binary the same then the C strings are equal too, but not the other way around, because xstrings may contain binary zeros.
All xstring API functions except for xstring_allocate, xstring_equal, xstring_cmpassign and xstring_append are thread-safe. The volatile qualifier will show you atomic access.
The xstring API is lock-free and wait-free.
If the xstring API fails to allocate sufficient memory, the application will terminate.
The API is optimized in a way that empty strings ("") do not use dynamic storage.
If you are compiling with a C++ compiler the type xstring is automatically replaced by a binary compatible class that provides overloaded operators for the most common operations and ensures all of the guidelines. The xstring class implicitly ensures all of the above guidelines. For this to work a global variable PLUGIN_CONTEXT Ctx; must exist and initialized by the argument ctx of plugin_init.
There is one restriction with the C++ API of xstring: You must not assign anything to a xstring instance in a static initializer, more precisely before the plugin_init call. Only calling the default constructor is valid within this context.
The xstring objects are binary compatible in C and C++. So xstring instances may be shared between C and C++ code.
Task | Code example | Remarks |
---|---|---|
Create a xstring with initial value NULL. |
xstring str; |
|
Create a new instance of a xstring from a C string. |
xstring str("bla"); |
|
Release a xstring and set it to NULL. |
str.reset(); |
This is implicitly done by the destructor. |
Return the length of a xstring. |
str.size(); |
|
Test two strings for equality. |
str1 == str2 |
|
Compare two xstrings. |
str1.compareTo(str2) |
|
Assign a xstring with another instance. |
str1 = str2; |
|
Assign a xstring from a shared instance. |
volatile xstring shared; |
This assignment provides strong thread safety. |
Assign a xstring with the value of a C string. |
str1 = "text"; |
|
Assign a xstring with a new string only if they are different. |
bool changed = |
|
Append the value of a C string to a xstring. |
str1 += "append this"; |
|
Allocate new storage for a xstring instance. |
char* cp = str1.allocate(7); |
See xstring_allocate. |
Like sprintf/vsprintf into a xstring. |
str1.sprintf("%i", 5); |
The latter form creates a temporary, e.g. as function argument. |