text: /**
    Onion HTTP server library
    Copyright (C) 2010-2018 David Moreno Montero and others
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of, at your choice:
  
    a. the Apache License Version 2.0.
  
    b. the GNU General Public License as published by the
    Free Software Foundation; either version 2.0 of the License,
    or (at your option) any later version.
  
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
  
    You should have received a copy of both licenses, if not see
    <http://www.gnu.org/licenses/> and
    <http://www.apache.org/licenses/LICENSE-2.0>.
  */
  
  #ifndef ONION_DICT_H
  #define ONION_DICT_H
  
  #include "types.h"
  #include <stddef.h>
  #include <strings.h>
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /**
   * @short Flags to change some parameters of each key.
   * @ingroup dict
   */
    enum onion_dict_flags_e {
  //      OD_EMPTY=1,
      OD_FREE_KEY = 2,            ///< Whether the key has to be removed at free time
      OD_FREE_VALUE = 4,          ///< Whether the value has to be removed at free time
      OD_FREE_ALL = 6,            ///< Whether both, the key and value have to be removed at free time. In any case its also marked for freeing later.
      OD_DUP_KEY = 0x12,          ///< Whether the key has to be dupped
      OD_DUP_VALUE = 0x24,        ///< Whether the value has to be dupped
      OD_DUP_ALL = 0x36,          ///< Whether both, the key and value have to be dupped. In any case its also marked for freeing later.
      OD_REPLACE = 0x040,         ///< If already exists, replaces content.
  
      // Types
      OD_STRING = 0,              ///< Stored data is a string, this is the most normal situation
      OD_DICT = 0x0100,           ///< Stored data is another dictionary
  
      OD_TYPE_MASK = 0x0FF00,     ///< Mask for the types
  
      // Flags for onion_dict_set_flags
      OD_ICASE = 0x01,            ///< Do case insensitive cmps.
    };
  
  /// Initializes a dict.
    onion_dict *onion_dict_new();
  
    void onion_dict_set_flags(onion_dict * dict, int flags);
  
  /// Adds a value. Flags are or from onion_dict_flags_e, for example OD_DUP_ALL. @see onion_dict_flags_e
    void onion_dict_add(onion_dict * dict, const char *key, const void *value,
                        int flags);
  
  /// Removes a value
    int onion_dict_remove(onion_dict * dict, const char *key);
  
  /// Removes the full dict struct form mem.
    void onion_dict_free(onion_dict * dict);
  
  /// Merges argument dictionary into current
    void onion_dict_merge(onion_dict * me, const onion_dict * other);
  
  /// Creates a soft duplicate of the dict.
    onion_dict *onion_dict_dup(onion_dict * dict);
  
  /// Creates a hard duplicate of the dict.
    onion_dict *onion_dict_hard_dup(onion_dict * dict);
  
  /// Gets a value
    const char *onion_dict_get(const onion_dict * dict, const char *key);
  
  /// Gets a value, recursively over the nested dicts, until NULL.
    const char *onion_dict_rget(const onion_dict * dict, const char *key, ...);
  
  /// Gets a dict. It ensures its a dict.
    onion_dict *onion_dict_get_dict(const onion_dict * dict, const char *key);
  
  /// Gets a dict. It ensures its a dict. Recursively until NULL.
    onion_dict *onion_dict_rget_dict(const onion_dict * dict, const char *key,
                                     ...);
  
  /// Prints a dot ready graph to stderr
    void onion_dict_print_dot(const onion_dict * dict);
  
  /// Visits the full graph in preorder, calling that function on each node. void func(void *data, const char *key, const void *value, int flags).
    void onion_dict_preorder(const onion_dict * dict, void *func, void *data);
  
  /// Counts elements
    int onion_dict_count(const onion_dict * dict);
  
  /// @{ @name lock management
  /// Locks for reading. Several can read, one can write.
    void onion_dict_lock_read(const onion_dict * dict);
  /// Locks for writing
    void onion_dict_lock_write(onion_dict * dict);
  /// Unlocks last lock
    void onion_dict_unlock(onion_dict * dict);
  /// @}
  
  /// Converts a dict into a JSON onion_block
    onion_block *onion_dict_to_json(onion_dict * dict);
  /// Converts a C string into a dictionary
    onion_dict *onion_dict_from_json(const char *data);
  
  #ifdef __cplusplus
  }
  #endif
  #endif
  