michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @file dictionary.h michael@0: @author N. Devillard michael@0: @date Sep 2007 michael@0: @version $Revision: 1.12 $ michael@0: @brief Implements a dictionary for string variables. michael@0: michael@0: This module implements a simple dictionary object, i.e. a list michael@0: of string/string associations. This object is useful to store e.g. michael@0: informations retrieved from a configuration file (ini files). michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: michael@0: /* michael@0: $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $ michael@0: $Author: ndevilla $ michael@0: $Date: 2007-11-23 21:37:00 $ michael@0: $Revision: 1.12 $ michael@0: */ michael@0: michael@0: #ifndef _DICTIONARY_H_ michael@0: #define _DICTIONARY_H_ michael@0: michael@0: /*--------------------------------------------------------------------------- michael@0: Includes michael@0: ---------------------------------------------------------------------------*/ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #ifndef _WIN32 michael@0: #include michael@0: #endif michael@0: michael@0: /*--------------------------------------------------------------------------- michael@0: New types michael@0: ---------------------------------------------------------------------------*/ michael@0: michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Dictionary object michael@0: michael@0: This object contains a list of string/string associations. Each michael@0: association is identified by a unique string key. Looking up values michael@0: in the dictionary is speeded up by the use of a (hopefully collision-free) michael@0: hash function. michael@0: */ michael@0: /*-------------------------------------------------------------------------*/ michael@0: typedef struct _dictionary_ { michael@0: int n ; /** Number of entries in dictionary */ michael@0: int size ; /** Storage size */ michael@0: char ** val ; /** List of string values */ michael@0: char ** key ; /** List of string keys */ michael@0: unsigned * hash ; /** List of hash values for keys */ michael@0: } dictionary ; michael@0: michael@0: michael@0: /*--------------------------------------------------------------------------- michael@0: Function prototypes michael@0: ---------------------------------------------------------------------------*/ michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Compute the hash key for a string. michael@0: @param key Character string to use for key. michael@0: @return 1 unsigned int on at least 32 bits. michael@0: michael@0: This hash function has been taken from an Article in Dr Dobbs Journal. michael@0: This is normally a collision-free function, distributing keys evenly. michael@0: The key is stored anyway in the struct so that collision can be avoided michael@0: by comparing the key itself in last resort. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: unsigned dictionary_hash(char * key); michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Create a new dictionary object. michael@0: @param size Optional initial size of the dictionary. michael@0: @return 1 newly allocated dictionary objet. michael@0: michael@0: This function allocates a new dictionary object of given size and returns michael@0: it. If you do not know in advance (roughly) the number of entries in the michael@0: dictionary, give size=0. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: dictionary * dictionary_new(int size); michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Delete a dictionary object michael@0: @param d dictionary object to deallocate. michael@0: @return void michael@0: michael@0: Deallocate a dictionary object and all memory associated to it. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: void dictionary_del(dictionary * vd); michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Get a value from a dictionary. michael@0: @param d dictionary object to search. michael@0: @param key Key to look for in the dictionary. michael@0: @param def Default value to return if key not found. michael@0: @return 1 pointer to internally allocated character string. michael@0: michael@0: This function locates a key in a dictionary and returns a pointer to its michael@0: value, or the passed 'def' pointer if no such key can be found in michael@0: dictionary. The returned character pointer points to data internal to the michael@0: dictionary object, you should not try to free it or modify it. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: char * dictionary_get(dictionary * d, char * key, char * def); michael@0: michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Set a value in a dictionary. michael@0: @param d dictionary object to modify. michael@0: @param key Key to modify or add. michael@0: @param val Value to add. michael@0: @return int 0 if Ok, anything else otherwise michael@0: michael@0: If the given key is found in the dictionary, the associated value is michael@0: replaced by the provided one. If the key cannot be found in the michael@0: dictionary, it is added to it. michael@0: michael@0: It is Ok to provide a NULL value for val, but NULL values for the dictionary michael@0: or the key are considered as errors: the function will return immediately michael@0: in such a case. michael@0: michael@0: Notice that if you dictionary_set a variable to NULL, a call to michael@0: dictionary_get will return a NULL value: the variable will be found, and michael@0: its value (NULL) is returned. In other words, setting the variable michael@0: content to NULL is equivalent to deleting the variable from the michael@0: dictionary. It is not possible (in this implementation) to have a key in michael@0: the dictionary without value. michael@0: michael@0: This function returns non-zero in case of failure. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: int dictionary_set(dictionary * vd, char * key, char * val); michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Delete a key in a dictionary michael@0: @param d dictionary object to modify. michael@0: @param key Key to remove. michael@0: @return void michael@0: michael@0: This function deletes a key in a dictionary. Nothing is done if the michael@0: key cannot be found. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: void dictionary_unset(dictionary * d, char * key); michael@0: michael@0: michael@0: /*-------------------------------------------------------------------------*/ michael@0: /** michael@0: @brief Dump a dictionary to an opened file pointer. michael@0: @param d Dictionary to dump michael@0: @param f Opened file pointer. michael@0: @return void michael@0: michael@0: Dumps a dictionary onto an opened file pointer. Key pairs are printed out michael@0: as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as michael@0: output file pointers. michael@0: */ michael@0: /*--------------------------------------------------------------------------*/ michael@0: void dictionary_dump(dictionary * d, FILE * out); michael@0: michael@0: #endif