1*4882a593Smuzhiyun 2*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 3*4882a593Smuzhiyun /** 4*4882a593Smuzhiyun @file dictionary.h 5*4882a593Smuzhiyun @author N. Devillard 6*4882a593Smuzhiyun @brief Implements a dictionary for string variables. 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun This module implements a simple dictionary object, i.e. a list 9*4882a593Smuzhiyun of string/string associations. This object is useful to store e.g. 10*4882a593Smuzhiyun informations retrieved from a configuration file (ini files). 11*4882a593Smuzhiyun */ 12*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #ifndef _DICTIONARY_H_ 15*4882a593Smuzhiyun #define _DICTIONARY_H_ 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun /*--------------------------------------------------------------------------- 18*4882a593Smuzhiyun Includes 19*4882a593Smuzhiyun ---------------------------------------------------------------------------*/ 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #include <stdio.h> 22*4882a593Smuzhiyun #include <stdlib.h> 23*4882a593Smuzhiyun #include <string.h> 24*4882a593Smuzhiyun #include <unistd.h> 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #ifdef __cplusplus 27*4882a593Smuzhiyun extern "C" { 28*4882a593Smuzhiyun #endif 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun /*--------------------------------------------------------------------------- 31*4882a593Smuzhiyun New types 32*4882a593Smuzhiyun ---------------------------------------------------------------------------*/ 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 36*4882a593Smuzhiyun /** 37*4882a593Smuzhiyun @brief Dictionary object 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun This object contains a list of string/string associations. Each 40*4882a593Smuzhiyun association is identified by a unique string key. Looking up values 41*4882a593Smuzhiyun in the dictionary is speeded up by the use of a (hopefully collision-free) 42*4882a593Smuzhiyun hash function. 43*4882a593Smuzhiyun */ 44*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 45*4882a593Smuzhiyun typedef struct _dictionary_ { 46*4882a593Smuzhiyun int n ; /** Number of entries in dictionary */ 47*4882a593Smuzhiyun ssize_t size ; /** Storage size */ 48*4882a593Smuzhiyun char ** val ; /** List of string values */ 49*4882a593Smuzhiyun char ** key ; /** List of string keys */ 50*4882a593Smuzhiyun unsigned * hash ; /** List of hash values for keys */ 51*4882a593Smuzhiyun } dictionary ; 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /*--------------------------------------------------------------------------- 55*4882a593Smuzhiyun Function prototypes 56*4882a593Smuzhiyun ---------------------------------------------------------------------------*/ 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 59*4882a593Smuzhiyun /** 60*4882a593Smuzhiyun @brief Compute the hash key for a string. 61*4882a593Smuzhiyun @param key Character string to use for key. 62*4882a593Smuzhiyun @return 1 unsigned int on at least 32 bits. 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun This hash function has been taken from an Article in Dr Dobbs Journal. 65*4882a593Smuzhiyun This is normally a collision-free function, distributing keys evenly. 66*4882a593Smuzhiyun The key is stored anyway in the struct so that collision can be avoided 67*4882a593Smuzhiyun by comparing the key itself in last resort. 68*4882a593Smuzhiyun */ 69*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 70*4882a593Smuzhiyun unsigned dictionary_hash(const char * key); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 73*4882a593Smuzhiyun /** 74*4882a593Smuzhiyun @brief Create a new dictionary object. 75*4882a593Smuzhiyun @param size Optional initial size of the dictionary. 76*4882a593Smuzhiyun @return 1 newly allocated dictionary objet. 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun This function allocates a new dictionary object of given size and returns 79*4882a593Smuzhiyun it. If you do not know in advance (roughly) the number of entries in the 80*4882a593Smuzhiyun dictionary, give size=0. 81*4882a593Smuzhiyun */ 82*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 83*4882a593Smuzhiyun dictionary * dictionary_new(size_t size); 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 86*4882a593Smuzhiyun /** 87*4882a593Smuzhiyun @brief Delete a dictionary object 88*4882a593Smuzhiyun @param d dictionary object to deallocate. 89*4882a593Smuzhiyun @return void 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun Deallocate a dictionary object and all memory associated to it. 92*4882a593Smuzhiyun */ 93*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 94*4882a593Smuzhiyun void dictionary_del(dictionary * vd); 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 97*4882a593Smuzhiyun /** 98*4882a593Smuzhiyun @brief Get a value from a dictionary. 99*4882a593Smuzhiyun @param d dictionary object to search. 100*4882a593Smuzhiyun @param key Key to look for in the dictionary. 101*4882a593Smuzhiyun @param def Default value to return if key not found. 102*4882a593Smuzhiyun @return 1 pointer to internally allocated character string. 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun This function locates a key in a dictionary and returns a pointer to its 105*4882a593Smuzhiyun value, or the passed 'def' pointer if no such key can be found in 106*4882a593Smuzhiyun dictionary. The returned character pointer points to data internal to the 107*4882a593Smuzhiyun dictionary object, you should not try to free it or modify it. 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 110*4882a593Smuzhiyun const char * dictionary_get(const dictionary * d, const char * key, const char * def); 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 114*4882a593Smuzhiyun /** 115*4882a593Smuzhiyun @brief Set a value in a dictionary. 116*4882a593Smuzhiyun @param d dictionary object to modify. 117*4882a593Smuzhiyun @param key Key to modify or add. 118*4882a593Smuzhiyun @param val Value to add. 119*4882a593Smuzhiyun @return int 0 if Ok, anything else otherwise 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun If the given key is found in the dictionary, the associated value is 122*4882a593Smuzhiyun replaced by the provided one. If the key cannot be found in the 123*4882a593Smuzhiyun dictionary, it is added to it. 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun It is Ok to provide a NULL value for val, but NULL values for the dictionary 126*4882a593Smuzhiyun or the key are considered as errors: the function will return immediately 127*4882a593Smuzhiyun in such a case. 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun Notice that if you dictionary_set a variable to NULL, a call to 130*4882a593Smuzhiyun dictionary_get will return a NULL value: the variable will be found, and 131*4882a593Smuzhiyun its value (NULL) is returned. In other words, setting the variable 132*4882a593Smuzhiyun content to NULL is equivalent to deleting the variable from the 133*4882a593Smuzhiyun dictionary. It is not possible (in this implementation) to have a key in 134*4882a593Smuzhiyun the dictionary without value. 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun This function returns non-zero in case of failure. 137*4882a593Smuzhiyun */ 138*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 139*4882a593Smuzhiyun int dictionary_set(dictionary * vd, const char * key, const char * val); 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 142*4882a593Smuzhiyun /** 143*4882a593Smuzhiyun @brief Delete a key in a dictionary 144*4882a593Smuzhiyun @param d dictionary object to modify. 145*4882a593Smuzhiyun @param key Key to remove. 146*4882a593Smuzhiyun @return void 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun This function deletes a key in a dictionary. Nothing is done if the 149*4882a593Smuzhiyun key cannot be found. 150*4882a593Smuzhiyun */ 151*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 152*4882a593Smuzhiyun void dictionary_unset(dictionary * d, const char * key); 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/ 156*4882a593Smuzhiyun /** 157*4882a593Smuzhiyun @brief Dump a dictionary to an opened file pointer. 158*4882a593Smuzhiyun @param d Dictionary to dump 159*4882a593Smuzhiyun @param f Opened file pointer. 160*4882a593Smuzhiyun @return void 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun Dumps a dictionary onto an opened file pointer. Key pairs are printed out 163*4882a593Smuzhiyun as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as 164*4882a593Smuzhiyun output file pointers. 165*4882a593Smuzhiyun */ 166*4882a593Smuzhiyun /*--------------------------------------------------------------------------*/ 167*4882a593Smuzhiyun void dictionary_dump(const dictionary * d, FILE * out); 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun #ifdef __cplusplus 170*4882a593Smuzhiyun } 171*4882a593Smuzhiyun #endif 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun #endif 174