|
1 /* |
|
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
3 * |
|
4 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 * POSSIBILITY OF SUCH DAMAGE. |
|
27 */ |
|
28 /** |
|
29 * @file properties.h |
|
30 * @brief Interface for parsing data from properties files. |
|
31 * @author Mike Becker |
|
32 * @author Olaf Wintermann |
|
33 * @copyright 2-Clause BSD License |
|
34 */ |
|
35 |
|
36 #ifndef UCX_PROPERTIES_H |
|
37 #define UCX_PROPERTIES_H |
|
38 |
|
39 #include "common.h" |
|
40 #include "string.h" |
|
41 #include "map.h" |
|
42 #include "buffer.h" |
|
43 |
|
44 #include <stdio.h> |
|
45 #include <string.h> |
|
46 |
|
47 #ifdef __cplusplus |
|
48 extern "C" { |
|
49 #endif |
|
50 |
|
51 /** |
|
52 * Configures the expected characters for the properties parser. |
|
53 */ |
|
54 struct cx_properties_config_s { |
|
55 /** |
|
56 * The key/value delimiter that shall be used. |
|
57 * This is '=' by default. |
|
58 */ |
|
59 char delimiter; |
|
60 |
|
61 /** |
|
62 * The first comment character. |
|
63 * This is '#' by default. |
|
64 */ |
|
65 char comment1; |
|
66 |
|
67 /** |
|
68 * The second comment character. |
|
69 * This is not set by default. |
|
70 */ |
|
71 char comment2; |
|
72 |
|
73 /** |
|
74 * The third comment character. |
|
75 * This is not set by default. |
|
76 */ |
|
77 char comment3; |
|
78 |
|
79 /* |
|
80 * The character, when appearing at the end of a line, continues that line. |
|
81 * This is '\' by default. |
|
82 */ |
|
83 /** |
|
84 * Reserved for future use. |
|
85 */ |
|
86 char continuation; |
|
87 }; |
|
88 |
|
89 /** |
|
90 * Typedef for the properties config. |
|
91 */ |
|
92 typedef struct cx_properties_config_s CxPropertiesConfig; |
|
93 |
|
94 /** |
|
95 * Default properties configuration. |
|
96 */ |
|
97 cx_attr_export |
|
98 extern const CxPropertiesConfig cx_properties_config_default; |
|
99 |
|
100 /** |
|
101 * Status codes for the properties interface. |
|
102 */ |
|
103 enum cx_properties_status { |
|
104 /** |
|
105 * Everything is fine. |
|
106 */ |
|
107 CX_PROPERTIES_NO_ERROR, |
|
108 /** |
|
109 * The input buffer does not contain more data. |
|
110 */ |
|
111 CX_PROPERTIES_NO_DATA, |
|
112 /** |
|
113 * The input ends unexpectedly. |
|
114 * |
|
115 * This either happens when the last line does not terminate with a line |
|
116 * break, or when the input ends with a parsed key but no value. |
|
117 */ |
|
118 CX_PROPERTIES_INCOMPLETE_DATA, |
|
119 /** |
|
120 * Not used as a status and never returned by any function. |
|
121 * |
|
122 * You can use this enumerator to check for all "good" status results |
|
123 * by checking if the status is less than @c CX_PROPERTIES_OK. |
|
124 * |
|
125 * A "good" status means, that you can refill data and continue parsing. |
|
126 */ |
|
127 CX_PROPERTIES_OK, |
|
128 /** |
|
129 * Input buffer is @c NULL. |
|
130 */ |
|
131 CX_PROPERTIES_NULL_INPUT, |
|
132 /** |
|
133 * The line contains a delimiter, but no key. |
|
134 */ |
|
135 CX_PROPERTIES_INVALID_EMPTY_KEY, |
|
136 /** |
|
137 * The line contains data, but no delimiter. |
|
138 */ |
|
139 CX_PROPERTIES_INVALID_MISSING_DELIMITER, |
|
140 /** |
|
141 * More internal buffer was needed, but could not be allocated. |
|
142 */ |
|
143 CX_PROPERTIES_BUFFER_ALLOC_FAILED, |
|
144 /** |
|
145 * Initializing the properties source failed. |
|
146 * |
|
147 * @see cx_properties_read_init_func |
|
148 */ |
|
149 CX_PROPERTIES_READ_INIT_FAILED, |
|
150 /** |
|
151 * Reading from a properties source failed. |
|
152 * |
|
153 * @see cx_properties_read_func |
|
154 */ |
|
155 CX_PROPERTIES_READ_FAILED, |
|
156 /** |
|
157 * Sinking a k/v-pair failed. |
|
158 * |
|
159 * @see cx_properties_sink_func |
|
160 */ |
|
161 CX_PROPERTIES_SINK_FAILED, |
|
162 }; |
|
163 |
|
164 /** |
|
165 * Typedef for the properties status enum. |
|
166 */ |
|
167 typedef enum cx_properties_status CxPropertiesStatus; |
|
168 |
|
169 /** |
|
170 * Interface for working with properties data. |
|
171 */ |
|
172 struct cx_properties_s { |
|
173 /** |
|
174 * The configuration. |
|
175 */ |
|
176 CxPropertiesConfig config; |
|
177 |
|
178 /** |
|
179 * The text input buffer. |
|
180 */ |
|
181 CxBuffer input; |
|
182 |
|
183 /** |
|
184 * Internal buffer. |
|
185 */ |
|
186 CxBuffer buffer; |
|
187 }; |
|
188 |
|
189 /** |
|
190 * Typedef for the properties interface. |
|
191 */ |
|
192 typedef struct cx_properties_s CxProperties; |
|
193 |
|
194 |
|
195 /** |
|
196 * Typedef for a properties sink. |
|
197 */ |
|
198 typedef struct cx_properties_sink_s CxPropertiesSink; |
|
199 |
|
200 /** |
|
201 * A function that consumes a k/v-pair in a sink. |
|
202 * |
|
203 * The sink could be e.g. a map and the sink function would be calling |
|
204 * a map function to store the k/v-pair. |
|
205 * |
|
206 * @param prop the properties interface that wants to sink a k/v-pair |
|
207 * @param sink the sink |
|
208 * @param key the key |
|
209 * @param value the value |
|
210 * @retval zero success |
|
211 * @retval non-zero sinking the k/v-pair failed |
|
212 */ |
|
213 cx_attr_nonnull |
|
214 typedef int(*cx_properties_sink_func)( |
|
215 CxProperties *prop, |
|
216 CxPropertiesSink *sink, |
|
217 cxstring key, |
|
218 cxstring value |
|
219 ); |
|
220 |
|
221 /** |
|
222 * Defines a sink for k/v-pairs. |
|
223 */ |
|
224 struct cx_properties_sink_s { |
|
225 /** |
|
226 * The sink object. |
|
227 */ |
|
228 void *sink; |
|
229 /** |
|
230 * Optional custom data. |
|
231 */ |
|
232 void *data; |
|
233 /** |
|
234 * A function for consuming k/v-pairs into the sink. |
|
235 */ |
|
236 cx_properties_sink_func sink_func; |
|
237 }; |
|
238 |
|
239 |
|
240 /** |
|
241 * Typedef for a properties source. |
|
242 */ |
|
243 typedef struct cx_properties_source_s CxPropertiesSource; |
|
244 |
|
245 /** |
|
246 * A function that reads data from a source. |
|
247 * |
|
248 * When the source is depleted, implementations SHALL provide an empty |
|
249 * string in the @p target and return zero. |
|
250 * A non-zero return value is only permitted in case of an error. |
|
251 * |
|
252 * The meaning of the optional parameters is implementation-dependent. |
|
253 * |
|
254 * @param prop the properties interface that wants to read from the source |
|
255 * @param src the source |
|
256 * @param target a string buffer where the read data shall be stored |
|
257 * @retval zero success |
|
258 * @retval non-zero reading the data failed |
|
259 */ |
|
260 cx_attr_nonnull |
|
261 typedef int(*cx_properties_read_func)( |
|
262 CxProperties *prop, |
|
263 CxPropertiesSource *src, |
|
264 cxstring *target |
|
265 ); |
|
266 |
|
267 /** |
|
268 * A function that may initialize additional memory for the source. |
|
269 * |
|
270 * @param prop the properties interface that wants to read from the source |
|
271 * @param src the source |
|
272 * @retval zero initialization was successful |
|
273 * @retval non-zero otherwise |
|
274 */ |
|
275 cx_attr_nonnull |
|
276 typedef int(*cx_properties_read_init_func)( |
|
277 CxProperties *prop, |
|
278 CxPropertiesSource *src |
|
279 ); |
|
280 |
|
281 /** |
|
282 * A function that cleans memory initialized by the read_init_func. |
|
283 * |
|
284 * @param prop the properties interface that wants to read from the source |
|
285 * @param src the source |
|
286 */ |
|
287 cx_attr_nonnull |
|
288 typedef void(*cx_properties_read_clean_func)( |
|
289 CxProperties *prop, |
|
290 CxPropertiesSource *src |
|
291 ); |
|
292 |
|
293 /** |
|
294 * Defines a properties source. |
|
295 */ |
|
296 struct cx_properties_source_s { |
|
297 /** |
|
298 * The source object. |
|
299 * |
|
300 * For example a file stream or a string. |
|
301 */ |
|
302 void *src; |
|
303 /** |
|
304 * Optional additional data pointer. |
|
305 */ |
|
306 void *data_ptr; |
|
307 /** |
|
308 * Optional size information. |
|
309 */ |
|
310 size_t data_size; |
|
311 /** |
|
312 * A function that reads data from the source. |
|
313 */ |
|
314 cx_properties_read_func read_func; |
|
315 /** |
|
316 * Optional function that may prepare the source for reading data. |
|
317 */ |
|
318 cx_properties_read_init_func read_init_func; |
|
319 /** |
|
320 * Optional function that cleans additional memory allocated by the |
|
321 * read_init_func. |
|
322 */ |
|
323 cx_properties_read_clean_func read_clean_func; |
|
324 }; |
|
325 |
|
326 /** |
|
327 * Initialize a properties interface. |
|
328 * |
|
329 * @param prop the properties interface |
|
330 * @param config the properties configuration |
|
331 * @see cxPropertiesInitDefault() |
|
332 */ |
|
333 cx_attr_nonnull |
|
334 cx_attr_export |
|
335 void cxPropertiesInit(CxProperties *prop, CxPropertiesConfig config); |
|
336 |
|
337 /** |
|
338 * Destroys the properties interface. |
|
339 * |
|
340 * @note Even when you are certain that you did not use the interface in a |
|
341 * way that caused a memory allocation, you should call this function anyway. |
|
342 * Future versions of the library might add features that need additional memory |
|
343 * and you really don't want to search the entire code where you might need |
|
344 * add call to this function. |
|
345 * |
|
346 * @param prop the properties interface |
|
347 */ |
|
348 cx_attr_nonnull |
|
349 cx_attr_export |
|
350 void cxPropertiesDestroy(CxProperties *prop); |
|
351 |
|
352 /** |
|
353 * Destroys and re-initializes the properties interface. |
|
354 * |
|
355 * You might want to use this, to reset the parser after |
|
356 * encountering a syntax error. |
|
357 * |
|
358 * @param prop the properties interface |
|
359 */ |
|
360 cx_attr_nonnull |
|
361 static inline void cxPropertiesReset(CxProperties *prop) { |
|
362 CxPropertiesConfig config = prop->config; |
|
363 cxPropertiesDestroy(prop); |
|
364 cxPropertiesInit(prop, config); |
|
365 } |
|
366 |
|
367 /** |
|
368 * Initialize a properties parser with the default configuration. |
|
369 * |
|
370 * @param prop (@c CxProperties*) the properties interface |
|
371 * @see cxPropertiesInit() |
|
372 */ |
|
373 #define cxPropertiesInitDefault(prop) \ |
|
374 cxPropertiesInit(prop, cx_properties_config_default) |
|
375 |
|
376 /** |
|
377 * Fills the input buffer with data. |
|
378 * |
|
379 * After calling this function, you can parse the data by calling |
|
380 * cxPropertiesNext(). |
|
381 * |
|
382 * @remark The properties interface tries to avoid allocations. |
|
383 * When you use this function and cxPropertiesNext() interleaving, |
|
384 * no allocations are performed. However, you must not free the |
|
385 * pointer to the data in that case. When you invoke the fill |
|
386 * function more than once before calling cxPropertiesNext(), |
|
387 * the additional data is appended - inevitably leading to |
|
388 * an allocation of a new buffer and copying the previous contents. |
|
389 * |
|
390 * @param prop the properties interface |
|
391 * @param buf a pointer to the data |
|
392 * @param len the length of the data |
|
393 * @retval zero success |
|
394 * @retval non-zero a memory allocation was necessary but failed |
|
395 * @see cxPropertiesFill() |
|
396 */ |
|
397 cx_attr_nonnull |
|
398 cx_attr_access_r(2, 3) |
|
399 cx_attr_export |
|
400 int cxPropertiesFilln( |
|
401 CxProperties *prop, |
|
402 const char *buf, |
|
403 size_t len |
|
404 ); |
|
405 |
|
406 #ifdef __cplusplus |
|
407 } // extern "C" |
|
408 cx_attr_nonnull |
|
409 static inline int cxPropertiesFill( |
|
410 CxProperties *prop, |
|
411 cxstring str |
|
412 ) { |
|
413 return cxPropertiesFilln(prop, str.ptr, str.length); |
|
414 } |
|
415 |
|
416 cx_attr_nonnull |
|
417 static inline int cxPropertiesFill( |
|
418 CxProperties *prop, |
|
419 cxmutstr str |
|
420 ) { |
|
421 return cxPropertiesFilln(prop, str.ptr, str.length); |
|
422 } |
|
423 |
|
424 cx_attr_nonnull |
|
425 cx_attr_cstr_arg(2) |
|
426 static inline int cxPropertiesFill( |
|
427 CxProperties *prop, |
|
428 const char *str |
|
429 ) { |
|
430 return cxPropertiesFilln(prop, str, strlen(str)); |
|
431 } |
|
432 |
|
433 extern "C" { |
|
434 #else // __cplusplus |
|
435 /** |
|
436 * Fills the input buffer with data. |
|
437 * |
|
438 * After calling this function, you can parse the data by calling |
|
439 * cxPropertiesNext(). |
|
440 * |
|
441 * @attention The properties interface tries to avoid allocations. |
|
442 * When you use this function and cxPropertiesNext() interleaving, |
|
443 * no allocations are performed. However, you must not free the |
|
444 * pointer to the data in that case. When you invoke the fill |
|
445 * function more than once before calling cxPropertiesNext(), |
|
446 * the additional data is appended - inevitably leading to |
|
447 * an allocation of a new buffer and copying the previous contents. |
|
448 * |
|
449 * @param prop the properties interface |
|
450 * @param str the text to fill in |
|
451 * @retval zero success |
|
452 * @retval non-zero a memory allocation was necessary but failed |
|
453 * @see cxPropertiesFilln() |
|
454 */ |
|
455 #define cxPropertiesFill(prop, str) _Generic((str), \ |
|
456 cxstring: cx_properties_fill_cxstr, \ |
|
457 cxmutstr: cx_properties_fill_mutstr, \ |
|
458 char*: cx_properties_fill_str, \ |
|
459 const char*: cx_properties_fill_str) \ |
|
460 (prop, str) |
|
461 |
|
462 /** |
|
463 * @copydoc cxPropertiesFill() |
|
464 */ |
|
465 cx_attr_nonnull |
|
466 static inline int cx_properties_fill_cxstr( |
|
467 CxProperties *prop, |
|
468 cxstring str |
|
469 ) { |
|
470 return cxPropertiesFilln(prop, str.ptr, str.length); |
|
471 } |
|
472 |
|
473 /** |
|
474 * @copydoc cxPropertiesFill() |
|
475 */ |
|
476 cx_attr_nonnull |
|
477 static inline int cx_properties_fill_mutstr( |
|
478 CxProperties *prop, |
|
479 cxmutstr str |
|
480 ) { |
|
481 return cxPropertiesFilln(prop, str.ptr, str.length); |
|
482 } |
|
483 |
|
484 /** |
|
485 * @copydoc cxPropertiesFill() |
|
486 */ |
|
487 cx_attr_nonnull |
|
488 cx_attr_cstr_arg(2) |
|
489 static inline int cx_properties_fill_str( |
|
490 CxProperties *prop, |
|
491 const char *str |
|
492 ) { |
|
493 return cxPropertiesFilln(prop, str, strlen(str)); |
|
494 } |
|
495 #endif |
|
496 |
|
497 /** |
|
498 * Specifies stack memory that shall be used as internal buffer. |
|
499 * |
|
500 * @param prop the properties interface |
|
501 * @param buf a pointer to stack memory |
|
502 * @param capacity the capacity of the stack memory |
|
503 */ |
|
504 cx_attr_nonnull |
|
505 cx_attr_export |
|
506 void cxPropertiesUseStack( |
|
507 CxProperties *prop, |
|
508 char *buf, |
|
509 size_t capacity |
|
510 ); |
|
511 |
|
512 /** |
|
513 * Retrieves the next key/value-pair. |
|
514 * |
|
515 * This function returns zero as long as there are key/value-pairs found. |
|
516 * If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA is returned. |
|
517 * |
|
518 * When an incomplete line is encountered, #CX_PROPERTIES_INCOMPLETE_DATA is |
|
519 * returned, and you can add more data with #cxPropertiesFill(). |
|
520 * |
|
521 * @remark The incomplete line will be stored in an internal buffer, which is |
|
522 * allocated on the heap, by default. If you want to avoid allocations, |
|
523 * you can specify sufficient space with cxPropertiesUseStack() after |
|
524 * initialization with cxPropertiesInit(). |
|
525 * |
|
526 * @attention The returned strings will point into a buffer that might not be |
|
527 * available later. It is strongly recommended to copy the strings for further |
|
528 * use. |
|
529 * |
|
530 * @param prop the properties interface |
|
531 * @param key a pointer to the cxstring that shall contain the property name |
|
532 * @param value a pointer to the cxstring that shall contain the property value |
|
533 * @retval CX_PROPERTIES_NO_ERROR (zero) a key/value pair was found |
|
534 * @retval CX_PROPERTIES_NO_DATA there is no (more) data in the input buffer |
|
535 * @retval CX_PROPERTIES_INCOMPLETE_DATA the data in the input buffer is incomplete |
|
536 * (fill more data and try again) |
|
537 * @retval CX_PROPERTIES_NULL_INPUT the input buffer was never filled |
|
538 * @retval CX_PROPERTIES_INVALID_EMPTY_KEY the properties data contains an illegal empty key |
|
539 * @retval CX_PROPERTIES_INVALID_MISSING_DELIMITER the properties data contains a line without delimiter |
|
540 * @retval CX_PROPERTIES_BUFFER_ALLOC_FAILED an internal allocation was necessary but failed |
|
541 */ |
|
542 cx_attr_nonnull |
|
543 cx_attr_nodiscard |
|
544 cx_attr_export |
|
545 CxPropertiesStatus cxPropertiesNext( |
|
546 CxProperties *prop, |
|
547 cxstring *key, |
|
548 cxstring *value |
|
549 ); |
|
550 |
|
551 /** |
|
552 * Creates a properties sink for an UCX map. |
|
553 * |
|
554 * The values stored in the map will be pointers to freshly allocated, |
|
555 * zero-terminated C strings (@c char*), which means the @p map should have been |
|
556 * created with #CX_STORE_POINTERS. |
|
557 * |
|
558 * The default stdlib allocator will be used, unless you specify a custom |
|
559 * allocator in the optional @c data field of the returned sink. |
|
560 * |
|
561 * @param map the map that shall consume the k/v-pairs. |
|
562 * @return the sink |
|
563 * @see cxPropertiesLoad() |
|
564 */ |
|
565 cx_attr_nonnull |
|
566 cx_attr_nodiscard |
|
567 cx_attr_export |
|
568 CxPropertiesSink cxPropertiesMapSink(CxMap *map); |
|
569 |
|
570 /** |
|
571 * Creates a properties source based on an UCX string. |
|
572 * |
|
573 * @param str the string |
|
574 * @return the properties source |
|
575 * @see cxPropertiesLoad() |
|
576 */ |
|
577 cx_attr_nodiscard |
|
578 cx_attr_export |
|
579 CxPropertiesSource cxPropertiesStringSource(cxstring str); |
|
580 |
|
581 /** |
|
582 * Creates a properties source based on C string with the specified length. |
|
583 * |
|
584 * @param str the string |
|
585 * @param len the length |
|
586 * @return the properties source |
|
587 * @see cxPropertiesLoad() |
|
588 */ |
|
589 cx_attr_nonnull |
|
590 cx_attr_nodiscard |
|
591 cx_attr_access_r(1, 2) |
|
592 cx_attr_export |
|
593 CxPropertiesSource cxPropertiesCstrnSource(const char *str, size_t len); |
|
594 |
|
595 /** |
|
596 * Creates a properties source based on a C string. |
|
597 * |
|
598 * The length will be determined with strlen(), so the string MUST be |
|
599 * zero-terminated. |
|
600 * |
|
601 * @param str the string |
|
602 * @return the properties source |
|
603 * @see cxPropertiesLoad() |
|
604 */ |
|
605 cx_attr_nonnull |
|
606 cx_attr_nodiscard |
|
607 cx_attr_cstr_arg(1) |
|
608 cx_attr_export |
|
609 CxPropertiesSource cxPropertiesCstrSource(const char *str); |
|
610 |
|
611 /** |
|
612 * Creates a properties source based on an FILE. |
|
613 * |
|
614 * @param file the file |
|
615 * @param chunk_size how many bytes may be read in one operation |
|
616 * |
|
617 * @return the properties source |
|
618 * @see cxPropertiesLoad() |
|
619 */ |
|
620 cx_attr_nonnull |
|
621 cx_attr_nodiscard |
|
622 cx_attr_access_r(1) |
|
623 cx_attr_export |
|
624 CxPropertiesSource cxPropertiesFileSource(FILE *file, size_t chunk_size); |
|
625 |
|
626 |
|
627 /** |
|
628 * Loads properties data from a source and transfers it to a sink. |
|
629 * |
|
630 * This function tries to read as much data from the source as possible. |
|
631 * When the source was completely consumed and at least on k/v-pair was found, |
|
632 * the return value will be #CX_PROPERTIES_NO_ERROR. |
|
633 * When the source was consumed but no k/v-pairs were found, the return value |
|
634 * will be #CX_PROPERTIES_NO_DATA. |
|
635 * In case the source data ends unexpectedly, the #CX_PROPERTIES_INCOMPLETE_DATA |
|
636 * is returned. In that case you should call this function again with the same |
|
637 * sink and either an updated source or the same source if the source is able to |
|
638 * yield the missing data. |
|
639 * |
|
640 * The other result codes apply, according to their description. |
|
641 * |
|
642 * @param prop the properties interface |
|
643 * @param sink the sink |
|
644 * @param source the source |
|
645 * @retval CX_PROPERTIES_NO_ERROR (zero) a key/value pair was found |
|
646 * @retval CX_PROPERTIES_READ_INIT_FAILED initializing the source failed |
|
647 * @retval CX_PROPERTIES_READ_FAILED reading from the source failed |
|
648 * @retval CX_PROPERTIES_SINK_FAILED sinking the properties into the sink failed |
|
649 * @retval CX_PROPERTIES_NO_DATA the source did not provide any key/value pairs |
|
650 * @retval CX_PROPERTIES_INCOMPLETE_DATA the source did not provide enough data |
|
651 * @retval CX_PROPERTIES_INVALID_EMPTY_KEY the properties data contains an illegal empty key |
|
652 * @retval CX_PROPERTIES_INVALID_MISSING_DELIMITER the properties data contains a line without delimiter |
|
653 * @retval CX_PROPERTIES_BUFFER_ALLOC_FAILED an internal allocation was necessary but failed |
|
654 */ |
|
655 cx_attr_nonnull |
|
656 cx_attr_export |
|
657 CxPropertiesStatus cxPropertiesLoad( |
|
658 CxProperties *prop, |
|
659 CxPropertiesSink sink, |
|
660 CxPropertiesSource source |
|
661 ); |
|
662 |
|
663 #ifdef __cplusplus |
|
664 } // extern "C" |
|
665 #endif |
|
666 |
|
667 #endif // UCX_PROPERTIES_H |