/***************************************************************************
$RCSfile: db.h,v $
-------------------
cvs : $Id: db.h,v 1.41 2005/03/09 11:34:30 aquamaniac Exp $
begin : Tue Sep 09 2003
copyright : (C) 2003 by Martin Preuss
email : martin@libchipcard.de
***************************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA *
* *
***************************************************************************/
/** @file db.h */
#ifndef GWENHYWFAR_DB_H
#define GWENHYWFAR_DB_H
#include
#include
#include
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup MOD_DB Database
* @ingroup MOD_PARSER
*
* @brief This group contains the definition of a GWEN_DB database.
*
* A GWEN_DB database consists of a tree of @ref GWEN_DB_NODE entries.
* Such a @ref GWEN_DB_NODE node can either be a group node, or a
* variable node, or a value node. Usually an application programmer
* will only get in touch with group nodes. The application programmer
* can iterate through the group nodes with GWEN_DB_GetGroup(),
* GWEN_DB_Groups_foreach(), and can retrieve variable values with
* GWEN_DB_GetIntValue(), GWEN_DB_GetCharValue() and so on.
*
*
* The following graph shows the internal structure of a GWEN_DB:
* @image html db2.png "Internal structure of a GWEN_DB"
*
* As you can see the GWEN_DB consists of multiple units called NODE. Every
* node has a pointer to:
*
* - its parent
* - its first child (only the first)
* - its successor (but not its predecessor!)
*
* Such a node can be either of the following:
*
* - a group containing other groups and variables
* - a variable containing values (and values only)
* - a value containing its value data
*
*
*
* Each group has a name. Depending on the GWEN_DB_FLAGS given when
* reading a GWEN_DB from a file or creating it, it may very well be
* possible to have multiple groups with the same name as children of
* the same root node. Again: Child group nodes with the same name may
* very well exist. This also applies to variable nodes.
*
* For the interested reader, we again explain the difference of the
* three kinds of nodes. Depending on either of these cases, you can
*
*
* - Iterate through groups or get a variable with
* e.g. GWEN_DB_GetNextGroup(), GWEN_DB_GetNextVar()
*
- Get the type of a variable with e.g. GWEN_DB_GetVariableType()
* -- the value of a variable is retrieved by the shortcut functions
* explained below.
*
- Get the type of a value with GWEN_DB_GetValueType(). Again the
* value itself is retrieved with the shortcut functions below.
*
*
* To retrieve or set the value of such a variable, the following
* "shortcut" functions for all three supported typed exist:
* GWEN_DB_GetIntValue(), GWEN_DB_GetCharValue(),
* GWEN_DB_GetBinValue(). These functions only accept a group and a "path"
* to the desired variable.
*
*/
/*@{*/
/** maximum size of a text line when reading/writing from/to streams */
#define GWEN_DB_LINE_MAXSIZE 1024
/** @name DB Flags
*
*
* Please note that the setter functions also take the flags from
* the module @ref MOD_PATH (e.g. @ref GWEN_PATH_FLAGS_PATHMUSTEXIST)
* into account. So you most likely need to specify
* them, too.
*
*
* However, for your conveniance there is a default flag value which suffices
* in most cases (@ref GWEN_DB_FLAGS_DEFAULT).
*
*/
/*@{*/
/** Overwrite existing values when assigning a new value to a variable */
#define GWEN_DB_FLAGS_OVERWRITE_VARS 0x00010000
/** Overwrite existing groups when calling @ref GWEN_DB_GetGroup() */
#define GWEN_DB_FLAGS_OVERWRITE_GROUPS 0x00020000
/** quote variable names when writing them to a stream */
#define GWEN_DB_FLAGS_QUOTE_VARNAMES 0x00040000
/** quote values when writing them to a stream */
#define GWEN_DB_FLAGS_QUOTE_VALUES 0x00080000
/** allows writing of subgroups when writing to a stream */
#define GWEN_DB_FLAGS_WRITE_SUBGROUPS 0x00100000
/** adds some comments when writing to a stream */
#define GWEN_DB_FLAGS_DETAILED_GROUPS 0x00200000
/** indents text according to the current path depth when writing to a
* stream to improve the readability of the created file */
#define GWEN_DB_FLAGS_INDEND 0x00400000
/** writes a newline to the stream after writing a group to improve
* the readability of the created file */
#define GWEN_DB_FLAGS_ADD_GROUP_NEWLINES 0x00800000
/** uses a colon (":") instead of an equation mark when reading/writing
* variable definitions */
#define GWEN_DB_FLAGS_USE_COLON 0x01000000
/** stops reading from a stream at empty lines */
#define GWEN_DB_FLAGS_STOP_ON_EMPTY_LINE 0x02000000
/** normally the type of a variable is written to the stream, too.
* This flag changes this behaviour */
#define GWEN_DB_FLAGS_OMIT_TYPES 0x04000000
/** appends data to an existing file instead of overwriting it */
#define GWEN_DB_FLAGS_APPEND_FILE 0x08000000
/** Char values are escaped when writing them to a file. */
#define GWEN_DB_FLAGS_ESCAPE_CHARVALUES 0x10000000
/** Char values are unescaped when reading them from a file (uses the same
* bit @ref GWEN_DB_FLAGS_ESCAPE_CHARVALUES uses) */
#define GWEN_DB_FLAGS_UNESCAPE_CHARVALUES 0x10000000
/** locks a file before reading from or writing to it
* This is used by @ref GWEN_DB_ReadFile and @ref GWEN_DB_WriteFile */
#define GWEN_DB_FLAGS_LOCKFILE 0x20000000
/** These are the default flags which you use in most cases */
#define GWEN_DB_FLAGS_DEFAULT \
(\
GWEN_DB_FLAGS_QUOTE_VALUES | \
GWEN_DB_FLAGS_WRITE_SUBGROUPS | \
GWEN_DB_FLAGS_DETAILED_GROUPS | \
GWEN_DB_FLAGS_INDEND | \
GWEN_DB_FLAGS_ADD_GROUP_NEWLINES | \
GWEN_DB_FLAGS_ESCAPE_CHARVALUES | \
GWEN_DB_FLAGS_UNESCAPE_CHARVALUES\
)
/** same like @ref GWEN_DB_FLAGS_DEFAULT except that the produced file
* (when writing to a stream) is more compact (but less readable)*/
#define GWEN_DB_FLAGS_COMPACT \
(\
GWEN_DB_FLAGS_QUOTE_VALUES | \
GWEN_DB_FLAGS_WRITE_SUBGROUPS | \
GWEN_DB_FLAGS_ESCAPE_CHARVALUES | \
GWEN_DB_FLAGS_UNESCAPE_CHARVALUES\
)
/** These flags can be used to read a DB from a HTTP header. It uses a
* colon instead of the equation mark with variable definitions and stops
* when encountering an empty line.*/
#define GWEN_DB_FLAGS_HTTP \
(\
GWEN_DB_FLAGS_USE_COLON |\
GWEN_DB_FLAGS_STOP_ON_EMPTY_LINE\
)
/*@}*/
/** @name Node Flags
*/
/*@{*/
/** is set then this node has been altered */
#define GWEN_DB_NODE_FLAGS_DIRTY 0x00000001
/** variable is volatile (will not be written) */
#define GWEN_DB_NODE_FLAGS_VOLATILE 0x00000002
/** this is only valid for groups. It determines whether subgroups will
* inherit the hash mechanism set in the root node. */
#define GWEN_DB_NODE_FLAGS_INHERIT_HASH_MECHANISM 0x00000004
/*@}*/
/**
* This is the type used to store a DB. Its contents are explicitly NOT
* part of the API.
*
* A description of what can be done with this type can be found in
* @ref db.h
*/
typedef union GWEN_DB_NODE GWEN_DB_NODE;
/**
* This specifies the type of a value stored in the DB.
*/
typedef enum {
/** type unknown */
GWEN_DB_VALUETYPE_UNKNOWN=0,
/** simple, null terminated C-string */
GWEN_DB_VALUETYPE_CHAR,
/** integer */
GWEN_DB_VALUETYPE_INT,
/** binary, user defined data */
GWEN_DB_VALUETYPE_BIN,
/** pointer , will not be stored or read to/from files */
GWEN_DB_VALUETYPE_PTR
} GWEN_DB_VALUETYPE;
/** @name Constructing, Destructing, Copying
*
*/
/*@{*/
/**
* Creates a new (empty) group with the given name. I.e. this is the
* constructor. When finished using this group, you should free it
* using @ref GWEN_DB_Group_free() in order to avoid memory leaks.
* @param name name of the group to create
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_Group_new(const char *name);
/**
* Frees a DB group. I.e. this is the destructor. This is needed to
* avoid memory leaks.
* @param n db node
*/
GWENHYWFAR_API
void GWEN_DB_Group_free(GWEN_DB_NODE *n);
/**
* Creates a deep copy of the given node. This copy will then be owned
* by the caller and MUST be freed after using it by calling @ref
* GWEN_DB_Group_free().
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_Group_dup(const GWEN_DB_NODE *n);
/*@}*/
/** @name Iterating Through Groups
*
*/
/*@{*/
/**
* Returns the first group node below the given one.
*
* If there is no group node then NULL is returned. This can either
* mean that this node does not have any children or the only
* children are variables instead of groups.
*
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n);
/**
* Returns the next group node following the given one, which has the
* same parent node.
*
* This function works absolutely independently of the group nodes'
* names -- the returned node may or may not have the same name as the
* specified node. The only guarantee is that the returned node will
* be a group node.
*
* If there is no group node then NULL is returned. This can either
* mean that the parent node does not have any further
* children, or that the other children are variables instead
* of groups.
*
* @note This is one of the few functions where the returned node is @e not
* the child of the specified node, but instead it is the next node
* with the same parent node. In other words, this function is an
* exception. In most other functions the returned node is a child of
* the specified node.
*
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetNextGroup(GWEN_DB_NODE *n);
/**
* Returns the first group node below the given one by name.
*
* If there is no matching group node then NULL is returned. This can either
* mean that this node does not have any children or the only
* children are variables instead of groups or their is no group of the
* given name.
*
* @param n db node
* @param name name to look for (joker and wildcards allowed)
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name);
/**
* Returns the next group node following the given one, which has the
* same parent node, by name.
*
* If there is no matching group node then NULL is returned. This can either
* mean that the parent node does not have any further
* children, or that the other children are variables instead
* of groups or that there is no group with the given name.
*
* @note This is one of the few functions where the returned node is @e not
* the child of the specified node, but instead it is the next node
* with the same parent node. In other words, this function is an
* exception. In most other functions the returned node is a child of
* the specified node.
*
* @param n db node
* @param name name to look for (joker and wildcards allowed)
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name);
/** Callback function type for GWEN_DB_Groups_Foreach(),
* GWEN_DB_Variables_Foreach(), and GWEN_DB_Values_Foreach().
*
* @param node The current node element
*
* @param user_data The arbitrary data passed to the foreach function.
*
* @return NULL if the iteration should continue, or non-NULL if the
* iteration should stop and that value be returned.
*/
typedef void *(*GWEN_DB_NODES_CB)(GWEN_DB_NODE *node, void *user_data);
/** Iterates through all group nodes that are @e direct children
* of the given node, calling the callback function 'func' on each
* group node. Traversal will stop when 'func' returns a non-NULL
* value, and the routine will return with that value. Otherwise the
* routine will return NULL.
*
* If no nodes that are groups are found as children, then
* this function will simply do nothing.
*
* @param node The group node whose children shall be iterated through.
* @param func The function to be called with each group node.
* @param user_data A pointer passed on to the function 'func'.
* @return The non-NULL pointer returned by 'func' as soon as it
* returns one. Otherwise (i.e. 'func' always returns NULL)
* returns NULL.
* @author Christian Stimming */
GWENHYWFAR_API
void *GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func,
void *user_data);
/** Returns the number of group nodes that are @e direct children of
* the given node. In other words, this is the number of group nodes
* that will be reached in the GWEN_DB_Groups_foreach() function. */
GWENHYWFAR_API
unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node);
/*@}*/
/** @name Variable Getter and Setter
*
* These getter functions check for the existence of the given variable and
* return the value specified by an index.
* Under the following circumstances the also given default value will be
* returned:
*
* - the variable does not exist
* - the variable exists but has no values (should not occur)
* - the variable exists but the given value index is out of range (e.g.
* specifying index 1 with a variable that has only one value)
* - a string value is expected but the variable is not of that type.
* However, if you want an integer value but the variable only has a char
* value then the getter functions try to convert the char to an integer.
* Other conversions do not take place.
*
*
* The setter functions either replace an existing variable, create a missing
* variable, add a value or return an error if the variable does not exist
* (see description of the flags).
* All setter functions make deep copies of the given values, so you may
* free the params after calling the setter function.
*
* All getter functions return a const pointer to the variable's retrieved
* value.
* All setter functions return Zero if ok and Nonzero on error.
*
* This module knows about the following types (see @ref GWEN_DB_VALUETYPE):
*
* - char (simple null terminated C strings)
* - int (integer values)
* - bin (binary, user specified data)
*
*
* @note The value returned by a getter function is only valid as long as the
* corresponding variable (node) exists.
* So if you retrieve the value of a variable and delete the variable (or even
* the whole DB) afterwards the pointer becomes invalid and using it will most
* likely crash your program.
* If you want to use such a value even after the corresponding variable
* has been deleted you need to make a copy.
*
*/
/*@{*/
/**
* Returns the variable's retrieved value.
* @param n db node
* @param path path and name of the variable
* @param idx index number of the value to return
* @param defVal default value to return in case there is no real value
*/
GWENHYWFAR_API
const char *GWEN_DB_GetCharValue(GWEN_DB_NODE *n,
const char *path,
int idx,
const char *defVal);
/**
* @return 0 on success, nonzero on error
* @param n db node
* @param flags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
* @param path path and name of the variable
* @param val The string value that is copied into the DB
*/
GWENHYWFAR_API
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 flags,
const char *path,
const char *val);
/**
* Adds the given char value to the given variable if it not already exists
* (depending on the arguments senseCase and check).
* @return 0 on success, nonzero on error
* @param n db node
* @param path path and name of the variable
* @param val The string value that is copied into the DB
* @param senseCase if 0 then the case of the value is ignored while checking
* @param check if 1 then the variable will be checked for this value
*/
GWENHYWFAR_API
int GWEN_DB_AddCharValue(GWEN_DB_NODE *n,
const char *path,
const char *val,
int senseCase,
int check);
/**
* Returns the variable's retrieved value.
* @param n db node
* @param path path and name of the variable
* @param idx index number of the value to return
* @param defVal default value to return in case there is no real value
*/
GWENHYWFAR_API
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n,
const char *path,
int idx,
int defVal);
/**
* @return 0 on success, nonzero on error
* @param n db node
* @param flags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
* @param path path and name of the variable
* @param val new value
*/
GWENHYWFAR_API
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 flags,
const char *path,
int val);
/**
* Returns the variable's retrieved value. The size of the binary
* data is written into the int pointer argument returnValueSize.
* @param n db node
* @param path path and name of the variable
* @param idx index number of the value to return
* @param defVal default value to return in case there is no real value
* @param defValSize size of the default value
* @param returnValueSize pointer to a variable to receive the length
* of the data returned
*/
GWENHYWFAR_API
const void *GWEN_DB_GetBinValue(GWEN_DB_NODE *n,
const char *path,
int idx,
const void *defVal,
unsigned int defValSize,
unsigned int *returnValueSize);
/**
* @param n db node
* @param path path and name of the variable
* @param flags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
* @param val The binary data that is copied into the DB.
* @param valSize The number of bytes in the binary data value.
*
* @return 0 on success, nonzero on error
*/
GWENHYWFAR_API
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 flags,
const char *path,
const void *val,
unsigned int valSize);
/**
* Returns the variable's retrieved value.
* @param n db node
* @param path path and name of the variable
* @param idx index number of the value to return
* @param defVal default value to return in case there is no real value
*/
GWENHYWFAR_API
void *GWEN_DB_GetPtrValue(GWEN_DB_NODE *n,
const char *path,
int idx,
void *defVal);
/**
* @param n db node
* @param path path and name of the variable
* @param flags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
* @param val The pointer that is stored within the DB.
*
* @return 0 on success, nonzero on error
*/
GWENHYWFAR_API
int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 flags,
const char *path,
void *val);
/*@}*/
/** @name Group Handling
*
*/
/*@{*/
/**
* This function either creates a new group, returns an existing one or
* returns an error if there is no group but the caller wanted one (depending
* on the flags given).
* @param n db node
* @param flags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
* @param path path and name of the group to be created/located
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetGroup(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 flags,
const char *path);
/**
* Returns the name of the given group.
*/
GWENHYWFAR_API
const char *GWEN_DB_GroupName(GWEN_DB_NODE *n);
/**
* Renames the given group.
* @param n db node
* @param newname new name for the group
*/
GWENHYWFAR_API
void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname);
/**
* Adds the given group node as a new child of the given parent group node.
*
* The group name has no influence on what will happen in this
* function. In other words, if the parent group already has a child
* group with the same name as 'node', then after this function two
* child group nodes with the same name will exist.
*
* @note This function takes over the ownership of the new group, so
* you MUST NOT free it afterwards.
*
* @param parent Some group node that will be the parent of the added node
* @param node Group node to add
*/
GWENHYWFAR_API
int GWEN_DB_AddGroup(GWEN_DB_NODE *parent, GWEN_DB_NODE *node);
/**
* Adds the given group node as the new first child of the given parent group
* node.
*
* The group name has no influence on what will happen in this
* function. In other words, if the parent group already has a child
* group with the same name as 'node', then after this function two
* child group nodes with the same name will exist.
*
* @note This function takes over the ownership of the new group, so
* you MUST NOT free it afterwards.
*
* @param parent Some group node that will be the parent of the added node
* @param node Group node to add
*/
GWENHYWFAR_API
int GWEN_DB_InsertGroup(GWEN_DB_NODE *parent, GWEN_DB_NODE *node);
/**
* This function adds all children of the second node as new children to
* the first given one.
*
* @note This function does NOT take over ownership of the new
* group. The caller is still the owner of the given group.
* @param n db node
* @param nn node whose children are to be added (makes deep copies)
*/
GWENHYWFAR_API
int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn);
/**
* Unlinks a group (and thereby all its children) from its parent and
* brothers.
*
* This function DOES NOT free the group, it just unlinks it. You can then use
* it with e.g. @ref GWEN_DB_AddGroup or other functions to relink it at any
* other position of even in other DBs.
* @param n db node
*/
GWENHYWFAR_API
void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n);
/**
* Locates and removes the group of the given name.
* @return 0 on success, nonzero on error
* @param n db node
* @param path path to the group to delete
*/
GWENHYWFAR_API
int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n,
const char *path);
/**
* Frees all children of the given node thereby clearing it.
* @return 0 on success, nonzero on error
* @param n db node
* @param path path to the group under the given node to clear
* (if 0 then clear the given node)
*/
GWENHYWFAR_API
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n,
const char *path);
/** Predicate: Returns nonzero (TRUE) or zero (FALSE) if the given
* NODE is a Group or not. Usually these group nodes are the only
* nodes that the application gets in touch with.
*
* @param n db node
*/
GWENHYWFAR_API
int GWEN_DB_IsGroup(const GWEN_DB_NODE *n);
/**
* Returns the node flags for the given db node.
* Please note that all modifications applied to a node will set the
* dirty flag in the node itself and all its parents.
* This allows to use this funcion here to check whether a DB has been
* modified.
* @return current node flags for this node (see
* @ref GWEN_DB_NODE_FLAGS_DIRTY)
*
* @param n db node
*/
GWENHYWFAR_API
GWEN_TYPE_UINT32 GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n);
/**
* Modifies the node flags for the given db node
* @param n db node
* @param flags flags to set (see @ref GWEN_DB_NODE_FLAGS_DIRTY)
*/
GWENHYWFAR_API
void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 flags);
/**
* Modifies the flags of the given node and all its parents according
* to the parameters given.
* @param n db node
* @param newflags new flags to set (see @ref GWEN_DB_NODE_FLAGS_DIRTY)
* @param mask only those flags which are set in this mask are modified
* according to newflags
*/
void GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 newflags,
GWEN_TYPE_UINT32 mask);
/**
* Modifies the flags of the given node and all its children according
* to the parameters given.
* @param n db node
* @param newflags new flags to set (see @ref GWEN_DB_NODE_FLAGS_DIRTY)
* @param mask only those flags which are set in this mask are modified
* according to newflags
*/
void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n,
GWEN_TYPE_UINT32 newflags,
GWEN_TYPE_UINT32 mask);
/*@}*/
/** @name Reading and Writing From/To Streams
*
* These functions read or write a DB from/to GWEN_BUFFEREDIO.
* This allows to use any source or target supported by GWEN_BUFFEREDIO
* for data storage (these are currently sockets, files and memory buffers).
* The flags determine how to read/write the data (e.g. if sub-groups are
* to be written etc).
*/
/*@{*/
/**
* Read a DB from GWEN_BUFFEREDIO.
* @param n db node
* @param bio buffered IO to use
* @param dbflags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
*/
GWENHYWFAR_API
int GWEN_DB_ReadFromStream(GWEN_DB_NODE *n,
GWEN_BUFFEREDIO *bio,
GWEN_TYPE_UINT32 dbflags);
/**
* Read a DB from a file.
* @param n db node
* @param fname path and name of the file to load
* @param dbflags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
*/
GWENHYWFAR_API
int GWEN_DB_ReadFile(GWEN_DB_NODE *n,
const char *fname,
GWEN_TYPE_UINT32 dbflags);
/**
* Write a DB to a GWEN_BUFFEREDIO.
* @param n db node
* @param bio buffered IO to use
* @param dbflags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
*/
GWENHYWFAR_API
int GWEN_DB_WriteToStream(GWEN_DB_NODE *n,
GWEN_BUFFEREDIO *bio,
GWEN_TYPE_UINT32 dbflags);
/**
* Write a DB to a file.
* @param n db node
* @param fname path and name of the file to create. If it already exists
* it will be overwritten
* @param dbflags see @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others which
* can all be OR-combined to form the flags to use.
*/
GWENHYWFAR_API
int GWEN_DB_WriteFile(GWEN_DB_NODE *n,
const char *fname,
GWEN_TYPE_UINT32 dbflags);
/**
* Imports a file into a DB using a GWEN_DBIO importer.
* @param n node to read into (becomes the root of the imported data)
* @param fname name of the file to import
* @param type GWEN_DBIO type
* @param params parameters for the GWEN_DBIO importer (content depends on
* the importer, may even be NULL for some types)
* @param dbflags flags to use while importing (see
* @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others)
*/
GWENHYWFAR_API
int GWEN_DB_ReadFileAs(GWEN_DB_NODE *n,
const char *fname,
const char *type,
GWEN_DB_NODE *params,
GWEN_TYPE_UINT32 dbflags);
/**
* Exports a DB to a file using a GWEN_DBIO exporter.
* @param n node to write
* @param fname name of the file to export to
* @param type GWEN_DBIO type
* @param params parameters for the GWEN_DBIO exporter (content depends on
* the exporter, may even be NULL for some types)
* @param dbflags flags to use while exporting (see
* @ref GWEN_DB_FLAGS_OVERWRITE_VARS and others)
*/
GWENHYWFAR_API
int GWEN_DB_WriteFileAs(GWEN_DB_NODE *n,
const char *fname,
const char *type,
GWEN_DB_NODE *params,
GWEN_TYPE_UINT32 dbflags);
/*@}*/
/** @name Iterating Through Variables and variable handling
*
*/
/*@{*/
/**
* Returns the first variable below the given group.
* If there is no variable then NULL is returned.
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetFirstVar(GWEN_DB_NODE *n);
/**
* Returns the next variable node following the given one, which has
* the same parent node.
*
* This function works absolutely independently of the variable nodes'
* names -- the returned node may or may not have the same name as the
* specified node. The only guarantee is that the returned node will
* be a variable node.
*
* If there is no variable node then NULL is returned. This can either
* mean that the parent node does not have any further children, or
* that the other children are groups instead of variables.
*
* @note This is the only function where the returned node is @e not
* the child of the specified node, but instead it is the next node
* with the same parent node. In other words, this function is an
* exception. In all other functions the returned node is a child of
* the specified node.
*
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetNextVar(GWEN_DB_NODE *n);
/**
* Returns the name of the variable specified by the given node.
* @param n db node specifying a variable (not a group !)
*/
GWENHYWFAR_API
const char *GWEN_DB_VariableName(GWEN_DB_NODE *n);
/** Iterates through all variable nodes that are @e direct children
* of the given node, calling the callback function 'func' on each
* variable node. Traversal will stop when 'func' returns a non-NULL
* value, and the routine will return with that value. Otherwise the
* routine will return NULL.
*
* If no nodes that are variables are found as children, then
* this function will simply do nothing.
*
* @param node The group node whose children shall be iterated through.
* @param func The function to be called with each group node.
* @param user_data A pointer passed on to the function 'func'.
* @return The non-NULL pointer returned by 'func' as soon as it
* returns one. Otherwise (i.e. 'func' always returns NULL)
* returns NULL.
* @author Christian Stimming */
GWENHYWFAR_API
void *GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func,
void *user_data);
/** Returns the number of variable nodes that are @e direct children
* of the given node. In other words, this is the number of variable
* nodes that will be reached in the GWEN_DB_Variables_Foreach()
* function. */
GWENHYWFAR_API
unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node);
/**
* Returns the type of the first value of the given variable
* @param n root node of the DB
* @param p path of the variable to inspect
*/
GWENHYWFAR_API
GWEN_DB_VALUETYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n,
const char *p);
/**
* Deletes the given variable by removing it and its values from the DB.
* @param n root of the DB
* @param path path to the variable to remove
* @return Zero on success, nonzero on error
*/
GWENHYWFAR_API
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n,
const char *path);
/**
* Checks whether the given variable exists.
* @return Zero if variable not found, nonzero otherwise
* @param n root of the DB
* @param path path to the variable to check for
*/
GWENHYWFAR_API
int GWEN_DB_VariableExists(GWEN_DB_NODE *n,
const char *path);
/**
* Checks whether the given variable and value exists.
* @return Zero if variable not found, nonzero otherwise
* @param n root of the DB
* @param path path to the variable to check for
* @param idx index number of the variable's value to check for
*/
GWENHYWFAR_API
int GWEN_DB_ValueExists(GWEN_DB_NODE *n,
const char *path,
unsigned int idx);
/** Predicate: Returns nonzero (TRUE) or zero (FALSE) if the given
* NODE is a Variable or not. Usually the Application does not get in
* touch with such Nodes but only with nodes that are Groups.
*
* @param n db node
*/
GWENHYWFAR_API
int GWEN_DB_IsVariable(const GWEN_DB_NODE *n);
/*@}*/
/** @name Iterating Through Values and value handling
*
*/
/*@{*/
/**
* Returns the first value below the given variable.
* If there is no value then NULL is returned.
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetFirstValue(GWEN_DB_NODE *n);
/**
* Returns the next value node following the given one, which has the
* same parent node.
*
* This function works absolutely independently of the value nodes'
* names (FIXME: is there such thing as a value name? If not, then
* this paragraph should be removed) -- the returned node may or may
* not have the same name as the specified node. The only guarantee is
* that the returned node will be a value node.
*
* If there is no value node then NULL is returned. This can either
* mean that the parent node does not have any further children, or
* that the other children are variables instead of values (FIXME: Is
* the last sentence true? If this can't be the case then it can be
* deleted.)
*
* @note This is the only function where the returned node is @e not
* the child of the specified node, but instead it is the next node
* with the same parent node. In other words, this function is an
* exception. In all other functions the returned node is a child of
* the specified node.
*
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_NODE *GWEN_DB_GetNextValue(GWEN_DB_NODE *n);
/** Iterates through all value nodes that are @e direct children
* of the given node, calling the callback function 'func' on each
* value node. Traversal will stop when 'func' returns a non-NULL
* value, and the routine will return with that value. Otherwise the
* routine will return NULL.
*
* If no nodes that are values are found as children, then
* this function will simply do nothing.
*
* @param node The variable node whose children shall be iterated through.
* @param func The function to be called with each group node.
* @param user_data A pointer passed on to the function 'func'.
* @return The non-NULL pointer returned by 'func' as soon as it
* returns one. Otherwise (i.e. 'func' always returns NULL)
* returns NULL.
* @author Christian Stimming */
GWENHYWFAR_API
void *GWEN_DB_Values_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func,
void *user_data);
/** Returns the number of value nodes that are @e direct children of
* the given node. In other words, this is the number of value nodes
* that will be reached in the GWEN_DB_Values_foreach() function. */
GWENHYWFAR_API
unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node);
/**
* Returns the type of the given value.
* @param n db node
*/
GWENHYWFAR_API
GWEN_DB_VALUETYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n);
GWENHYWFAR_API
GWEN_DB_VALUETYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n,
const char *p,
unsigned int i);
/** Predicate: Returns nonzero (TRUE) or zero (FALSE) if the given
* NODE is a Value or not. Usually the Application does not get in
* touch with such Nodes but only with nodes that are Groups.
*
* @param n db node
*/
GWENHYWFAR_API
int GWEN_DB_IsValue(const GWEN_DB_NODE *n);
/*@}*/
/** @name Debugging
*
* These functions are for debugging purposes only. You should NOT consider
* them part of the API.
*/
/*@{*/
/**
* Dumps the content of the given DB to the given file (e.g. stderr).
* @param n node to dump
* @param f destination file (e.g. stderr)
* @param insert number of blanks to insert at every line
*/
GWENHYWFAR_API
void GWEN_DB_Dump(GWEN_DB_NODE *n, FILE *f, int insert);
/*@}*/
/** @name Hash Mechanism
*
* These functions allow for the implementation of hash mechanisms for
* DB groups.
* Those mechanisms can be applied to group nodes to speed up the lookup of
* subnodes to groups.
*/
/*@{*/
typedef struct GWEN_DB_HASH_MECHANISM GWEN_DB_HASH_MECHANISM;
typedef int (*GWEN_DB_HASH_INITNODE_FN)(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_NODE *node,
void **hashData);
typedef int (*GWEN_DB_HASH_FININODE_FN)(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_NODE *node,
void **hashData);
typedef int (*GWEN_DB_HASH_ADDNODE_FN)(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_NODE *parent,
GWEN_DB_NODE *node,
int appendOrInsert, /* 1=append */
void *hashData);
typedef int (*GWEN_DB_HASH_UNLINKNODE_FN)(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_NODE *parent,
GWEN_DB_NODE *node,
void *hashData);
typedef GWEN_DB_NODE* (*GWEN_DB_HASH_GETNODE_FN)(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_NODE *parent,
const char *name,
int idx,
void *hashData);
GWENHYWFAR_API
GWEN_DB_HASH_MECHANISM *GWEN_DB_HashMechanism_new();
GWENHYWFAR_API
void GWEN_DB_HashMechanism_Attach(GWEN_DB_HASH_MECHANISM *hm);
GWENHYWFAR_API
void GWEN_DB_HashMechanism_free(GWEN_DB_HASH_MECHANISM *hm);
GWENHYWFAR_API
void GWEN_DB_HashMechanism_SetInitNodeFn(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_HASH_INITNODE_FN f);
GWENHYWFAR_API
void GWEN_DB_HashMechanism_SetFiniNodeFn(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_HASH_FININODE_FN f);
GWENHYWFAR_API
void GWEN_DB_HashMechanism_SetAddNodeFn(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_HASH_ADDNODE_FN f);
GWENHYWFAR_API
void GWEN_DB_HashMechanism_SetUnlinkNodeFn(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_HASH_UNLINKNODE_FN f);
GWENHYWFAR_API
void GWEN_DB_HashMechanism_SetGetNodeFn(GWEN_DB_HASH_MECHANISM *hm,
GWEN_DB_HASH_GETNODE_FN f);
/**
* Assigns a hash mechanism to a DB group. If the node flag
* @ref GWEN_DB_NODE_FLAGS_INHERIT_HASH_MECHANISM is set on this node then
* this hash mechanism will be set to all nodes which become children to the
* given node as they are added (but only if the nodes to be added don't
* already have a hash mechanism of their own).
*
* You should set the hash mechanism to the root node and also set the flag
* described above to ensure that every group in every level uses this hash
* mechanism. The GWEN_DB takes care of calling the approppriate init, fini,
* attach and free functions of the hash mechanism.
*
*
*/
GWENHYWFAR_API
int GWEN_DB_Group_SetHashMechanism(GWEN_DB_NODE *node,
GWEN_DB_HASH_MECHANISM *hm);
/*@}*/
/*@}*/
#ifdef __cplusplus
}
#endif
#endif