| 62 |
62 |
| 63 void cxPropertiesUseStack(CxProperties *prop, |
63 void cxPropertiesUseStack(CxProperties *prop, |
| 64 char *buf, size_t capacity); |
64 char *buf, size_t capacity); |
| 65 ``` |
65 ``` |
| 66 |
66 |
| |
67 The first step is to initialize a `CxProperties` structure with a call to `cxPropertiesInit()` using the desired config. |
| |
68 The shorthand `cxPropertiesInitDefault()` creates a default configuration with the equals sign `'='` as delimiter |
| |
69 and the hash-symbol `'#'` as comment symbol (the other two comment symbols remain unused in the default config). |
| |
70 |
| |
71 > In a future UCX version, the default `continuation` character will be a backslash `'\'`. |
| |
72 > In UCX 3.1 this feature is not implemented, yet. |
| |
73 |
| |
74 The actual parsing is an interleaving invocation of the `cxPropertiesFill()` (or `cxPropertiesFilln()`) and `cxPropertiesNext()` functions. |
| |
75 The `cxPropertiesFill()` function is a convenience function, that accepts UCX strings and normal zero-terminated C strings and behaves otherwise like `cxPropertiesFilln()`. |
| |
76 |
| |
77 Filling the input buffer is cost-free if there is no data already in the input buffer. |
| |
78 In that case, the input buffer only stores the pointer to the original data without creating a copy. |
| |
79 Calling `cxPropertiesNext()` will return with `CX_PROPERTIES_NO_ERROR` (= zero) for each key/value-pair that is successfully parsed, |
| |
80 and stores the pointers and lengths for both the key and the value into the structures pointed to by the `key` and `value` arguments. |
| |
81 |
| |
82 > This is all still free of any copies and allocations. |
| |
83 > That means, the pointers in `key` and `value` after `cxPropertiesNext()` returns will point into the input buffer. |
| |
84 > If you intend to store the key and/or the value somewhere else, it is strongly recommended to create a copy with `cx_strdup()`, |
| |
85 > because you will otherwise soon end up with a dangling pointer. |
| |
86 > {style="note"} |
| |
87 |
| |
88 If `cxPropertiesNext()` returns `CX_PROPERTIES_INCOMPLETE_DATA` it means that the input buffer is exhausted, |
| |
89 but the last line did not contain a full key/value pair. |
| |
90 In that case, you can call `cxPropertiesFill()` again to add more data and continue with `cxPropertiesNext()`. |
| |
91 |
| |
92 Note, that adding more data to a non-empty input buffer will lead to an allocation, |
| |
93 unless you specified some stack memory with `cxPropertiesUseStack()`. |
| |
94 The stack capacity must be large enough to contain the longest line in your data. |
| |
95 If the internal buffer is not large enough to contain a single line, it is extended. |
| |
96 If that is not possible for some reason, `cxPropertiesNext()` fails and returns `CX_PROPERTIES_BUFFER_ALLOC_FAILED`. |
| |
97 |
| |
98 If you want to reuse a `CxProperties` structure with the same config, you can call `cxPropertiesReset()`, even if the last operation was a failure. |
| |
99 Otherwise, you should always call `cxPropertiesDestroy()` when you are done with the parser. |
| |
100 |
| |
101 > It is strongly recommended to always call `cxPropertiesDestroy` when you are done with the parser, |
| |
102 > even if you did not expect any allocations because you used `cxPropertiesUseStack()`. |
| |
103 |
| 67 ### List of Status Codes |
104 ### List of Status Codes |
| |
105 |
| |
106 Below is a full list of error codes for `cxPropertiesNext()`. |
| |
107 |
| |
108 | Status Code | Meaning | |
| |
109 |-----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| |
110 | CX_PROPERTIES_NO_ERROR | A key/value pair was found and returned. | |
| |
111 | CX_PROPERTIES_NO_DATA | The input buffer does not contain more data. | |
| |
112 | 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 `cxPropertiesFill()` to add more data before retrying. | |
| |
113 | CX_PROPERTIES_NULL_INPUT | The input buffer was never initialized. Probably you forgot to call `cxPropertiesFill()` at least once. | |
| |
114 | CX_PROPERTIES_INVALID_EMPTY_KEY | Only white-spaces were found on the left hand-side of the delimiter. Keys must not be empty. | |
| |
115 | CX_PROPERTIES_INVALID_MISSING_DELIMITER | A line contains data, but no delimiter. | |
| |
116 | CX_PROPERTIES_BUFFER_ALLOC_FAILED | More internal buffer was needed, but could not be allocated. | |
| |
117 |
| 68 |
118 |
| 69 ## Sources and Sinks |
119 ## Sources and Sinks |
| 70 |
120 |
| 71 ```C |
121 ```C |
| 72 #include <cx/properties.h> |
122 #include <cx/properties.h> |
| 88 |
138 |
| 89 CxPropertiesStatus |
139 CxPropertiesStatus |
| 90 cxPropertiesLoad(CxProperties *prop, |
140 cxPropertiesLoad(CxProperties *prop, |
| 91 CxPropertiesSink sink, CxPropertiesSource source); |
141 CxPropertiesSink sink, CxPropertiesSource source); |
| 92 ``` |
142 ``` |
| |
143 |
| |
144 <warning> |
| |
145 TODO: write documentation |
| |
146 </warning> |
| |
147 |
| |
148 ### Additional Status Codes |
| |
149 |
| |
150 For sources and sinks there are three additional special status codes, |
| |
151 which only appear as return values for `cxPropertiesLoad()`. |
| |
152 |
| |
153 | Status Code | Meaning | |
| |
154 |-----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| |
155 | CX_PROPERTIES_READ_INIT_FAILED | Initializing the properties source failed and the `cx_properties_read_init_func` returned non-zero. | |
| |
156 | CX_PROPERTIES_READ_FAILED | Reading from a properties source failed and the `cx_properties_read_func` returned non-zero. | |
| |
157 | CX_PROPERTIES_SINK_FAILED | Sinking a key/value-pair failed and the `cx_properties_sink_func` returned non-zero. | |
| |
158 |
| 93 |
159 |
| 94 ### Creating own Sources and Sinks |
160 ### Creating own Sources and Sinks |
| 95 |
161 |
| 96 ```C |
162 ```C |
| 97 #include <cx/properties.h> |
163 #include <cx/properties.h> |