Properties
The UCX properties parser can be used to parse line-based key/value strings.
Supported Syntax
Key/value pairs must be line-based and separated by a single character delimiter. The parser supports up to three different characters which introduce comments. All characters starting with a comment character up to the end of the line are ignored. Blank lines are also ignored.
An example properties file looks like this:
Basic Parsing
The following listing shows the properties-parser API.
The first step is to initialize a CxProperties structure with a call to cxPropertiesInit() using the desired config. The shorthand cxPropertiesInitDefault() creates a default configuration with the equals sign '=' as delimiter and the hash-symbol '#' as comment symbol (the other two comment symbols remain unused in the default config). The line continuation symbol is set to '\'. Note that leading spaces of a continuing line are ignored.
The actual parsing is an interleaving invocation of the cxPropertiesFill() (or cxPropertiesFilln()) and cxPropertiesNext() functions. The cxPropertiesFill() function is a convenience function that accepts UCX strings and normal zero-terminated C strings and behaves otherwise like cxPropertiesFilln().
Filling the input buffer is cost-free if there is no data already in the input buffer. In that case, the input buffer only stores the pointer to the original data without creating a copy. Calling cxPropertiesNext() will return with CX_PROPERTIES_NO_ERROR (= zero) for each key/value-pair that is successfully parsed and stores the pointers and lengths for both the key and the value into the structures pointed to by the key and value arguments.
When all the data from the input buffer was successfully consumed, cxPropertiesNext() returns CX_PROPERTIES_NO_DATA.
If cxPropertiesNext() returns CX_PROPERTIES_INCOMPLETE_DATA, the input buffer is exhausted, but the last line did not contain a full key/value pair. In that case, you can call cxPropertiesFill() again to add more data and continue with cxPropertiesNext().
Note that adding more data to a non-empty input buffer will lead to an allocation, unless you specified some stack memory with cxPropertiesUseStack(). The stack capacity must be large enough to contain the longest line in your data. If the internal buffer is not large enough to contain a single line, it is extended. If that is not possible for some reason, cxPropertiesNext() fails and returns CX_PROPERTIES_BUFFER_ALLOC_FAILED.
If you want to reuse a CxProperties structure with the same config, you can call cxPropertiesReset(), even if the last operation was a failure. Otherwise, you should always call cxPropertiesDestroy() when you are done with the parser.
All the above operations are combined in the function cxPropertiesLoad(), which opens the file designated by the filename and loads all properties from that file into the specified CxMap. The convenience macro cxPropertiesLoadDefault() uses the default parser configuration for this. The target map must either store pointers of type char* or elements of type cxmutstr. In either case, the specified allocator is used to allocate the memory for the value. If the function encounters an error, all properties that have been added to the map so far stay in the map; there is no rollback.
List of Status Codes
Below is a full list of status codes for cxPropertiesNext() and cxPropertiesLoad().
Status Code | Meaning |
|---|---|
CX_PROPERTIES_NO_ERROR | A key/value pair was found and returned. |
CX_PROPERTIES_NO_DATA | The input buffer does not contain data. |
CX_PROPERTIES_INCOMPLETE_DATA | The input ends unexpectedly. This can happen when the last line does not terminate with a line break, or when the input ends with a parsed key but no value. Use |
CX_PROPERTIES_NULL_INPUT | The input buffer was never initialized. Probably you forgot to call |
CX_PROPERTIES_INVALID_EMPTY_KEY | Only white-spaces were found on the left hand-side of the delimiter. Keys must not be empty. |
CX_PROPERTIES_INVALID_MISSING_DELIMITER | A line contains data, but no delimiter. |
CX_PROPERTIES_BUFFER_ALLOC_FAILED | More internal buffer was needed, but could not be allocated. |
CX_PROPERTIES_FILE_ERROR | A file operation failed (only for |
For cxPropertiesLoad() the status code CX_PROPERTIES_NO_ERROR means that at least one property was loaded into the map, while CX_PROPERTIES_NO_DATA means that the file is syntactically fine but does not contain any properties.