13d0407baSopenharmony_ci/* 23d0407baSopenharmony_ci * Copyright 2015 Rockchip Electronics Co. LTD 33d0407baSopenharmony_ci * 43d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 53d0407baSopenharmony_ci * you may not use this file except in compliance with the License. 63d0407baSopenharmony_ci * You may obtain a copy of the License at 73d0407baSopenharmony_ci * 83d0407baSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 93d0407baSopenharmony_ci * 103d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 113d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 123d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133d0407baSopenharmony_ci * See the License for the specific language governing permissions and 143d0407baSopenharmony_ci * limitations under the License. 153d0407baSopenharmony_ci */ 163d0407baSopenharmony_ci 173d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 183d0407baSopenharmony_ci/** 193d0407baSopenharmony_ci @file dictionary.h 203d0407baSopenharmony_ci @author N. Devillard 213d0407baSopenharmony_ci @brief Implements a dictionary for string variables. 223d0407baSopenharmony_ci 233d0407baSopenharmony_ci This module implements a simple dictionary object, i.e. a list 243d0407baSopenharmony_ci of string/string associations. This object is useful to store e.g. 253d0407baSopenharmony_ci informations retrieved from a configuration file (ini files). 263d0407baSopenharmony_ci*/ 273d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 283d0407baSopenharmony_ci 293d0407baSopenharmony_ci#ifndef _DICTIONARY_H_ 303d0407baSopenharmony_ci#define _DICTIONARY_H_ 313d0407baSopenharmony_ci 323d0407baSopenharmony_ci/*--------------------------------------------------------------------------- 333d0407baSopenharmony_ci Includes 343d0407baSopenharmony_ci ---------------------------------------------------------------------------*/ 353d0407baSopenharmony_ci 363d0407baSopenharmony_ci#include <stdio.h> 373d0407baSopenharmony_ci#include <stdlib.h> 383d0407baSopenharmony_ci#include <string.h> 393d0407baSopenharmony_ci#include <unistd.h> 403d0407baSopenharmony_ci 413d0407baSopenharmony_ci#ifdef __cplusplus 423d0407baSopenharmony_ciextern "C" { 433d0407baSopenharmony_ci#endif 443d0407baSopenharmony_ci 453d0407baSopenharmony_ci/*--------------------------------------------------------------------------- 463d0407baSopenharmony_ci New types 473d0407baSopenharmony_ci ---------------------------------------------------------------------------*/ 483d0407baSopenharmony_ci 493d0407baSopenharmony_ci 503d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 513d0407baSopenharmony_ci/** 523d0407baSopenharmony_ci @brief Dictionary object 533d0407baSopenharmony_ci 543d0407baSopenharmony_ci This object contains a list of string/string associations. Each 553d0407baSopenharmony_ci association is identified by a unique string key. Looking up values 563d0407baSopenharmony_ci in the dictionary is speeded up by the use of a (hopefully collision-free) 573d0407baSopenharmony_ci hash function. 583d0407baSopenharmony_ci */ 593d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 603d0407baSopenharmony_citypedef struct _dictionary_ { 613d0407baSopenharmony_ci int n ; /** Number of entries in dictionary */ 623d0407baSopenharmony_ci ssize_t size ; /** Storage size */ 633d0407baSopenharmony_ci char ** val ; /** List of string values */ 643d0407baSopenharmony_ci char ** key ; /** List of string keys */ 653d0407baSopenharmony_ci unsigned * hash ; /** List of hash values for keys */ 663d0407baSopenharmony_ci} dictionary ; 673d0407baSopenharmony_ci 683d0407baSopenharmony_ci 693d0407baSopenharmony_ci/*--------------------------------------------------------------------------- 703d0407baSopenharmony_ci Function prototypes 713d0407baSopenharmony_ci ---------------------------------------------------------------------------*/ 723d0407baSopenharmony_ci 733d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 743d0407baSopenharmony_ci/** 753d0407baSopenharmony_ci @brief Compute the hash key for a string. 763d0407baSopenharmony_ci @param key Character string to use for key. 773d0407baSopenharmony_ci @return 1 unsigned int on at least 32 bits. 783d0407baSopenharmony_ci 793d0407baSopenharmony_ci This hash function has been taken from an Article in Dr Dobbs Journal. 803d0407baSopenharmony_ci This is normally a collision-free function, distributing keys evenly. 813d0407baSopenharmony_ci The key is stored anyway in the struct so that collision can be avoided 823d0407baSopenharmony_ci by comparing the key itself in last resort. 833d0407baSopenharmony_ci */ 843d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 853d0407baSopenharmony_ciunsigned dictionary_hash(const char * key); 863d0407baSopenharmony_ci 873d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 883d0407baSopenharmony_ci/** 893d0407baSopenharmony_ci @brief Create a new dictionary object. 903d0407baSopenharmony_ci @param size Optional initial size of the dictionary. 913d0407baSopenharmony_ci @return 1 newly allocated dictionary objet. 923d0407baSopenharmony_ci 933d0407baSopenharmony_ci This function allocates a new dictionary object of given size and returns 943d0407baSopenharmony_ci it. If you do not know in advance (roughly) the number of entries in the 953d0407baSopenharmony_ci dictionary, give size=0. 963d0407baSopenharmony_ci */ 973d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 983d0407baSopenharmony_cidictionary * dictionary_new(size_t size); 993d0407baSopenharmony_ci 1003d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 1013d0407baSopenharmony_ci/** 1023d0407baSopenharmony_ci @brief Delete a dictionary object 1033d0407baSopenharmony_ci @param d dictionary object to deallocate. 1043d0407baSopenharmony_ci @return void 1053d0407baSopenharmony_ci 1063d0407baSopenharmony_ci Deallocate a dictionary object and all memory associated to it. 1073d0407baSopenharmony_ci */ 1083d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 1093d0407baSopenharmony_civoid dictionary_del(dictionary * vd); 1103d0407baSopenharmony_ci 1113d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 1123d0407baSopenharmony_ci/** 1133d0407baSopenharmony_ci @brief Get a value from a dictionary. 1143d0407baSopenharmony_ci @param d dictionary object to search. 1153d0407baSopenharmony_ci @param key Key to look for in the dictionary. 1163d0407baSopenharmony_ci @param def Default value to return if key not found. 1173d0407baSopenharmony_ci @return 1 pointer to internally allocated character string. 1183d0407baSopenharmony_ci 1193d0407baSopenharmony_ci This function locates a key in a dictionary and returns a pointer to its 1203d0407baSopenharmony_ci value, or the passed 'def' pointer if no such key can be found in 1213d0407baSopenharmony_ci dictionary. The returned character pointer points to data internal to the 1223d0407baSopenharmony_ci dictionary object, you should not try to free it or modify it. 1233d0407baSopenharmony_ci */ 1243d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 1253d0407baSopenharmony_ciconst char * dictionary_get(const dictionary * d, const char * key, const char * def); 1263d0407baSopenharmony_ci 1273d0407baSopenharmony_ci 1283d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 1293d0407baSopenharmony_ci/** 1303d0407baSopenharmony_ci @brief Set a value in a dictionary. 1313d0407baSopenharmony_ci @param d dictionary object to modify. 1323d0407baSopenharmony_ci @param key Key to modify or add. 1333d0407baSopenharmony_ci @param val Value to add. 1343d0407baSopenharmony_ci @return int 0 if Ok, anything else otherwise 1353d0407baSopenharmony_ci 1363d0407baSopenharmony_ci If the given key is found in the dictionary, the associated value is 1373d0407baSopenharmony_ci replaced by the provided one. If the key cannot be found in the 1383d0407baSopenharmony_ci dictionary, it is added to it. 1393d0407baSopenharmony_ci 1403d0407baSopenharmony_ci It is Ok to provide a NULL value for val, but NULL values for the dictionary 1413d0407baSopenharmony_ci or the key are considered as errors: the function will return immediately 1423d0407baSopenharmony_ci in such a case. 1433d0407baSopenharmony_ci 1443d0407baSopenharmony_ci Notice that if you dictionary_set a variable to NULL, a call to 1453d0407baSopenharmony_ci dictionary_get will return a NULL value: the variable will be found, and 1463d0407baSopenharmony_ci its value (NULL) is returned. In other words, setting the variable 1473d0407baSopenharmony_ci content to NULL is equivalent to deleting the variable from the 1483d0407baSopenharmony_ci dictionary. It is not possible (in this implementation) to have a key in 1493d0407baSopenharmony_ci the dictionary without value. 1503d0407baSopenharmony_ci 1513d0407baSopenharmony_ci This function returns non-zero in case of failure. 1523d0407baSopenharmony_ci */ 1533d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 1543d0407baSopenharmony_ciint dictionary_set(dictionary * vd, const char * key, const char * val); 1553d0407baSopenharmony_ci 1563d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 1573d0407baSopenharmony_ci/** 1583d0407baSopenharmony_ci @brief Delete a key in a dictionary 1593d0407baSopenharmony_ci @param d dictionary object to modify. 1603d0407baSopenharmony_ci @param key Key to remove. 1613d0407baSopenharmony_ci @return void 1623d0407baSopenharmony_ci 1633d0407baSopenharmony_ci This function deletes a key in a dictionary. Nothing is done if the 1643d0407baSopenharmony_ci key cannot be found. 1653d0407baSopenharmony_ci */ 1663d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 1673d0407baSopenharmony_civoid dictionary_unset(dictionary * d, const char * key); 1683d0407baSopenharmony_ci 1693d0407baSopenharmony_ci 1703d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 1713d0407baSopenharmony_ci/** 1723d0407baSopenharmony_ci @brief Dump a dictionary to an opened file pointer. 1733d0407baSopenharmony_ci @param d Dictionary to dump 1743d0407baSopenharmony_ci @param f Opened file pointer. 1753d0407baSopenharmony_ci @return void 1763d0407baSopenharmony_ci 1773d0407baSopenharmony_ci Dumps a dictionary onto an opened file pointer. Key pairs are printed out 1783d0407baSopenharmony_ci as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as 1793d0407baSopenharmony_ci output file pointers. 1803d0407baSopenharmony_ci */ 1813d0407baSopenharmony_ci/*--------------------------------------------------------------------------*/ 1823d0407baSopenharmony_civoid dictionary_dump(const dictionary * d, FILE * out); 1833d0407baSopenharmony_ci 1843d0407baSopenharmony_ci#ifdef __cplusplus 1853d0407baSopenharmony_ci} 1863d0407baSopenharmony_ci#endif 1873d0407baSopenharmony_ci 1883d0407baSopenharmony_ci#endif 189