00001 #ifndef LIBNAGIOS_KVVEC_H_INCLUDED 00002 #define LIBNAGIOS_KVVEC_H_INCLUDED 00003 00004 /** 00005 * @file kvvec.h 00006 * @brief Key/value vector library function and type declarations 00007 * 00008 * The kvvec library is nifty as either a configuration meta-format 00009 * or for IPC purposes. Take a look at the buf2kvvec() and kvvec2buf() 00010 * pair of functions for the latter. 00011 * @{ 00012 */ 00013 00014 /** 00015 * key/value pair 00016 * One of the two major components of the kvvec api 00017 */ 00018 struct key_value { 00019 char *key; /**< The key */ 00020 char *value; /**< The value */ 00021 int key_len; /**< Length of key */ 00022 int value_len; /**< Length of value */ 00023 }; 00024 00025 /** 00026 * key/value vector buffer. Actually just a buffer, but one that gets 00027 * used as return value and internal tracker for kvvec2buf() 00028 */ 00029 struct kvvec_buf { 00030 char *buf; /**< The buffer */ 00031 unsigned long buflen; /**< Length of buffer */ 00032 unsigned long bufsize; /**< Size of buffer (includes overalloc) */ 00033 }; 00034 00035 /** 00036 * key/value vector struct 00037 * This is the main component of the kvvec library 00038 * @note This should be made opaque, with a kvvec_foreach() using a 00039 * callback to iterate over key/value pairs. 00040 */ 00041 struct kvvec { 00042 struct key_value *kv; /**< The key/value array */ 00043 int kv_alloc; /**< Allocated size of key/value array */ 00044 int kv_pairs; /**< Number of key/value pairs */ 00045 int kvv_sorted; /**< Determines if this kvvec has been sorted */ 00046 }; 00047 00048 /** Portable initializer for stack-allocated key/value vectors */ 00049 #define KVVEC_INITIALIZER { NULL, 0, 0, 0 } 00050 00051 /** Parameters for kvvec_destroy() */ 00052 #define KVVEC_FREE_KEYS 1 /**< Free keys when destroying a kv vector */ 00053 #define KVVEC_FREE_VALUES 2 /**< Free values when destroying a kv vector */ 00054 /** Free both keys and values when destroying a kv vector */ 00055 #define KVVEC_FREE_ALL (KVVEC_FREE_KEYS | KVVEC_FREE_VALUES) 00056 00057 #define KVVEC_ASSIGN 0 /**< Assign from buf in buf2kvvec_prealloc() */ 00058 #define KVVEC_COPY 1 /**< Copy from buf in buf2kvvec_prealloc() */ 00059 #define KVVEC_APPEND 2 /**< Don't reset kvvec in buf2kvvec_prealloc() */ 00060 00061 /** 00062 * Initialize a previously allocated key/value vector 00063 * 00064 * @param kvv The key/value vector to initialize 00065 * @param hint Number of key/value pairs we expect to store 00066 * @return Pointer to a struct kvvec, properly initialized 00067 */ 00068 extern struct kvvec *kvvec_init(struct kvvec *kvv, int hint); 00069 00070 /** 00071 * Create a key/value vector 00072 * 00073 * @param hint Number of key/value pairs we expect to store 00074 * @return Pointer to a struct kvvec, properly initialized 00075 */ 00076 extern struct kvvec *kvvec_create(int hint); 00077 00078 /** 00079 * Resize a key/value vector 00080 * Used by kvvec_grow(). If size is smaller than the current number of 00081 * used key/value slots, -1 is returned. 00082 * 00083 * @param[in] kvv The key/value vector to resize 00084 * @param[in] size The size to grow to 00085 * @return 0 on success, < 0 on errors 00086 */ 00087 extern int kvvec_resize(struct kvvec *kvv, int size); 00088 00089 /** 00090 * Grow a key/value vector. 00091 * Used internally as needed by the kvvec api. If 'hint' is zero, the 00092 * key/value capacity is increased by a third of the current capacity 00093 * plus a small constant number. This uses kvvec_resize() internally. 00094 * 00095 * @param kvv The key/value vector to grow 00096 * @param hint The amount of key/value slots we should grow by 00097 * @return 0 on success, < 0 on errors 00098 */ 00099 extern int kvvec_grow(struct kvvec *kvv, int hint); 00100 00101 /** 00102 * Return remaining storage capacity of key/value vector 00103 * @param[in] kvv The key/value vector to check 00104 * @return Number of key/value pairs that can be stored without growing 00105 */ 00106 extern unsigned int kvvec_capacity(struct kvvec *kvv); 00107 00108 /** 00109 * Sort a key/value vector alphabetically by key name 00110 * @param kvv The key/value vector to sort 00111 * @return 0 00112 */ 00113 extern int kvvec_sort(struct kvvec *kvv); 00114 00115 /** 00116 * Add a key/value pair to an existing key/value vector, with 00117 * lengths of strings already calculated 00118 * @param kvv The key/value vector to add this key/value pair to 00119 * @param key The key 00120 * @param keylen Length of the key 00121 * @param value The value 00122 * @param valuelen Length of the value 00123 * @return 0 on success, < 0 on errors 00124 */ 00125 extern int kvvec_addkv_wlen(struct kvvec *kvv, const char *key, int keylen, const char *value, int valuelen); 00126 00127 /** 00128 * Shortcut to kvvec_addkv_wlen() when lengths aren't known 00129 * @param kvv The key/value vector to add this key/value pair to 00130 * @param key The key 00131 * @param value The value 00132 * @return 0 on success, < 0 on errors 00133 */ 00134 #define kvvec_addkv(kvv, key, value) kvvec_addkv_wlen(kvv, key, 0, value, 0) 00135 00136 /** 00137 * Walk each key/value pair in a key/value vector, sending them 00138 * as arguments to a callback function. The callback function has 00139 * no control over the iteration process and must not delete or 00140 * modify the key/value vector it's operating on. 00141 * @param kvv The key/value vector to walk 00142 * @param arg Extra argument to the callback function 00143 * @param callback Callback function 00144 * @return 0 on success, < 0 on errors 00145 */ 00146 extern int kvvec_foreach(struct kvvec *kvv, void *arg, int (*callback)(struct key_value *, void *)); 00147 00148 /** 00149 * Destroy a key/value vector 00150 * @param kvv The key/value vector to destroy 00151 * @param flags or'ed combination of KVVEC_FREE_{KEYS,VALUES}, or KVVEC_FREE_ALL 00152 * @return 0 on success, < 0 on errors 00153 */ 00154 extern int kvvec_destroy(struct kvvec *kvv, int flags); 00155 00156 /** 00157 * Free key/value pairs associated with a key/value vector 00158 * @param kvv The key/value vector to operate on 00159 * @param flags flags or'ed combination of KVVEC_FREE_{KEYS,VALUES}, or KVVEC_FREE_ALL 00160 */ 00161 void kvvec_free_kvpairs(struct kvvec *kvv, int flags); 00162 00163 /** 00164 * Create a linear buffer of all the key/value pairs and 00165 * return it as a kvvec_buf. The caller must free() all 00166 * pointers in the returned kvvec_buf 00167 * (FIXME: add kvvec_buf_destroy(), or move this and its counterpart 00168 * out of the kvvec api into a separate one) 00169 * 00170 * @param kvv The key/value vector to convert 00171 * @param kv_sep Character separating keys and their values 00172 * @param pair_sep Character separating key/value pairs 00173 * @param overalloc Integer determining how much extra data we should 00174 * allocate. The overallocated memory is filled with 00175 * nul bytes. 00176 * @return A pointer to a newly created kvvec_buf structure 00177 */ 00178 extern struct kvvec_buf *kvvec2buf(struct kvvec *kvv, char kv_sep, char pair_sep, int overalloc); 00179 00180 /** 00181 * Create a key/value vector from a pre-parsed buffer. Immensely 00182 * useful for ipc in combination with kvvec2buf(). 00183 * 00184 * @param str The buffer to convert to a key/value vector 00185 * @param len Length of buffer to convert 00186 * @param kvsep Character separating key and value 00187 * @param pair_sep Character separating key/value pairs 00188 * @param flags bitmask. See KVVEC_{ASSIGN,COPY,APPEND} for values 00189 * @return The created key/value vector 00190 */ 00191 extern struct kvvec *buf2kvvec(char *str, unsigned int len, const char kvsep, const char pair_sep, int flags); 00192 00193 /** 00194 * Parse a buffer into the pre-allocated key/value vector. Immensely 00195 * useful for ipc in combination with kvvec2buf(). 00196 * 00197 * @param kvv A pre-allocated key/value vector to populate 00198 * @param str The buffer to convert to a key/value vector 00199 * @param len Length of buffer to convert 00200 * @param kvsep Character separating key and value 00201 * @param pair_sep Character separating key/value pairs 00202 * @param flags bitmask. See KVVEC_{ASSIGN,COPY,APPEND} for values 00203 * @return The number of pairs in the created key/value vector 00204 */ 00205 extern int buf2kvvec_prealloc(struct kvvec *kvv, char *str, unsigned int len, const char kvsep, const char pair_sep, int flags); 00206 /** @} */ 00207 #endif /* INCLUDE_kvvec_h__ */