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