le_cfg_interface.h

Go to the documentation of this file.
1 
2 
3 /*
4  * ====================== WARNING ======================
5  *
6  * THE CONTENTS OF THIS FILE HAVE BEEN AUTO-GENERATED.
7  * DO NOT MODIFY IN ANY WAY.
8  *
9  * ====================== WARNING ======================
10  */
11 
12 /**
13  * @page c_config Config Tree API
14  *
15  * @ref le_cfg_interface.h "API Reference" <br>
16  * @ref howToConfigTree
17  *
18  * <HR>
19  *
20  * The Config Tree API is used by apps to read and write their specific configurations.
21  * Each app is given an isolated tree. The system utilities
22  * store their configuration in the @c root tree.
23  * Trees are created when they are first accessed by a user or component/process etc.
24  * Apps automatically get read access to a tree with the same name as the app.
25  * Apps can also be granted read or write access to any other tree with any other name (e.g., a tree
26  * named @c foo can be shared with @e appA and @e appB).
27  *
28  * Paths in the tree look like traditional Unix style paths like this:
29  *
30  * @code /path/to/my/value @endcode
31  *
32  * The path root is the root of the tree where the app has been given access. If the
33  * app has permission to access another tree, the path can also include the name
34  * of the other tree, followed by a colon.
35  *
36  * @code secondTree:/path/to/my/value @endcode
37  *
38  * In this case, a value named @c value is read from the tree named @c secondTree
39  *
40  * The tree is broken down into stems and leaves.
41  *
42  * A stem is a node that has at least one child
43  * node. A leaf has no children, but can hold a value.
44  *
45  * The config tree supports string, signed integer, boolean, floating point, and empty
46  * values. It's recommended to store anything more complex using stems and leaves, which enhances
47  * readablity and debugging. It also sidesteps nasty cross platform alignment issues.
48  *
49  * @todo Talk about the treeConfig, user limits, tree name, tree access. Global timeouts.
50  *
51  * @section cfg_transaction Read and Write Transactions
52  *
53  * The config tree uses simple transactions to work with its data. Both read
54  * and write transactions are supported. Use read transactions to ensure you can
55  * atomically read multiple values from your configuration while keeping consistency
56  * with third parties trying to write data.
57  *
58  * To prevent a single client from locking out other clients, read and
59  * write transactions have their own configurable timeout.
60  *
61  * During a write transaction, both reading and writing are allowed. If you
62  * write a value during a transaction and read from that value again, you will get the same value
63  * you wrote. Third party clients will continue to see the old value. It's not until you commit
64  * your transaction that third parties will begin to see your updated value.
65  *
66  * During read transactions, writes are not permitted and are thrown away.
67  *
68  * Transactions are started by creating an iterator. Either a read or write iterator can be
69  * created. To end the transaction, you can delete the iterator, cancelling the
70  * transaction. Or,for write transactions, you can commit the iterator.
71  *
72  * You can have multiple read transactions against the tree. They won't
73  * block other transactions from being creating. A read transaction won't block creating a write
74  * transaction either. A read transaction only blocks a write transaction from being
75  * comitted to the tree.
76  *
77  * A write transaction in progress will also block creating another write transaction.
78  * If a write transaction is in progress when the request for another write transaction comes in,
79  * the secondary request will be blocked. This secondary request will remain blocked until the
80  * first transaction has been comitted or has timed out. The transaction timeout default is 30
81  * seconds. You can extend the timeout by setting a value (in seconds) in
82  * @c configTree/transactionTimeout.
83  *
84  * @section cfg_iteration Iterating the Tree
85  *
86  * This code sample shows how to iterate a specified node and print its contents:
87  *
88  * @code
89  * static void PrintNode(le_cfg_IteratorRef_t iteratorRef)
90  * {
91  * do
92  * {
93  * char stringBuffer[MAX_CFG_STRING] = { 0 };
94  *
95  * le_cfg_GetNodeName(iteratorRef, "", stringBuffer, sizeof(stringBuffer));
96  *
97  * switch (le_cfg_GetNodeType(iteratorRef, ""))
98  * {
99  * case LE_CFG_TYPE_STEM:
100  * {
101  * printf("%s/\n", stringBuffer);
102  *
103  * if (le_cfg_GoToFirstChild(iteratorRef) == LE_OK)
104  * {
105  * PrintNode(iteratorRef);
106  * le_cfg_GoToNode(iteratorRef, "..");
107  * }
108  * }
109  * break;
110  *
111  * case LE_CFG_TYPE_EMPTY:
112  * printf("%s = *empty*\n", stringBuffer);
113  * break;
114  *
115  * case LE_CFG_TYPE_BOOL:
116  * printf("%s = %s\n",
117  * stringBuffer,
118  * (le_cfg_GetBool(iteratorRef, "", false) ? "true" : "false"));
119  * break;
120  *
121  * case LE_CFG_TYPE_INT:
122  * printf("%s = %d\n", stringBuffer, le_cfg_GetInt(iteratorRef, "", 0));
123  * break;
124  *
125  * case LE_CFG_TYPE_FLOAT:
126  * printf("%s = %f\n", stringBuffer, le_cfg_GetFloat(iteratorRef, "", 0.0));
127  * break;
128  *
129  * case LE_CFG_TYPE_STRING:
130  * printf("%s = ", stringBuffer);
131  * LE_ASSERT(le_cfg_GetString(iteratorRef,
132  * "",
133  * stringBuffer,
134  * sizeof(stringBuffer),
135  * "") == LE_OK);
136  * printf("%s\n", stringBuffer);
137  * break;
138  *
139  * case LE_CFG_TYPE_DOESNT_EXIST:
140  * printf("%s = ** DENIED **\n", stringBuffer);
141  * break;
142  * }
143  * }
144  * while (le_cfg_GoToNextSibling(iteratorRef) == LE_OK);
145  * }
146  *
147  *
148  * le_cfg_IteratorRef_t iteratorRef = le_cfg_CreateReadTxn("/path/to/my/location");
149  *
150  * PrintNode(iteratorRef);
151  * le_cfg_CancelTxn(iteratorRef);
152  *
153  *
154  * @endcode
155  *
156  *
157  * @section cfg_transactWrite Writing Configuration Data
158  *
159  * This code sample uses a write transaction to update a target's IP address
160  * so the data is written atomically.
161  *
162  * @code
163  * void SetIp4Static
164  * (
165  * le_cfg_IteratorRef_t iteratorRef,
166  * const char* interfaceNamePtr,
167  * const char* ipAddrPtr,
168  * const char* netMaskPtr
169  * )
170  * {
171  * // Change current tree position to the base ip4 node.
172  * char nameBuffer[MAX_CFG_STRING] = { 0 };
173  *
174  * int r = snprintf(nameBuffer, sizeof(nameBuffer), "/system/%s/ip4", interfaceNamePtr);
175  * LE_ASSERT((r >= 0) && (r < sizeof(nameBuffer));
176  *
177  * le_cfg_GoToNode(iteratorRef, nameBuffer);
178  *
179  * le_cfg_SetString(iteratorRef, "addr", ipAddrPtr);
180  * le_cfg_SetString(iteratorRef, "mask", netMaskPtr);
181  *
182  * le_cfg_CommitTxn(iteratorRef);
183  * }
184  * @endcode
185  *
186  *
187  * @section cfg_transactRead Reading Configuration Data
188  *
189  * This is a code sample of a read transaction.
190  *
191  * @code
192  * le_result_t GetIp4Static
193  * (
194  * le_cfg_IteratorRef_t iteratorRef,
195  * const char* interfaceNamePtr,
196  * char* ipAddrPtr,
197  * size_t ipAddrSize,
198  * char* netMaskPtr,
199  * size_t netMaskSize
200  * )
201  * {
202  * // Change current tree position to the base ip4 node.
203  * char nameBuffer[MAX_CFG_STRING] = { 0 };
204  *
205  * int r = snprintf(nameBuffer, sizeof(nameBuffer), "/system/%s/ip4", interfaceNamePtr);
206  * if (r < 0)
207  * {
208  * return LE_FAULT;
209  * }
210  * else if (r >= sizeof(nameBuffer))
211  * {
212  * return LE_OVERFLOW;
213  * }
214  *
215  * if (le_cfg_NodeExists(iteratorRef, nameBuffer) == false)
216  * {
217  * LE_WARN("Configuration not found.");
218  * return LE_NOT_FOUND;
219  * }
220  *
221  * le_cfg_GoToNode(iteratorRef, nameBuffer);
222  *
223  * le_cfg_GetString(iteratorRef, "addr", ipAddrPtr, ipAddrSize, "");
224  * le_cfg_GetString(iteratorRef, "mask", netMaskPtr, netMaskSize, "");
225  *
226  * return LE_OK;
227  * }
228  * @endcode
229  *
230  *
231  * @section cfg_quick Working without Transactions
232  *
233  * It's possible to ignore iterators and transactions entirely (e.g., if all you need to do
234  * is read or write some simple values in the tree).
235  *
236  * The non-transactional reads and writes work almost identically to the transactional versions.
237  * They just don't explictly take an iterator object. The "quick" functions internally use an
238  * implicit transaction. This implicit transaction wraps one get or set, and does not protect
239  * your code from other activity in the system.
240  *
241  * Because these functions don't take an explicit transaction, they can't work with relative
242  * paths. If a relative path is given, the path will be considered relative to the tree's root.
243  *
244  * Translating this to a "quick" (non-transactional) example looks like this:
245  *
246  * @code
247  * void ClearIpInfo
248  * (
249  * const char* interfaceNamePtr
250  * )
251  * {
252  * char pathBuffer[MAX_CFG_STRING] = { 0 };
253  *
254  * snprintf(pathBuffer, sizeof(pathBuffer), "/system/%s/ip4/", interfaceNamePtr);
255  * le_cfg_QuickDeleteNode(pathBuffer);
256  * }
257  * @endcode
258  *
259  * @note Because each read is independant, there's no guarantee of
260  * consistency between them. If another process changes one of the values while you
261  * read/write the other, the two values could be read out of sync.
262  *
263  * You'll also need to set @ref howToConfigTree_nonTxn.
264  *
265  * <HR>
266  *
267  * Copyright (C) Sierra Wireless Inc.
268  */
269 /**
270  * @file le_cfg_interface.h
271  *
272  * Legato @ref c_config include file.
273  *
274  * Copyright (C) Sierra Wireless Inc.
275  */
276 
277 #ifndef LE_CFG_INTERFACE_H_INCLUDE_GUARD
278 #define LE_CFG_INTERFACE_H_INCLUDE_GUARD
279 
280 
281 #include "legato.h"
282 
283 
284 //--------------------------------------------------------------------------------------------------
285 /**
286  * Type for handler called when a server disconnects.
287  */
288 //--------------------------------------------------------------------------------------------------
289 typedef void (*le_cfg_DisconnectHandler_t)(void *);
290 
291 //--------------------------------------------------------------------------------------------------
292 /**
293  *
294  * Connect the current client thread to the service providing this API. Block until the service is
295  * available.
296  *
297  * For each thread that wants to use this API, either ConnectService or TryConnectService must be
298  * called before any other functions in this API. Normally, ConnectService is automatically called
299  * for the main thread, but not for any other thread. For details, see @ref apiFilesC_client.
300  *
301  * This function is created automatically.
302  */
303 //--------------------------------------------------------------------------------------------------
305 (
306  void
307 );
308 
309 //--------------------------------------------------------------------------------------------------
310 /**
311  *
312  * Try to connect the current client thread to the service providing this API. Return with an error
313  * if the service is not available.
314  *
315  * For each thread that wants to use this API, either ConnectService or TryConnectService must be
316  * called before any other functions in this API. Normally, ConnectService is automatically called
317  * for the main thread, but not for any other thread. For details, see @ref apiFilesC_client.
318  *
319  * This function is created automatically.
320  *
321  * @return
322  * - LE_OK if the client connected successfully to the service.
323  * - LE_UNAVAILABLE if the server is not currently offering the service to which the client is
324  * bound.
325  * - LE_NOT_PERMITTED if the client interface is not bound to any service (doesn't have a binding).
326  * - LE_COMM_ERROR if the Service Directory cannot be reached.
327  */
328 //--------------------------------------------------------------------------------------------------
330 (
331  void
332 );
333 
334 //--------------------------------------------------------------------------------------------------
335 /**
336  * Set handler called when server disconnection is detected.
337  *
338  * When a server connection is lost, call this handler then exit with LE_FATAL. If a program wants
339  * to continue without exiting, it should call longjmp() from inside the handler.
340  */
341 //--------------------------------------------------------------------------------------------------
343 (
344  le_cfg_DisconnectHandler_t disconnectHandler,
345  void *contextPtr
346 );
347 
348 //--------------------------------------------------------------------------------------------------
349 /**
350  *
351  * Disconnect the current client thread from the service providing this API.
352  *
353  * Normally, this function doesn't need to be called. After this function is called, there's no
354  * longer a connection to the service, and the functions in this API can't be used. For details, see
355  * @ref apiFilesC_client.
356  *
357  * This function is created automatically.
358  */
359 //--------------------------------------------------------------------------------------------------
361 (
362  void
363 );
364 
365 
366 //--------------------------------------------------------------------------------------------------
367 /**
368  * Length of the strings used by this API.
369  */
370 //--------------------------------------------------------------------------------------------------
371 #define LE_CFG_STR_LEN 511
372 
373 //--------------------------------------------------------------------------------------------------
374 /**
375  * Length of the strings used by this API, including the trailing NULL.
376  */
377 //--------------------------------------------------------------------------------------------------
378 #define LE_CFG_STR_LEN_BYTES 512
379 
380 //--------------------------------------------------------------------------------------------------
381 /**
382  * Allowed length of a node name.
383  */
384 //--------------------------------------------------------------------------------------------------
385 #define LE_CFG_NAME_LEN 127
386 
387 //--------------------------------------------------------------------------------------------------
388 /**
389  * The node name length, including a trailing NULL.
390  */
391 //--------------------------------------------------------------------------------------------------
392 #define LE_CFG_NAME_LEN_BYTES 128
393 
394 //--------------------------------------------------------------------------------------------------
395 /**
396  * Reference to a tree iterator object.
397  */
398 //--------------------------------------------------------------------------------------------------
399 typedef struct le_cfg_Iterator* le_cfg_IteratorRef_t;
400 
401 
402 //--------------------------------------------------------------------------------------------------
403 /**
404  * Identifies the type of node.
405  */
406 //--------------------------------------------------------------------------------------------------
407 typedef enum
408 {
410  ///< A node with no value.
412  ///< A string encoded as utf8.
414  ///< Boolean value.
416  ///< Signed 32-bit.
418  ///< 64-bit floating point value.
420  ///< Non-leaf node, this node is the parent of other nodes.
422  ///< Node doesn't exist.
423 }
425 
426 
427 //--------------------------------------------------------------------------------------------------
428 /**
429  * Reference type used by Add/Remove functions for EVENT 'le_cfg_Change'
430  */
431 //--------------------------------------------------------------------------------------------------
432 typedef struct le_cfg_ChangeHandler* le_cfg_ChangeHandlerRef_t;
433 
434 
435 //--------------------------------------------------------------------------------------------------
436 /**
437  * Handler for node change notifications.
438  */
439 //--------------------------------------------------------------------------------------------------
440 typedef void (*le_cfg_ChangeHandlerFunc_t)
441 (
442  void* contextPtr
443  ///<
444 );
445 
446 //--------------------------------------------------------------------------------------------------
447 /**
448  * Create a read transaction and open a new iterator for traversing the config tree.
449  *
450  * @note This action creates a read lock on the given tree, which will start a read-timeout.
451  * Once the read timeout expires, all active read iterators on that tree will be
452  * expired and the clients will be killed.
453  *
454  * @note A tree transaction is global to that tree; a long-held read transaction will block other
455  * user's write transactions from being comitted.
456  *
457  * @return This will return a newly created iterator reference.
458  */
459 //--------------------------------------------------------------------------------------------------
461 (
462  const char* basePath
463  ///< [IN] Path to the location to create the new iterator.
464 )
465 __attribute__(( nonnull(1) ));
466 
467 //--------------------------------------------------------------------------------------------------
468 /**
469  * Create a write transaction and open a new iterator for both reading and writing.
470  *
471  * @note This action creates a write transaction. If the app holds the iterator for
472  * longer than the configured write transaction timeout, the iterator will cancel the
473  * transaction. Other reads will fail to return data, and all writes will be thrown
474  * away.
475  *
476  * @note A tree transaction is global to that tree; a long-held write transaction will block
477  * other user's write transactions from being started. Other trees in the system
478  * won't be affected.
479  *
480  * @return This will return a newly created iterator reference.
481  */
482 //--------------------------------------------------------------------------------------------------
484 (
485  const char* basePath
486  ///< [IN] Path to the location to create the new iterator.
487 )
488 __attribute__(( nonnull(1) ));
489 
490 //--------------------------------------------------------------------------------------------------
491 /**
492  * Close the write iterator and commit the write transaction. This updates the config tree
493  * with all of the writes that occured using the iterator.
494  *
495  * @note This operation will also delete the iterator object.
496  */
497 //--------------------------------------------------------------------------------------------------
498 void le_cfg_CommitTxn
499 (
500  le_cfg_IteratorRef_t iteratorRef
501  ///< [IN] Iterator object to commit.
502 );
503 
504 //--------------------------------------------------------------------------------------------------
505 /**
506  * Close and free the given iterator object. If the iterator is a write iterator, the transaction
507  * will be canceled. If the iterator is a read iterator, the transaction will be closed.
508  *
509  * @note This operation will also delete the iterator object.
510  */
511 //--------------------------------------------------------------------------------------------------
512 void le_cfg_CancelTxn
513 (
514  le_cfg_IteratorRef_t iteratorRef
515  ///< [IN] Iterator object to close.
516 );
517 
518 //--------------------------------------------------------------------------------------------------
519 /**
520  * Change the node where the iterator is pointing. The path passed can be an absolute or a
521  * relative path from the iterators current location.
522  *
523  * The target node does not need to exist. Writing a value to a non-existant node will
524  * automatically create that node and any ancestor nodes (parent, parent's parent, etc.) that
525  * also don't exist.
526  */
527 //--------------------------------------------------------------------------------------------------
528 void le_cfg_GoToNode
529 (
530  le_cfg_IteratorRef_t iteratorRef,
531  ///< [IN] Iterator to move.
532  const char* newPath
533  ///< [IN] Absolute or relative path from the current location.
534 )
535 __attribute__(( nonnull(2) ));
536 
537 //--------------------------------------------------------------------------------------------------
538 /**
539  * Move the iterator to the parent of the node.
540  *
541  * @return Return code will be one of the following values:
542  *
543  * - LE_OK - Commit was completed successfully.
544  * - LE_NOT_FOUND - Current node is the root node: has no parent.
545  */
546 //--------------------------------------------------------------------------------------------------
548 (
549  le_cfg_IteratorRef_t iteratorRef
550  ///< [IN] Iterator to move.
551 );
552 
553 //--------------------------------------------------------------------------------------------------
554 /**
555  * Move the iterator to the the first child of the node where the iterator is currently pointed.
556  *
557  * For read iterators without children, this function will fail. If the iterator is a write
558  * iterator, then a new node is automatically created. If this node or newly created
559  * children of this node are not written to, then this node will not persist even if the iterator is
560  * comitted.
561  *
562  * @return Return code will be one of the following values:
563  *
564  * - LE_OK - Move was completed successfully.
565  * - LE_NOT_FOUND - The given node has no children.
566  */
567 //--------------------------------------------------------------------------------------------------
569 (
570  le_cfg_IteratorRef_t iteratorRef
571  ///< [IN] Iterator object to move.
572 );
573 
574 //--------------------------------------------------------------------------------------------------
575 /**
576  * Jump the iterator to the next child node of the current node. Assuming the following tree:
577  *
578  * @code
579  * baseNode/
580  * childA/
581  * valueA
582  * valueB
583  * @endcode
584  *
585  * If the iterator is moved to the path, "/baseNode/childA/valueA". After the first
586  * GoToNextSibling the iterator will be pointing at valueB. A second call to GoToNextSibling
587  * will cause the function to return LE_NOT_FOUND.
588  *
589  * @return Returns one of the following values:
590  *
591  * - LE_OK - Commit was completed successfully.
592  * - LE_NOT_FOUND - Iterator has reached the end of the current list of siblings.
593  * Also returned if the the current node has no siblings.
594  */
595 //--------------------------------------------------------------------------------------------------
597 (
598  le_cfg_IteratorRef_t iteratorRef
599  ///< [IN] Iterator to iterate.
600 );
601 
602 //--------------------------------------------------------------------------------------------------
603 /**
604  * Get path to the node where the iterator is currently pointed.
605  *
606  * Assuming the following tree:
607  *
608  * @code
609  * baseNode/
610  * childA/
611  * valueA
612  * valueB
613  * @endcode
614  *
615  * If the iterator was currently pointing at valueA, GetPath would return the following path:
616  *
617  * @code
618  * /baseNode/childA/valueA
619  * @endcode
620  *
621  * Optionally, a path to another node can be supplied to this function. So, if the iterator is
622  * again on valueA and the relative path ".." is supplied then this function will return the
623  * following path:
624  *
625  * @code
626  * /baseNode/childA/
627  * @endcode
628  *
629  * @return - LE_OK - The write was completed successfully.
630  * - LE_OVERFLOW - The supplied string buffer was not large enough to hold the value.
631  */
632 //--------------------------------------------------------------------------------------------------
634 (
635  le_cfg_IteratorRef_t iteratorRef,
636  ///< [IN] Iterator to move.
637  const char* path,
638  ///< [IN] Path to the target node. Can be an absolute path, or
639  ///< a path relative from the iterator's current position.
640  char* pathBuffer,
641  ///< [OUT] Absolute path to the iterator's current node.
642  size_t pathBufferSize
643  ///< [IN]
644 )
645 __attribute__(( nonnull(2) ));
646 
647 //--------------------------------------------------------------------------------------------------
648 /**
649  * Get the type of node where the iterator is currently pointing.
650  *
651  * @return le_cfg_nodeType_t value indicating the stored value.
652  */
653 //--------------------------------------------------------------------------------------------------
655 (
656  le_cfg_IteratorRef_t iteratorRef,
657  ///< [IN] Iterator object to use to read from the tree.
658  const char* path
659  ///< [IN] Path to the target node. Can be an absolute path, or
660  ///< a path relative from the iterator's current position.
661 )
662 __attribute__(( nonnull(2) ));
663 
664 //--------------------------------------------------------------------------------------------------
665 /**
666  * Get the name of the node where the iterator is currently pointing.
667  *
668  * @return - LE_OK Read was completed successfully.
669  * - LE_OVERFLOW Supplied string buffer was not large enough to hold the value.
670  */
671 //--------------------------------------------------------------------------------------------------
673 (
674  le_cfg_IteratorRef_t iteratorRef,
675  ///< [IN] Iterator object to use to read from the tree.
676  const char* path,
677  ///< [IN] Path to the target node. Can be an absolute path, or
678  ///< a path relative from the iterator's current position.
679  char* name,
680  ///< [OUT] Read the name of the node object.
681  size_t nameSize
682  ///< [IN]
683 )
684 __attribute__(( nonnull(2) ));
685 
686 //--------------------------------------------------------------------------------------------------
687 /**
688  * Add handler function for EVENT 'le_cfg_Change'
689  *
690  * This event provides information on changes to the given node object, or any of it's children,
691  * where a change could be either a read, write, create or delete operation.
692  */
693 //--------------------------------------------------------------------------------------------------
695 (
696  const char* newPath,
697  ///< [IN] Path to the object to watch.
698  le_cfg_ChangeHandlerFunc_t handlerPtr,
699  ///< [IN] Handler to receive change notification
700  void* contextPtr
701  ///< [IN]
702 )
703 __attribute__(( nonnull(1) ));
704 
705 //--------------------------------------------------------------------------------------------------
706 /**
707  * Remove handler function for EVENT 'le_cfg_Change'
708  */
709 //--------------------------------------------------------------------------------------------------
711 (
712  le_cfg_ChangeHandlerRef_t handlerRef
713  ///< [IN]
714 );
715 
716 //--------------------------------------------------------------------------------------------------
717 /**
718  * Delete the node specified by the path. If the node doesn't exist, nothing happens. All child
719  * nodes are also deleted.
720  *
721  * If the path is empty, the iterator's current node is deleted.
722  *
723  * Only valid during a write transaction.
724  */
725 //--------------------------------------------------------------------------------------------------
727 (
728  le_cfg_IteratorRef_t iteratorRef,
729  ///< [IN] Iterator to use as a basis for the transaction.
730  const char* path
731  ///< [IN] Path to the target node. Can be an absolute path, or
732  ///< a path relative from the iterator's current position.
733 )
734 __attribute__(( nonnull(2) ));
735 
736 //--------------------------------------------------------------------------------------------------
737 /**
738  * Check if the given node is empty. A node is also considered empty if it doesn't yet exist. A
739  * node is also considered empty if it has no value or is a stem with no children.
740  *
741  * If the path is empty, the iterator's current node is queried for emptiness.
742  *
743  * Valid for both read and write transactions.
744  *
745  * @return A true if the node is considered empty, false if not.
746  */
747 //--------------------------------------------------------------------------------------------------
748 bool le_cfg_IsEmpty
749 (
750  le_cfg_IteratorRef_t iteratorRef,
751  ///< [IN] Iterator to use as a basis for the transaction.
752  const char* path
753  ///< [IN] Path to the target node. Can be an absolute path, or
754  ///< a path relative from the iterator's current position.
755 )
756 __attribute__(( nonnull(2) ));
757 
758 //--------------------------------------------------------------------------------------------------
759 /**
760  * Clear out the nodes's value. If it doesn't exist it will be created, but have no value.
761  *
762  * If the path is empty, the iterator's current node will be cleared. If the node is a stem
763  * then all children will be removed from the tree.
764  *
765  * Only valid during a write transaction.
766  */
767 //--------------------------------------------------------------------------------------------------
768 void le_cfg_SetEmpty
769 (
770  le_cfg_IteratorRef_t iteratorRef,
771  ///< [IN] Iterator to use as a basis for the transaction.
772  const char* path
773  ///< [IN] Path to the target node. Can be an absolute path, or
774  ///< a path relative from the iterator's current position.
775 )
776 __attribute__(( nonnull(2) ));
777 
778 //--------------------------------------------------------------------------------------------------
779 /**
780  * Check to see if a given node in the config tree exists.
781  *
782  * @return True if the specified node exists in the tree. False if not.
783  */
784 //--------------------------------------------------------------------------------------------------
786 (
787  le_cfg_IteratorRef_t iteratorRef,
788  ///< [IN] Iterator to use as a basis for the transaction.
789  const char* path
790  ///< [IN] Path to the target node. Can be an absolute path, or
791  ///< a path relative from the iterator's current position.
792 )
793 __attribute__(( nonnull(2) ));
794 
795 //--------------------------------------------------------------------------------------------------
796 /**
797  * Read a string value from the config tree. If the value isn't a string, or if the node is
798  * empty or doesn't exist, the default value will be returned.
799  *
800  * Valid for both read and write transactions.
801  *
802  * If the path is empty, the iterator's current node will be read.
803  *
804  * @return - LE_OK - Read was completed successfully.
805  * - LE_OVERFLOW - Supplied string buffer was not large enough to hold the value.
806  */
807 //--------------------------------------------------------------------------------------------------
809 (
810  le_cfg_IteratorRef_t iteratorRef,
811  ///< [IN] Iterator to use as a basis for the transaction.
812  const char* path,
813  ///< [IN] Path to the target node. Can be an absolute path,
814  ///< or a path relative from the iterator's current
815  ///< position.
816  char* value,
817  ///< [OUT] Buffer to write the value into.
818  size_t valueSize,
819  ///< [IN]
820  const char* defaultValue
821  ///< [IN] Default value to use if the original can't be
822  ///< read.
823 )
824 __attribute__(( nonnull(2,5) ));
825 
826 //--------------------------------------------------------------------------------------------------
827 /**
828  * Write a string value to the config tree. Only valid during a write
829  * transaction.
830  *
831  * If the path is empty, the iterator's current node will be set.
832  */
833 //--------------------------------------------------------------------------------------------------
834 void le_cfg_SetString
835 (
836  le_cfg_IteratorRef_t iteratorRef,
837  ///< [IN] Iterator to use as a basis for the transaction.
838  const char* path,
839  ///< [IN] Path to the target node. Can be an absolute path, or
840  ///< a path relative from the iterator's current position.
841  const char* value
842  ///< [IN] Value to write.
843 )
844 __attribute__(( nonnull(2,3) ));
845 
846 //--------------------------------------------------------------------------------------------------
847 /**
848  * Read a signed integer value from the config tree.
849  *
850  * If the underlying value is not an integer, the default value will be returned instead. The
851  * default value is also returned if the node does not exist or if it's empty.
852  *
853  * If the value is a floating point value, then it will be rounded and returned as an integer.
854  *
855  * Valid for both read and write transactions.
856  *
857  * If the path is empty, the iterator's current node will be read.
858  */
859 //--------------------------------------------------------------------------------------------------
860 int32_t le_cfg_GetInt
861 (
862  le_cfg_IteratorRef_t iteratorRef,
863  ///< [IN] Iterator to use as a basis for the transaction.
864  const char* path,
865  ///< [IN] Path to the target node. Can be an absolute path, or
866  ///< a path relative from the iterator's current position.
867  int32_t defaultValue
868  ///< [IN] Default value to use if the original can't be
869  ///< read.
870 )
871 __attribute__(( nonnull(2) ));
872 
873 //--------------------------------------------------------------------------------------------------
874 /**
875  * Write a signed integer value to the config tree. Only valid during a
876  * write transaction.
877  *
878  * If the path is empty, the iterator's current node will be set.
879  */
880 //--------------------------------------------------------------------------------------------------
881 void le_cfg_SetInt
882 (
883  le_cfg_IteratorRef_t iteratorRef,
884  ///< [IN] Iterator to use as a basis for the transaction.
885  const char* path,
886  ///< [IN] Path to the target node. Can be an absolute path, or
887  ///< a path relative from the iterator's current position.
888  int32_t value
889  ///< [IN] Value to write.
890 )
891 __attribute__(( nonnull(2) ));
892 
893 //--------------------------------------------------------------------------------------------------
894 /**
895  * Read a 64-bit floating point value from the config tree.
896  *
897  * If the value is an integer then the value will be promoted to a float. Otherwise, if the
898  * underlying value is not a float or integer, the default value will be returned.
899  *
900  * If the path is empty, the iterator's current node will be read.
901  *
902  * @note Floating point values will only be stored up to 6 digits of precision.
903  */
904 //--------------------------------------------------------------------------------------------------
905 double le_cfg_GetFloat
906 (
907  le_cfg_IteratorRef_t iteratorRef,
908  ///< [IN] Iterator to use as a basis for the transaction.
909  const char* path,
910  ///< [IN] Path to the target node. Can be an absolute path, or
911  ///< a path relative from the iterator's current position.
912  double defaultValue
913  ///< [IN] Default value to use if the original can't be
914  ///< read.
915 )
916 __attribute__(( nonnull(2) ));
917 
918 //--------------------------------------------------------------------------------------------------
919 /**
920  * Write a 64-bit floating point value to the config tree. Only valid
921  * during a write transaction.
922  *
923  * If the path is empty, the iterator's current node will be set.
924  *
925  * @note Floating point values will only be stored up to 6 digits of precision.
926  */
927 //--------------------------------------------------------------------------------------------------
928 void le_cfg_SetFloat
929 (
930  le_cfg_IteratorRef_t iteratorRef,
931  ///< [IN] Iterator to use as a basis for the transaction.
932  const char* path,
933  ///< [IN] Path to the target node. Can be an absolute path, or
934  ///< a path relative from the iterator's current position.
935  double value
936  ///< [IN] Value to write.
937 )
938 __attribute__(( nonnull(2) ));
939 
940 //--------------------------------------------------------------------------------------------------
941 /**
942  * Read a value from the tree as a boolean. If the node is empty or doesn't exist, the default
943  * value is returned. Default value is also returned if the node is a different type than
944  * expected.
945  *
946  * Valid for both read and write transactions.
947  *
948  * If the path is empty, the iterator's current node will be read.
949  */
950 //--------------------------------------------------------------------------------------------------
951 bool le_cfg_GetBool
952 (
953  le_cfg_IteratorRef_t iteratorRef,
954  ///< [IN] Iterator to use as a basis for the transaction.
955  const char* path,
956  ///< [IN] Path to the target node. Can be an absolute path, or
957  ///< a path relative from the iterator's current position.
958  bool defaultValue
959  ///< [IN] Default value to use if the original can't be
960  ///< read.
961 )
962 __attribute__(( nonnull(2) ));
963 
964 //--------------------------------------------------------------------------------------------------
965 /**
966  * Write a boolean value to the config tree. Only valid during a write
967  * transaction.
968  *
969  * If the path is empty, the iterator's current node will be set.
970  */
971 //--------------------------------------------------------------------------------------------------
972 void le_cfg_SetBool
973 (
974  le_cfg_IteratorRef_t iteratorRef,
975  ///< [IN] Iterator to use as a basis for the transaction.
976  const char* path,
977  ///< [IN] Path to the target node. Can be an absolute path, or
978  ///< a path relative from the iterator's current position.
979  bool value
980  ///< [IN] Value to write.
981 )
982 __attribute__(( nonnull(2) ));
983 
984 //--------------------------------------------------------------------------------------------------
985 /**
986  * Delete the node specified by the path. If the node doesn't exist, nothing happens. All child
987  * nodes are also deleted.
988  */
989 //--------------------------------------------------------------------------------------------------
991 (
992  const char* path
993  ///< [IN] Path to the node to delete.
994 )
995 __attribute__(( nonnull(1) ));
996 
997 //--------------------------------------------------------------------------------------------------
998 /**
999  * Make a given node empty. If the node doesn't currently exist then it is created as a new empty
1000  * node.
1001  */
1002 //--------------------------------------------------------------------------------------------------
1004 (
1005  const char* path
1006  ///< [IN] Absolute or relative path to read from.
1007 )
1008 __attribute__(( nonnull(1) ));
1009 
1010 //--------------------------------------------------------------------------------------------------
1011 /**
1012  * Read a string value from the config tree. If the value isn't a string, or if the node is
1013  * empty or doesn't exist, the default value will be returned.
1014  *
1015  * @return - LE_OK - Commit was completed successfully.
1016  * - LE_OVERFLOW - Supplied string buffer was not large enough to hold the value.
1017  */
1018 //--------------------------------------------------------------------------------------------------
1020 (
1021  const char* path,
1022  ///< [IN] Path to read from.
1023  char* value,
1024  ///< [OUT] Value read from the requested node.
1025  size_t valueSize,
1026  ///< [IN]
1027  const char* defaultValue
1028  ///< [IN] Default value to use if the original can't be read.
1029 )
1030 __attribute__(( nonnull(1,4) ));
1031 
1032 //--------------------------------------------------------------------------------------------------
1033 /**
1034  * Write a string value to the config tree.
1035  */
1036 //--------------------------------------------------------------------------------------------------
1038 (
1039  const char* path,
1040  ///< [IN] Path to the value to write.
1041  const char* value
1042  ///< [IN] Value to write.
1043 )
1044 __attribute__(( nonnull(1,2) ));
1045 
1046 //--------------------------------------------------------------------------------------------------
1047 /**
1048  * Read a signed integer value from the config tree. If the value is a floating point
1049  * value, then it will be rounded and returned as an integer. Otherwise If the underlying value is
1050  * not an integer or a float, the default value will be returned instead.
1051  *
1052  * If the value is empty or the node doesn't exist, the default value is returned instead.
1053  */
1054 //--------------------------------------------------------------------------------------------------
1055 int32_t le_cfg_QuickGetInt
1056 (
1057  const char* path,
1058  ///< [IN] Path to the value to write.
1059  int32_t defaultValue
1060  ///< [IN] Default value to use if the original can't be read.
1061 )
1062 __attribute__(( nonnull(1) ));
1063 
1064 //--------------------------------------------------------------------------------------------------
1065 /**
1066  * Write a signed integer value to the config tree.
1067  */
1068 //--------------------------------------------------------------------------------------------------
1069 void le_cfg_QuickSetInt
1070 (
1071  const char* path,
1072  ///< [IN] Path to the value to write.
1073  int32_t value
1074  ///< [IN] Value to write.
1075 )
1076 __attribute__(( nonnull(1) ));
1077 
1078 //--------------------------------------------------------------------------------------------------
1079 /**
1080  * Read a 64-bit floating point value from the config tree. If the value is an integer,
1081  * then it is promoted to a float. Otherwise, if the underlying value is not a float, or an
1082  * integer the default value will be returned.
1083  *
1084  * If the value is empty or the node doesn't exist, the default value is returned.
1085  *
1086  * @note Floating point values will only be stored up to 6 digits of precision.
1087  */
1088 //--------------------------------------------------------------------------------------------------
1089 double le_cfg_QuickGetFloat
1090 (
1091  const char* path,
1092  ///< [IN] Path to the value to write.
1093  double defaultValue
1094  ///< [IN] Default value to use if the original can't be read.
1095 )
1096 __attribute__(( nonnull(1) ));
1097 
1098 //--------------------------------------------------------------------------------------------------
1099 /**
1100  * Write a 64-bit floating point value to the config tree.
1101  *
1102  * @note Floating point values will only be stored up to 6 digits of precision.
1103  */
1104 //--------------------------------------------------------------------------------------------------
1106 (
1107  const char* path,
1108  ///< [IN] Path to the value to write.
1109  double value
1110  ///< [IN] Value to write.
1111 )
1112 __attribute__(( nonnull(1) ));
1113 
1114 //--------------------------------------------------------------------------------------------------
1115 /**
1116  * Read a value from the tree as a boolean. If the node is empty or doesn't exist, the default
1117  * value is returned. This is also true if the node is a different type than expected.
1118  *
1119  * If the value is empty or the node doesn't exist, the default value is returned instead.
1120  */
1121 //--------------------------------------------------------------------------------------------------
1123 (
1124  const char* path,
1125  ///< [IN] Path to the value to write.
1126  bool defaultValue
1127  ///< [IN] Default value to use if the original can't be read.
1128 )
1129 __attribute__(( nonnull(1) ));
1130 
1131 //--------------------------------------------------------------------------------------------------
1132 /**
1133  * Write a boolean value to the config tree.
1134  */
1135 //--------------------------------------------------------------------------------------------------
1137 (
1138  const char* path,
1139  ///< [IN] Path to the value to write.
1140  bool value
1141  ///< [IN] Value to write.
1142 )
1143 __attribute__(( nonnull(1) ));
1144 
1145 #endif // LE_CFG_INTERFACE_H_INCLUDE_GUARD
void le_cfg_QuickSetInt(const char *path, int32_t value)
void le_cfg_QuickSetFloat(const char *path, double value)
void le_cfg_DisconnectService(void)
le_result_t
Definition: le_basics.h:35
void le_cfg_SetBool(le_cfg_IteratorRef_t iteratorRef, const char *path, bool value)
void le_cfg_SetString(le_cfg_IteratorRef_t iteratorRef, const char *path, const char *value)
bool le_cfg_QuickGetBool(const char *path, bool defaultValue)
64-bit floating point value.
Definition: le_cfg_interface.h:417
le_cfg_ChangeHandlerRef_t le_cfg_AddChangeHandler(const char *newPath, le_cfg_ChangeHandlerFunc_t handlerPtr, void *contextPtr)
struct le_cfg_ChangeHandler * le_cfg_ChangeHandlerRef_t
Definition: le_cfg_interface.h:432
le_result_t le_cfg_GoToNextSibling(le_cfg_IteratorRef_t iteratorRef)
void le_cfg_SetFloat(le_cfg_IteratorRef_t iteratorRef, const char *path, double value)
void(* le_cfg_DisconnectHandler_t)(void *)
Definition: le_cfg_interface.h:289
le_cfg_IteratorRef_t le_cfg_CreateReadTxn(const char *basePath)
le_result_t le_cfg_GetPath(le_cfg_IteratorRef_t iteratorRef, const char *path, char *pathBuffer, size_t pathBufferSize)
struct le_cfg_Iterator * le_cfg_IteratorRef_t
Definition: le_cfg_interface.h:399
int32_t le_cfg_GetInt(le_cfg_IteratorRef_t iteratorRef, const char *path, int32_t defaultValue)
A node with no value.
Definition: le_cfg_interface.h:409
double le_cfg_QuickGetFloat(const char *path, double defaultValue)
void le_cfg_ConnectService(void)
A string encoded as utf8.
Definition: le_cfg_interface.h:411
void le_cfg_GoToNode(le_cfg_IteratorRef_t iteratorRef, const char *newPath)
void le_cfg_QuickDeleteNode(const char *path)
Boolean value.
Definition: le_cfg_interface.h:413
void le_cfg_QuickSetString(const char *path, const char *value)
void le_cfg_CommitTxn(le_cfg_IteratorRef_t iteratorRef)
le_cfg_nodeType_t
Definition: le_cfg_interface.h:407
Node doesn&#39;t exist.
Definition: le_cfg_interface.h:421
double le_cfg_GetFloat(le_cfg_IteratorRef_t iteratorRef, const char *path, double defaultValue)
void le_cfg_DeleteNode(le_cfg_IteratorRef_t iteratorRef, const char *path)
void le_cfg_QuickSetEmpty(const char *path)
le_result_t le_cfg_TryConnectService(void)
le_result_t le_cfg_QuickGetString(const char *path, char *value, size_t valueSize, const char *defaultValue)
le_cfg_nodeType_t le_cfg_GetNodeType(le_cfg_IteratorRef_t iteratorRef, const char *path)
void(* le_cfg_ChangeHandlerFunc_t)(void *contextPtr)
Definition: le_cfg_interface.h:441
bool le_cfg_NodeExists(le_cfg_IteratorRef_t iteratorRef, const char *path)
le_cfg_IteratorRef_t le_cfg_CreateWriteTxn(const char *basePath)
void le_cfg_SetServerDisconnectHandler(le_cfg_DisconnectHandler_t disconnectHandler, void *contextPtr)
void le_cfg_SetInt(le_cfg_IteratorRef_t iteratorRef, const char *path, int32_t value)
void le_cfg_CancelTxn(le_cfg_IteratorRef_t iteratorRef)
bool le_cfg_IsEmpty(le_cfg_IteratorRef_t iteratorRef, const char *path)
int32_t le_cfg_QuickGetInt(const char *path, int32_t defaultValue)
Signed 32-bit.
Definition: le_cfg_interface.h:415
le_result_t le_cfg_GoToFirstChild(le_cfg_IteratorRef_t iteratorRef)
le_result_t le_cfg_GetNodeName(le_cfg_IteratorRef_t iteratorRef, const char *path, char *name, size_t nameSize)
void le_cfg_SetEmpty(le_cfg_IteratorRef_t iteratorRef, const char *path)
void le_cfg_QuickSetBool(const char *path, bool value)
bool le_cfg_GetBool(le_cfg_IteratorRef_t iteratorRef, const char *path, bool defaultValue)
le_result_t le_cfg_GetString(le_cfg_IteratorRef_t iteratorRef, const char *path, char *value, size_t valueSize, const char *defaultValue)
void le_cfg_RemoveChangeHandler(le_cfg_ChangeHandlerRef_t handlerRef)
le_result_t le_cfg_GoToParent(le_cfg_IteratorRef_t iteratorRef)
Non-leaf node, this node is the parent of other nodes.
Definition: le_cfg_interface.h:419