/* ELAPI Header file for collection interface. Copyright (C) Dmitri Pal 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 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 the GNU General Public License along with this program. If not, see . */ #ifndef ELAPI_COLLECTION_H #define ELAPI_COLLECTION_H #ifndef EOK #define EOK 0 #endif #define ELAPI_TYPE_STRING 0x00000001 #define ELAPI_TYPE_BINARY 0x00000002 #define ELAPI_TYPE_INTEGER 0x00000004 #define ELAPI_TYPE_UNSIGNED 0x00000008 #define ELAPI_TYPE_LONG 0x00000010 #define ELAPI_TYPE_ULONG 0x00000020 #define ELAPI_TYPE_DOUBLE 0x00000040 #define ELAPI_TYPE_COLLECTION 0x00000080 /* The item of this type denotes that starting element of a collection */ #define ELAPI_TYPE_COLLECTIONREF 0x00000100 /* The item of this type denotes a pointer to already existing external collection */ #define ELAPI_TYPE_END 0x10000000 /* Special type that denotes the end of the collection. Useful when traversing collection */ #define ELAPI_TYPE_ANY 0x0FFFFFFF /* Special type that denotes any. Useful when traversing collection */ /* Any data we deal with can't be longer than this */ #define ELAPI_MAX_DATA 65535 /* The modes that define how one collection can be added to another */ #define ELAPI_ADD_MODE_REFERENCE 0 /* One collection will contain a pointer of another */ #define ELAPI_ADD_MODE_EMBED 1 /* One collection will be donated to become a part of another collection. After that the donating connection handle should not be used or freed. It means that it can be donated only once. The donation attempt will fail if the collection is referenced by other collection. */ #define ELAPI_ADD_MODE_CLONE 2 /* Creates a deep copy of a collection with its sub collections */ /* Modes how the collection is traversed */ #define ELAPI_TRAVERSE_DEFAULT 0x00000000 /* No special flags - means it will go through all the items */ #define ELAPI_TRAVERSE_ONELEVEL 0x00000001 /* Flag to traverse only high level */ #define ELAPI_TRAVERSE_END 0x00000002 /* Call handler once more when end of the collection is reached - good for processing nested collections */ #define ELAPI_TRAVERSE_IGNORE 0x00000004 /* Ignore sub collections at all as if there are none */ /* Match values */ #define ELAPI_NOMATCH 0 #define ELAPI_MATCH 1 /* Structure that holds one property */ struct collection_item { struct collection_item *next; char *property; int property_len; int type; int length; void *data; }; /* Special type of data that stores collection header information */ struct collection_header { struct collection_item *last; int reference_count; int count; }; /* Function that creates an named collection */ int create_collection(struct collection_item **ci,char *name); /* Function that destroys a collection */ void destroy_collection(struct collection_item *ci); /* Family of functions that add properties to an event */ /* Family includes the following convinience functions: */ /* Add a string property to collection. Length should include the null terminating 0 */ int add_str_property(struct collection_item *ci,char *subcollection, char *property,char *string,int length); /* Add a binary property to collection. */ int add_binary_property(struct collection_item *ci,char *subcollection, char *property,void *binary_data,int length); /* Add an int property to collection. */ int add_int_property(struct collection_item *ci,char *subcollection, char *property,int number); /* Add an unsigned int property. */ int add_unsigned_property(struct collection_item *ci,char *subcollection, char *property,unsigned int number); /* Add a long property. */ int add_long_property(struct collection_item *ci,char *subcollection, char *property,long number); /* Add an unsigned long property. */ int add_ulong_property(struct collection_item *ci,char *subcollection, char *property,unsigned long number); /* Add a double property. */ int add_double_property(struct collection_item *ci,char *subcollection, char *property,double number); /* Add any property */ int add_any_property(struct collection_item *ci, /* Collection to find things in */ char *subcollection, /* Subcollection */ char *property, /* Name */ int type, /* Type of the passed in data */ void *data, /* Pointer to the new data */ int length); /* Length of the data. For strings should include trailing 0 */ /* Update functions */ /* Update a string property in the collection. Length should include the null terminating 0 */ int update_str_property(struct collection_item *ci, char *property,int mode_flags, char *string,int length); /* Update a binary property in the collection. */ int update_binary_property(struct collection_item *ci, char *property,int mode_flags, void *binary_data,int length); /* Update an int property in the collection. */ int update_int_property(struct collection_item *ci, char *property,int mode_flags, int number); /* Update an unsigned int property. */ int update_unsigned_property(struct collection_item *ci, char *property,int mode_flags, unsigned int number); /* Update a long property. */ int update_long_property(struct collection_item *ci, char *property,int mode_flags ,long number); /* Update an unsigned long property. */ int update_ulong_property(struct collection_item *ci, char *property,int mode_flags, unsigned long number); /* Update a double property. */ int update_double_property(struct collection_item *ci, char *property,int mode_flags, double number); /* Update property in the collection */ int update_property(struct collection_item *ci, /* Collection to find things in */ char *property_to_find, /* Name to match */ int type, /* Type of the passed in data */ void *new_data, /* Pointer to the new data */ int length, /* Length of the data. For strings should include trailing 0 */ int mode_flags); /* How to traverse the collection */ /* Add collection to collection */ int add_collection_to_collection(struct collection_item *ci, /* Collection handle to with we add another collection */ char *sub_collection_name, /* Name of the sub collection to which collection needs to be added as a property. If NULL high level collection is assumed. */ char *as_property, /* Name of the collection property. If NULL, same property as the name of the collection being added will be used. */ struct collection_item *collection_to_add, /* Collection to add */ int mode); /* How this collection needs to be added */ /* Create a deep copy of the current collection. */ /* Referenced collections of the donor are copied as sub collections. */ int copy_collection(struct collection_item **collection_copy, struct collection_item *collection_to_copy, char *name_to_use); /* Signature of the callback that needs to be used when traversing a collection or looking for a specific item */ typedef int (*item_fn)(char *, /* The name of the property will be passed in this parameter. */ int, /* Length of the property name will be passed in this parameter. */ int, /* Type of the data will be passed in this parameter */ void *, /* Ponter to the data will be passed in this parameter */ int, /* Length of data will be passed in this parameter */ void *, /* Custom data will be passed in this parameter */ int *); /* Pointer to variable where the handler can put non zero to stop processing */ /* Function to traverse the entire collection including optionally sub collections */ int traverse_collection(struct collection_item *ci, /* Collection to traverse */ int mode_flags, /* Flags defining how to traverse */ item_fn item_handler, /* Handler called for each item */ void *custom_data); /* Custom data passed around */ /* Search function. Looks up an item in the collection based on the property. Essentually it is a traverse function with spacial traversing logic. It is the responsibility of the handler to set something in the custom data to indicate that the item was found. Function will not return error if the item is not found. It is the responsibility of the calling application to check the data passed in custom_data and see if the item was found and that the action was performed. */ int get_item_and_do(struct collection_item *ci, /* Collection to find things in */ char *property_to_find, /* Name to match */ int type, /* Type filter */ int mode_flags, /* How to traverse the collection */ item_fn item_handler, /* Function to call when the item is found */ void *custom_data); /* Custom data passed around */ /* Convenience function to get individual item */ /* Caller should be aware that this is not a copy of the item * but the pointer to actual item stored in the collection. * The retuned pointer should never be altered or freed by caller of the function. * The caller should be sure that the collection does not go out of scope * while the pointer to its data is in use. */ int get_item(struct collection_item *ci, /* Collection to find things in */ char *property_to_find, /* Name to match */ int type, /* Type filter */ int mode_flags, /* How to traverse the collection */ struct collection_item **item); /* Found item */ /* Delete property from the collection */ int delete_property(struct collection_item *ci, /* Collection to find things in */ char *property_to_find, /* Name to match */ int type, /* Type filter */ int mode_flags); /* How to traverse the collection */ /* Convinience function to check if the property is indeed in the collection */ int is_item_in_collection(struct collection_item *ci, /* Collection to find things in */ char *property_to_find, /* Name to match */ int type, /* Type filter */ int mode_flags, /* How to traverse the collection */ int *found); /* Boolean that turns to nonzero if the match is found */ /* Get collection - get a pointer to a collection included into another collection */ int get_collection_reference(struct collection_item *ci, /* High level collection */ struct collection_item **acceptor, /* The pointer that will accept extracted handle */ char *collection_to_find); /* Name to of the collection */ #endif