1 /***********************************************************************************************************************************
2 Key Value Handler
3 ***********************************************************************************************************************************/
4 #ifndef COMMON_TYPE_KEYVALUE_H
5 #define COMMON_TYPE_KEYVALUE_H
6 
7 /***********************************************************************************************************************************
8 KeyValue object
9 ***********************************************************************************************************************************/
10 typedef struct KeyValue KeyValue;
11 
12 #include "common/type/object.h"
13 #include "common/type/variantList.h"
14 
15 /***********************************************************************************************************************************
16 Constant to indicate key not found
17 ***********************************************************************************************************************************/
18 #define KEY_NOT_FOUND                                               UINT_MAX
19 
20 /***********************************************************************************************************************************
21 Constructors
22 ***********************************************************************************************************************************/
23 KeyValue *kvNew(void);
24 KeyValue *kvDup(const KeyValue *source);
25 
26 /***********************************************************************************************************************************
27 Getters/Setters
28 ***********************************************************************************************************************************/
29 typedef struct KeyValuePub
30 {
31     MemContext *memContext;                                         // Mem context
32     VariantList *keyList;                                           // List of keys
33 } KeyValuePub;
34 
35 // List of keys
36 __attribute__((always_inline)) static inline const VariantList *
kvKeyList(const KeyValue * const this)37 kvKeyList(const KeyValue *const this)
38 {
39     return THIS_PUB(KeyValue)->keyList;
40 }
41 
42 /***********************************************************************************************************************************
43 Functions
44 ***********************************************************************************************************************************/
45 // Add a value to an existing key. If the key does not exist then this works the same as kvPut(). If the key does exist then the
46 // value is converted to a VariantList with the existing value and the new value as list items. Subsequent calls expand the list.
47 //
48 // NOTE: this function is seldom required and kvPut() should be used when a key is expected to have a single value.
49 KeyValue *kvAdd(KeyValue *this, const Variant *key, const Variant *value);
50 
51 // Move to a new parent mem context
52 __attribute__((always_inline)) static inline KeyValue *
kvMove(KeyValue * const this,MemContext * const parentNew)53 kvMove(KeyValue *const this, MemContext *const parentNew)
54 {
55     return objMove(this, parentNew);
56 }
57 
58 // Put key/value pair
59 KeyValue *kvPut(KeyValue *this, const Variant *key, const Variant *value);
60 
61 // Put key/value store. If this is called on an existing key it will replace the key with an empty kev/value store, even if the key
62 // already contains a key/value store.
63 KeyValue *kvPutKv(KeyValue *this, const Variant *key);
64 
65 // Get a value using the key
66 const Variant *kvGet(const KeyValue *this, const Variant *key);
67 
68 // Get a value using the key and return a default if not found
69 const Variant *kvGetDefault(const KeyValue *this, const Variant *key, const Variant *defaultValue);
70 
71 // Get key index if it exists
72 unsigned int kvGetIdx(const KeyValue *this, const Variant *key);
73 
74 // Does the key exist (even if the value is NULL)
75 __attribute__((always_inline)) static inline bool
kvKeyExists(const KeyValue * const this,const Variant * const key)76 kvKeyExists(const KeyValue *const this, const Variant *const key)
77 {
78     return kvGetIdx(this, key) != KEY_NOT_FOUND;
79 }
80 
81 // Get a value as a list (even if there is only one value) using the key
82 VariantList *kvGetList(const KeyValue *this, const Variant *key);
83 
84 /***********************************************************************************************************************************
85 Destructor
86 ***********************************************************************************************************************************/
87 __attribute__((always_inline)) static inline void
kvFree(KeyValue * const this)88 kvFree(KeyValue *const this)
89 {
90     objFree(this);
91 }
92 
93 /***********************************************************************************************************************************
94 Macros for function logging
95 ***********************************************************************************************************************************/
96 #define FUNCTION_LOG_KEY_VALUE_TYPE                                                                                                \
97     KeyValue *
98 #define FUNCTION_LOG_KEY_VALUE_FORMAT(value, buffer, bufferSize)                                                                   \
99     objToLog(value, "KeyValue", buffer, bufferSize)
100 
101 #endif
102