Files
sics/hipadaba.h
Ferdi Franceschini 3168325921 PSI update
r1464 | ffr | 2007-02-12 12:20:21 +1100 (Mon, 12 Feb 2007) | 2 lines
2012-11-15 12:58:05 +11:00

368 lines
14 KiB
C

/**
* Hipadaba is a hierarchical database of parameters. Parameters can be of
* various types. What happens when a parameter is being set, updated or read
* is largely determined through callbacks which can be registered on
* parameters. This can implement permission checking, range checking,
* automatic notifications and whatever comes up.
*
* There is some subtlety here between updating and setting a parameter. The
* issue is that in instrument control there are two types of parameters:
* Instant program parameters and external parameters like motors which are
* dependent on some possibly slow and inaccurate hardware. Let us consider
* the latter: Setting the parameter should do all necessary checks on the
* parameter and tell the hardware where to go. Some internal code may be
* watching the hardware; that code should use Update which justs sets a new value
* and invokes callbacks which notify interested parties about the new parameter
* value. For program parameters, a callback shall be installed which calls update
* directly after setting the parameter. Thus notification callbacks shall always be
* connected to the update chain.
*
* copyright: GPL
*
* Mark Koennecke, June 2006
*
* Added treeChange callback, Mark Koennecke, November 2006
*
* Added support for properties, Mark Koennecke, January 2007
*/
#ifndef HIPADABA
#define HIPADABA
#include <stringdict.h>
/*------- datatypes */
#define HIPNONE -1
#define HIPINT 0
#define HIPFLOAT 1
#define HIPTEXT 2
#define HIPINTAR 3
#define HIPFLOATAR 4
#define HIPINTVARAR 5
#define HIPFLOATVARAR 6
#define HIPOBJ 7
/* -------- callback types */
#define HCBSET 0
#define HCBUPDATE 1
#define HCBREAD 2
#define HCBTREE 3
/*--------- error codes */
#define HDBTYPEMISMATCH -7701
#define HDBLENGTHMISMATCH -7702
/*===================== structure definitions ===================================*/
typedef struct __hdbValue {
int dataType;
int arrayLength;
union __value {
int intValue;
double doubleValue;
char *text;
int *intArray;
double *floatArray;
void *obj;
}v;
}hdbValue;
/*------------------------------------------------------------------------------*/
typedef struct __hipadaba {
int magic;
struct __hipadaba *mama;
struct __hipadaba *child;
struct __hipadaba *next;
struct __hdbcallback *writeCallbacks;
struct __hdbcallback *updateCallbacks;
struct __hdbcallback *readCallbacks;
struct __hdbcallback *treeChangeCallbacks;
char *name;
hdbValue value;
int protected;
pStringDict properties;
}Hdb, *pHdb;
/*-------------------------------------------------------------------------------*/
typedef int (*hdbCallbackFunction)(void *userData, void *callData,
pHdb currentNode, hdbValue v);
typedef void (*killUserData)(void *data);
/*-------------------------------------------------------------------------------*/
typedef struct __hdbcallback {
void *userData;
killUserData killFunc;
hdbCallbackFunction userCallback;
int id;
int internalID;
struct __hdbcallback *next;
struct __hdbcallback *previous;
}hdbCallback, *pHdbCallback;
/*======================== Function protoypes: hdbData ========================*/
hdbValue makeHdbValue(int datatype, int length);
/**
* make a hdbValue and initailize it with the data in the void
* pointer. Do not initialise when data = NULL.
* @param dataType The datatype of the hdbValue
* @param The array length of the hdbValue
* @param data Initialisation data for hdbValue
* @return a suitably defined hdbValue
*/
hdbValue makeHdbData(int datatype, int length, void *data);
/**
* wrap an integer as an hdbValue
* @param initValue the initial value of the int
* @return: A properly initialized hdbValue structure
*/
hdbValue MakeHdbInt(int initValue);
/**
* wrap a float as an hdbValue
* @param initValue the initial value of the float
* @return: A properly initialized hdbValue structure
*/
hdbValue MakeHdbFloat(double initValue);
/**
* wrap a text string as an hdbValue
* @param initText the initial value of the text. WARNING: MakeHdbText does
* not copy the data. The Hdb code only copies data on updates. Normally this
* no problem; however in complicated cenarios it is better if initText points
* to dynamically allocated memory.
* @return: A properly initialized hdbValue structure
*/
hdbValue MakeHdbText(char *initText);
/**
* wrap a int array as an hdbValue
* @param length The length of the int array
* @param data the initial content of the int array. WARNING: MakeHdbIntArray
* does not copy the data. The Hdb code only copies data on updates. Normally
* this no problem; however in complicated scenarios it is better if
* data points to dynamically allocated memory.
* @return: A properly initialized hdbValue structure
*/
hdbValue MakeHdbIntArray(int length, int *data);
/**
* wrap a float array as an hdbValue
* @param length The length of the int array
* @param data the initial content of the float array. WARNING: MakeHdbFloatArray
* does not copy the data. The Hdb code only copies data on updates. Normally
* this no problem; however in complicated scenarios it is better if
* data points to dynamically allocated memory.
* @return: A properly initialized hdbValue structure
*/
hdbValue MakeHdbFloatArray(int length, double *data);
/**
* release any dynamic memory associated with v
* @param v The hdbValue to check for dynamic memory allocation to be
* released.
*/
void ReleaseHdbValue(hdbValue *v);
/**
* copy a hipadaba value field. Takes care of memory allocation
* @param source The hdbValue to copy from
* @param target The hdbValue to copy to.
* @return 1 on success, 0 when out of memory or when type mismatch
*/
int copyHdbValue(hdbValue *source, hdbValue *target);
/**
* compares two hdbValues for identity
* @param v1 The first hdbValue
* @param v2 The second hdbValue
* @return 1 when identical, 0 else
*/
int compareHdbValue(hdbValue v1, hdbValue v2);
/**
* create a hdbValue structure with the identical properties
* as the one given as parameter. Datatypes are copied, memory is
* allocated etc. Data is copied, too
* @param source The hdbValue type to clone
* @param clone the target hdbValue structure
* @return 1 on success, 0 on when out of memory
*/
int cloneHdbValue(hdbValue *source, hdbValue *clone);
/**
* get the length of the hdbValue in bytes.
* @param v The hdbValue to calculate the length for
* @return the number of data bytes
*/
int getHdbValueLength(hdbValue v);
/*========================== function protoypes: Nodes =======================*/
/**
* make a new hipadaba node
* @param name The name of the new node
* @param datatype The datatype of the new node
* @return a new node or NULL when out of memory
*/
pHdb MakeHipadabaNode(char *name, int datatype, int length);
/**
* add a child to a node at the end of the child list.
* @param parent The node to which to add the child
* @param child The node to add
* @param callData User data for the tree chnage callback. Can be NULL.
*/
void AddHipadabaChild(pHdb parent, pHdb child, void *callData);
/**
* delete a hipadaba node and all its children
* @parma node The node to delete
* @param callData User data for the tree change callback
*/
void DeleteHipadabaNode(pHdb node, void *callData);
/*
* checks if a Hdb node is valid
* @param node The node to check
* @return 1 when valid, 0 else
*/
int isHdbNodeValid(pHdb node);
/**
* retrieve a node
* @param root The node where to start the search for the node
* @param path The unix path string for the node relative to parent
* @return The desired node or NULL when no such node exists
*/
pHdb GetHipadabaNode(pHdb root, char *path);
/**
* given a node, return the full path name to the node
* @param node The node to get the path for
* @return The full path to the node. This is dynamically allocated memory;
* the caller is reponsible for deleting it. Can be NULL when out of memory.
*/
char *GetHipadabaPath(pHdb node);
/**
* removes a node from the parents child list.
* @node the node to remove
* @param callData User data for the tree change callback
*/
void RemoveHdbNodeFromParent(pHdb node, void *callData);
/**
* delete a callback chain
* @param root The callback chain to delete
*/
void DeleteCallbackChain(pHdbCallback root);
/*===================== function protoypes: Callbacks ========================*/
/**
* make a new hipdaba callback
* @param func The function to invoke for this callback
* @param userData userData to be associated with this callback. Can be NULL.
* @param killFunc A function for freeing the userData. Can be NULL, then it will
* not be invoked
* @param id An ID associated with this callback
* @param internalID Another ID to be associated with this callback. ID's come in
* useful when callbacks have to be deleted in a later stage.
* @return A new suitabvly initialised callback structure or NULL when required elements
* are missing or there is nor memory.
*/
pHdbCallback MakeHipadabaCallback(hdbCallbackFunction func,
void *userData, killUserData killFunc,
int id, int internalID);
/**
* add a callback at the end of the callback chain
* @param node The node to which to append the callback
* @param type the type of the callback to append
* @param newCB The callback to append
*/
void AppendHipadabaCallback(pHdb node,int type, pHdbCallback newCB);
/**
* add a callback at the head of the callback chain
* @param node The node to which to append the callback
* @param type the type of the callback to append
* @param newCB The callback prepend
*/
void PrependHipadabaCallback(pHdb node, int type, pHdbCallback newCB);
/**
* remove recursively all callbacks witch match the id
* @param root The starting node from where to start removing callbacks
* @param id The ID callbacks have to match in order to be removed.
*/
void RemoveHipadabaCallback(pHdb root, int id);
/**
* remove recursively all callbacks witch match the internal id
* @param root The starting node from where to start removing callbacks
* @param internalID The internal ID callbacks have to match in order to be removed.
*/
void InternalRemoveHipadabaCallback(pHdb root, int internalID);
/*============== Parameter Handling ===============================*/
/**
* Set a hipadaba parameter. This is an external set for a parameter. It may cause
* motors to start driving etc.
* @param node The node for which to set the parameter
* @param v The new value for the node
* @param callData Additonal context data to be passed to the callback functions
* @return 0 on failure, 1 on success
*/
int SetHipadabaPar(pHdb node, hdbValue v, void *callData);
/**
* Update a hipadaba parameter. This is an internal update of a parameter,
* during driving etc.
* @param node The node for which to update the parameter
* @param v The new value for the node
* @param callData Additonal context data to be passed to the callback functions
* @return 0 on failure, 1 on success
*/
int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData);
/**
* Read a hipadaba parameter
* @param node The node for which to read the parameter
* @param v The read value for the node
* @param callData Additonal context data to be passed to the callback functions
* @return 0 on failure, 1 on success
*/
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData);
/**
* Set a hipadaba parameter. This is an external set for a parameter. It may cause
* motors to start driving etc.
* @param node The node for which to set the parameter
* param dataType The datatype the value ought to have
* @param data A pointer to the data to set.
* @param length The length of data
* @param callData Additonal context data to be passed to the callback functions
* @return 0 on failure, a negative error code on failure
*/
int SetHdbPar(pHdb node, int dataType, void *data, int length,
void *callData);
/**
* Updates a hipadaba parameter. This does not cause an active parameter to
* start driving but invokes all notifications which may be registered on
* this parameter.
* @param node The node for which to set the parameter
* param dataType The datatype the value ought to have
* @param data A pointer to the data to set.
* @param length The length of data
* @param callData Additonal context data to be passed to the callback functions
* @return 0 on failure, a negative error code on failure
*/
int UpdateHdbPar(pHdb node, int dataType, void *data, int length,
void *callData);
/**
* Read a hipadaba parameter
* @param node The node for which to read the parameter
* @param dataType The expected type of the data
* @param data A pointer to which data will be copied
* @param length The length of data.
* @param callData Additonal context data to be passed to the callback functions
* @return 0 on failure, a negative error code on failures.
*/
int GetHdbPar(pHdb node, int dataType, void *data, int length,
void *callData);
/*================================ Property Interface ==============================================*/
/**
* set a property
* @param node The node to set the property for
* @param key The key for the property
* @param value The value of the property
*/
void SetHdbProperty(pHdb node, char *key, char *value);
/**
* get the value of a property
* @param node The node to get the property from
* @param key The properties key
* @param value The area to which to copy the property
* @param len The length of value
* @return 0 on failure, 1 on success
*/
int GetHdbProperty(pHdb node, char *key, char *value, int len);
/**
* initialize a property scan on this node
* @param node The node for which to scan properties
*/
void InitHdbPropertySearch(pHdb node);
/**
* get the next property in a search
* @param node The node for which to search properties
* @param value An area where to copy the value of the property
* @param len The length of value
* @return The key of the property or NULL when the property list is exhausted
*/
const char *GetNextHdbProperty(pHdb node, char *value ,int len);
#endif