[SSSD] Request for review of the new INI interface
Dmitri Pal
dpal at redhat.com
Sun Nov 30 20:15:50 UTC 2014
On 11/29/2014 08:38 PM, Dmitri Pal wrote:
> Hello,
>
> I have been working on an interface to modify configuration file (yes
> alternative to augeas) as promised.
> INI supports multi valued keys so the interface needs to be able to
> manage duplicates.
>
> The attached header file contains the prototype of the interface.
> I have implemented value management and about to do the section
> management. That part would be quite simple.
> Before I polish everything up, hook together and start sending patches
> I wanted to make sure the interface is OK and is not missing anything.
>
> I was not sure how much of the design page is needed.
> I will probably create one based on this thread with a pointer to
> header file.
>
> The assumption is that:
> - the caller will read an existing configuration object from a file or
> create a configuration object himself. These calls are
> alreadyavailable for some time.
> - the caller will then add/updated/delete the configuration object as
> he sees fit. This is this interface.
> - the caller then will call already existing serialization function
> that will return a simple buffer object that will contain a serialized
> configuration ready to be stored in a file.
> - the caller can use simple buffer methods to write content of the
> buffer to a file descriptor or just create a file (FILE *), get the
> serialized buffer and write to that file. It is up to the caller and
> there is so far no plan to provide a specific "save function" as it is
> unclear what would be a good function to have.
>
>
> Let me know if any of these assumptions wrong.
> Please take a look at the file, it has doxygen comments. It is a
> sanity check exercise not a thorough review :-).
> The comments refer to collection interface so I included it too for
> easier reading.
Please see attached a new version of the header.
Also I wonder if I should provide a way to sort the sections and keys in
a specific order.
Would it make sense to have a way to say:
- sort the keys in sections that match a specific pattern in the
following way: first keys that match pattern a, then b, then c... and
then all the rest as they are.
- sort the sections in such a way that sections with name matching the
following patter should go first, then other pattern next, then other
pattern and so on.
Would that will be useful? I think so, but before I spend time on it I
wanted to double check.
>
> --
> Thank you,
> Dmitri Pal
>
> Sr. Engineering Manager IdM portfolio
> Red Hat, Inc.
>
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
--
Thank you,
Dmitri Pal
Sr. Engineering Manager IdM portfolio
Red Hat, Inc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.fedorahosted.org/pipermail/sssd-devel/attachments/20141130/b5a6a03d/attachment.html>
-------------- next part --------------
/*
INI LIBRARY
Interface that allows modification of the INI file.
Copyright (C) Dmitri Pal <dpal at redhat.com> 2014
INI 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 3 of the License, or
(at your option) any later version.
INI 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 INI Library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INI_CONFIGMOD_H
#define INI_CONFIGMOD_H
/**
* @defgroup insflags Flags used in add_xxx_value functions
*
* Flags used in add_xxx_value functions.
*
* @{
*/
/** @brief This is the default mode - no dup checks on insert */
#define INI_VA_NOCHECK 0
/**
* @brief Update a specific value.
* Value of index is used to determine which one out of the duplicates
* needs to be updated. Index is 0-based. If the index is out of range
* the function will do best effort and return the last instance of the key.
* For example if you have five duplicates and you are searching for the tenth
* the function will find and return fifth instance.
*/
#define INI_VA_MOD 1
/**
* @brief Update a specific value.
* Value of index is used to determine which out of the duplicates
* needs to be updated. Index is 0-based. If the value is not found or
* the index is out of range the function returns ENOENT.
* For example if you have five duplicates and and you are searching for tenth
* the error ENOENT will be returned.
*/
#define INI_VA_MOD_E 2
/**
* @brief Check for duplicate name and overwrite if found.
* Value of index is used to determine which one of the duplicates
* needs to be updated. Index is 0-based. If the value is not found
* the new value will be added following other position related arguments.
* This option performs best effort search.
* For example if you have five duplicates and you are searching for the tenth
* the function will find and return fifth instance.
*/
#define INI_VA_MODADD 3
/**
* @brief Check for duplicate name and overwrite if found.
* Value of index is used to determine which one of the duplicates
* needs to be updated. Index is 0-based. If the value is not found
* the new value will be added following other position related arguments.
* This option performs exact search.
* For example if you have five duplicates and and you are searching for tenth
* the error ENOENT will be returned.
*/
#define INI_VA_MODADD_E 4
/** @brief Find all instances of the specific key and remove them first.
* Then add respecting the position related arguments.
*/
#define INI_VA_CLEAN 5
/** @brief Return error EEXIST if an entry with the same name exists. */
#define INI_VA_DUPERROR 6
/**
* @}
*/
/**
* @brief Function to add a section.
*
* Function creates a new section in the specified position.
* The position is relative to other sections. Duplicate sections
* are not allowed. In case a duplicate section is detected function
* will return error EEXIST.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to add.
* @param[in] comments Array of comments. Can be NULL if no comment is
* needed for the section. It is expected that
* comment lines start with the correct comment
* symbol. Function does not check this.
* @param[in] count_comment Count of comments in the array. If 0
* the array is expected to be NULL terminated
* and function will traverse array until its end.
* @param[in] position A constant that specifies the way the
* section should be added. For more information
* see "disposition constants" section of
* the collection interface. The value is used
* only in addition so see the explanation
* in the "insert" paragraph. Since duplicate
* sections are not allowed any constants that
* allow addition of duplicates will cause function
* to return an error.
* @param[in] other_section Used in conjunction with position constant.
* In some cases it is convenient to add
* a section that immediately before
* or after another section. While position defines
* where it should be added this parameter defines
* the section to relate to.
* @param[in] idx Index, allows treating set of sections as
* an array and add Nth section.
*
* @return 0 - Success.
* @return EEXIST - Section already exists.
* @return ENOSYS - Unknown position value.
* @return ENOMEM - No memory to add value.
* @return EINVAL - Invalid argument.
*/
int ini_config_add_section(struct ini_cfgobj *ini_config,
const char *section,
const char *comments[],
size_t count_comment,
int position,
const char *other_section,
int idx);
/**
* @brief Function to update a comment for a section.
*
* Function finds a section and updates or removes its comment.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to change the comment for.
* @param[in] comments Array of comments. Can be NULL if no comment is
* needed for the section. It is expected that
* comment lines start with the correct comment
* symbol. Function does not check this.
* @param[in] count_comment Count of comments in the array. If 0
* the array is expected to be NULL terminated
* and function will traverse array until its end.
*
* @return 0 - Success.
* @return ENOENT - Section is not found.
* @return ENOMEM - No memory to add value.
* @return EINVAL - Invalid argument.
*/
int ini_config_comment_section(struct ini_cfgobj *ini_config,
const char *section,
const char *comments[],
size_t count_comment);
/**
* @brief Function to rename a section.
*
* Function finds a section and renames it.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to find.
* @param[in] newname New section name.
*
* @return 0 - Success.
* @return ENOENT - Section is not found.
* @return ENOMEM - No memory to add value.
* @return EINVAL - Invalid argument.
*/
int ini_config_rename_section(struct ini_cfgobj *ini_config,
const char *section,
const char *newname);
/**
* @brief Function to delete a section by name.
*
* Function is a convenience wrapper around
* \ref ini_config_delete_section_by_position function.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to delete.
*
* @return 0 - Success.
* @return ENOENT - Section is not found.
* @return ENOMEM - No memory to add value.
* @return EINVAL - Invalid argument.
*/
int ini_config_delete_section_by_name(struct ini_cfgobj *ini_config,
const char *section);
/**
* @brief Function to delete a section by position or name.
*
* Function allows removing a specific section by its relative position
* in the list of sections or by its name.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] position A constant that specifies the way the
* section should be deleted. For more information
* see "disposition constants" section of
* the collection interface. The value is used
* only in deletion so see the explanation
* in the "delete" paragraph.
* There can't be duplicate sections. However
* function respects all of the listed constants.
* To find and delete a particular section
* one can use COL_DSP_FIRSTDUP constant.
* One should just expect that there is only
* one instance of every section if any.
* @param[in] section Used in conjunction with position constant.
* In some cases it is convenient to add
* a section immediately before
* or after another value. While position defines
* where it should be added this parameter defines
* the section to relate to.
* @param[in] idx Index of the position.
* For example one can specify
* that the third section should be deleted.
*
* @return 0 - Success.
* @return ENOENT - Section is not found.
* @return ENOMEM - No memory to add value.
* @return EINVAL - Invalid argument.
*/
int ini_config_delete_section_by_position(struct ini_cfgobj *ini_config,
int position,
const char *section,
int idx);
/**
* @brief Function to a add string value to a particular section.
*
* Depending on the flags function adds, or deletes and adds, or just modifies
* the configuration value stored in the configuration object.
*
* NOTE: all other ini_config_add_xxx_value functions are implemented
* as wrappers around this function so they have same behavior and logic.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to modify.
* @param[in] key Key of the value to add or modify.
* @param[in] value String that represents value.
* @param[in] comments Array of comments. Can be NULL if no comment is
* needed for the value. It is expected that
* comment lines start with the correct comment
* symbol. Function does not check this.
* @param[in] count_comment Count of comments in the array. If 0
* the array is expected to be NULL terminated
* and function will traverse array until its end.
* @param[in] border The boundary the value should be wrapped at.
* The usual value is 80 characters.
* @param[in] position A constant that specifies the way the
* value should be added. For more information
* see "disposition constants" section of
* the collection interface. The value is used
* only in addition so see the explanation
* in the "insert" paragraph.
* @param[in] other_key Used in conjunction with position constant.
* In some cases it is convenient to add
* a value that should be placed immediately before
* or after another value. While position defines
* where it should be added this parameter defines
* the key to relate to.
* @param[in] idx Index in the whole section or among
* duplicates. For example one can specify
* that the value should be added as a third
* duplicate. This is convenient if INI file allows
* duplicate keys.
* @param[in] flags These constants define the main behavior of
* the function. The function can thus be used
* to build configuration object from scratch
* (in this case no checks would be needed),
* to modify a specific key which can be identified
* by index among duplicate keys in the same
* section. For more information see \ref insflags.
*
* @return 0 - Success.
* @return EEXIST - The value already exists.
* @return ENOENT - The value not found.
* @return ENOSYS - Unknown flag or position value.
* @return ENOMEM - No memory to add value.
* @return EINVAL - Invalid argument.
*/
int ini_config_add_str_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
const char *value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an integer value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an integer argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_int_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
int value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a long value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a long integer argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_long_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
long value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an unsigned long value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an unsigned long integer argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_ulong_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
unsigned long value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an unsigned value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an unsigned argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_unsigned_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
unsigned value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an int32 value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an int32 argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_int32_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
int32_t value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an uint32 value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an uint32 argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_uint32_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
uint32_t value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an int64 value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an int64 argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_int64_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
int64_t value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add an uint64 value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* an uint64 argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_uint64_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
uint64_t value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a double value to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a double argument for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_double_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
double value,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a binary value to a particular section.
*
* Binary values are represented by a HEX string where two HEX digits
* represent one byte of the source data. The value is surrounded
* by a pair of single quotes.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a void argument for the value input. The length of the data is specified by
* by the value_len argument.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_bin_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
void *value,
size_t value_len,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a value that consists of an array of strings
* to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a string array argument and a count for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_str_arr_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
const char *value_str_arr[],
size_t count_str,
char sep,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a value that consists of an array of integers
* to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a integer array argument and a count for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_int_arr_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
int *value_int_arr,
size_t count_int,
char sep,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a value that consists of an array of long integers
* to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a long integer array argument and a count for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_long_arr_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
long *value_long_arr,
size_t count_long,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to add a value that consists of an array of doubles
* to a particular section.
*
* Function is similar to \ref ini_config_add_str_value except it uses
* a double array argument and a count for the value input.
*
* For logic, behavior and return values see \ref ini_config_add_str_value.
*/
int ini_config_add_double_arr_value(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
double *value_double_arr,
size_t count_double,
const char *comments[],
size_t count_comment,
int border,
int position,
const char *other_key,
int idx,
unsigned flags);
/**
* @brief Function to delete a value.
*
* Function deletes a value specified either by key or by position.
* For example the caller can remove first or last key of the section as well
* as first, last or specific instance of a specific key. If key is searched
* by index and index is out of range the function would return ENOENT
* indicating that specifically requested key is not found.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to remove the key from.
* @param[in] position A constant that specifies the way the
* key should be removed. For more information
* see "disposition constants" section of
* the collection interface.See the "delete"
* paragraph for more information.
* @param[in] key Used in conjunction with position constant.
* Depending on the value of the position
* argument the key argument can specify
* the key to delete or the key that the delete
* operation should be relative to.
* @param[in] idx Index of duplicates. For example one can specify
* that he wants to delete the third duplicate
* of a specific key. If there are less duplicates,
* i.e. the index is out of range, the function
* will return ENOENT.
*
* @return 0 - Value was removed.
* @return ENOENT - The value not found.
*/
int ini_config_delete_value(struct ini_cfgobj *ini_config,
const char *section,
int position,
const char *key,
int idx);
/**
* @brief Function to update a comment.
*
* Function can be used to find and modify a comment for a specific
* key in a specific section.
*
* @param[in] ini_config Configuration object to modify.
* @param[in] section Name of the section to find the key.
* @param[in] key The key to find.
* @param[in] comments The array of comments. Can be NULL. If NULL,
* the existing comment will be removed if any.
* The comment lines are expected to start with a
* standard comment symbol.
* @param[in] count_comment Count of comments. If 0 the comment is
* constructed using array of strings above.
* It is expected to be NULL terminated.
* @param[in] idx Index of duplicates. For example one can specify
* that he wants to find the third duplicate
* of a specific key. If there are less duplicates,
* i.e. the index is out of range, the function
* will return ENOENT.
*
* @return 0 - Value was removed.
* @return ENOENT - The value not found.
*/
int ini_config_update_comment(struct ini_cfgobj *ini_config,
const char *section,
const char *key,
const char *comments[],
size_t count_comment,
int idx);
-------------- next part --------------
/*
COLLECTION LIBRARY
Header file for collection interface.
Copyright (C) Dmitri Pal <dpal at redhat.com> 2009
Collection 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 3 of the License, or
(at your option) any later version.
Collection 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 Collection Library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COLLECTION_H
#define COLLECTION_H
#include <stdint.h>
/** @mainpage The COLLECTION interface
* The collection is a set of items of different types.
*
* To better understand how collections work imagine travel bags.
* They usually come in different sizes and one can put a bag in a bag when
* they put away to the shelf in a garage or closet. Collection is such bag
* except that you can put other bags into each other even if they are not
* empty.<br>
* When you put items into a bag you do not see the contents of the bag.
* You just hold the bag. How many other bags inside this bag you do not know.
* But you might know that you put a "wallet" somewhere there.
* You ask the bag you hold: "find my wallet and give it to me".
* get_item function will return you the item that is your "wallet".
* You can then change something or just get information about the item you
* retrieved. But in most cases you do not need the wallet itself. You want to
* get something from the wallet or put something into it. IMO money would
* be an obvious choice. To do this you use update_xxx_property functions.<br>
* There might be a bag somewhere deep and you might want to add something to
* it. add_xxx_property_xxx functions allow you to specify sub collection you
* want the item to be added to. If this sub collection argument is NULL top
* level collection is assumed.<br>
* The search in the collections uses a "x!y!z" notation to refer to an item (or
* property). You can search for "wallet" and it will find any first instance of
* the "wallet" in your luggage. But you might have two wallets. One is yours and
* another is your significant other's. So you might say find "my!wallet".
* It will find wallet in your bag (collection) named "my". This collection can
* be many levels deep inside other collections. You do not need to know the
* full path to get to it. But if you have the full path you can use the fill
* path like this "luggage!newbags!my!wallet".<br>
* It is useful to be able to put bags into bags as well as get them out of each
* other. When the collection is created the header keeps a reference count on
* how many copies of the collection are known to the world. So one can put a
* collection into collection and give up its access to it (embed) or still hold
* to the reference. By embedding the collection the caller effectively gives
* up its responsibility to destroy the collection after it is used.<br>
* By extracting reference from an internal collection the caller gains access
* to the collection directly and thus has responsibility to destroy it after
* use.
*
* Internally collection is implemented as a link list rather than a hash
* table.
* This makes it suitable for small (dozens of items) sets of data for which
* the order is important. Thus the collection properties and sub collections
* can be used to model objects like a book case. Imagine a book case that
* consists of multiple shelves. You can perform operations like "add a new
* shelf after second shelf" or "put a book on the 4th shelf right before
* the book with the red cover."
*
* A bit of terminology:
* - <b>collection</b> - an object implemented as a link list that holds
* properties (attributes).
* - <b>property</b> - a named logical element of the collection.
* - <b>item</b> - physical element of the collection, think about it
* as a node in the link list.
* - <b>value</b> - data associated with the property.
* - <b>type</b> - type of the data associated with a property.
* - <b>length</b> - length of the data associated with the property.
* - <b>sub collection</b> - collection embedded into another collection.
* It is a property with the value of a special
* type. The name of the property that denotes
* a sub collection can be different from the name
* of the collection it refers to.
* - <b>traverse</b> - call a function that will internally iterate
* through a collection and do something with its
* elements.
* - <b>iterate</b> - step through a collection yourselves.
*
* Characters with codes less than space in ASCII table are illegal for
* property names.
* Character '!' also illegal in a property or collection name and
* reserved for "x!y!z" notation.
*
* There is always a header item in any collection that starts the collection.
* Most of the functions in the interface (unless explicitly stated otherwise)
* assume that the collection_item * argument points to the header element.
* Passing in elements extracted from the middle of a collection to functions
* that expect header elements is illegal. There might be not enough checking
* at the moment but this will be enforced in future versions of the library.
*
*/
#ifndef EOK
#define EOK 0
#endif
/**
* @defgroup collection COLLECTION interface
* @{
*/
/**
* @brief Default class for a free form collection.
*/
#define COL_CLASS_DEFAULT 0
/**
* @brief Value indicates that property is not found.
*
* Used in search functions.
*/
#define COL_NOMATCH 0
/**
* @brief Value indicates that property is found.
*
* Used in search functions.
*/
#define COL_MATCH 1
/**
* @defgroup coltypes Type definition constants
* @{
*/
/**
* @brief Indicates that property is of type "string".
*
* For elements of type string the length includes the trailing 0.
*/
#define COL_TYPE_STRING 0x00000001
/** @brief Indicates that property is of type "binary". */
#define COL_TYPE_BINARY 0x00000002
/** @brief Indicates that property is of type "integer". */
#define COL_TYPE_INTEGER 0x00000004
/** @brief Indicates that property is of type "unsigned". */
#define COL_TYPE_UNSIGNED 0x00000008
/** @brief Indicates that property is of type "long". */
#define COL_TYPE_LONG 0x00000010
/** @brief Indicates that property is of type "unsigned long". */
#define COL_TYPE_ULONG 0x00000020
/** @brief Indicates that property is of type "double". */
#define COL_TYPE_DOUBLE 0x00000040
/** @brief Indicates that property is of Boolean type. */
#define COL_TYPE_BOOL 0x00000080
/**
* @brief Indicates that property is of type "collection".
*
* The item of this type denotes that starting element of a
* collection.
*/
#define COL_TYPE_COLLECTION 0x00000100
/**
* @brief Indicates that property is of type "sub collection".
*
* An item of this type is a pointer to an existing external
* collection.
*/
#define COL_TYPE_COLLECTIONREF 0x00000200
/**
* @brief Special type that denotes the end of the collection.
*
* Useful when traversing collections.
*/
#define COL_TYPE_END 0x10000000
/**
* @brief Special type that denotes any property in the collection.
*
* Useful when traversing collection and searching for a property
* of unknown type but known name.
*/
#define COL_TYPE_ANY 0x0FFFFFFF
/**
* @}
*/
/**
* @defgroup addmodes Constants defining add modes
*
* The following constants define how one collection can be added to another.
*
* @{
*/
/** @brief Add a collection into a collection as a reference */
#define COL_ADD_MODE_REFERENCE 0
/**
* @brief Embed the collection into another collection.
*
* The collection will become part of another collection.
* After this operation the handle to the collection being added
* should not be used or freed.
* Embedding a collection can be done only once.
* If the collection is referenced by another collection,
* the operation will fail.
*/
#define COL_ADD_MODE_EMBED 1
/**
* @brief Perform a deep copy.
*
* Perform a deep copy of a collection with
* all its sub collections */
#define COL_ADD_MODE_CLONE 2
/**
* @brief Create a flattened copy.
*
* Create a deep copy of a collection with
* its sub collections flattening and NOT
* resolving duplicates.
*/
#define COL_ADD_MODE_FLAT 3
/**
* @brief Create a flattened copy with constructed names.
*
* Creates a deep copy of a collection with
* its sub collections flattening and NOT
* resolving duplicates. Names are constructed
* in dotted notation.
* For example the sub collection
* named "sub" containing "foo" and
* "bar" will be flattened as:
* "sub.foo", "sub.bar".
*/
#define COL_ADD_MODE_FLATDOT 4
/**
* @}
*/
/**
* @defgroup traverseconst Constants defining traverse modes
*
* The following constants define how a collection can be
* traversed or iterated.
*
* Flags defined below can generally be combined with each other.
*
* \ref COL_TRAVERSE_FLAT, \ref COL_TRAVERSE_SHOWSUB,
* \ref COL_TRAVERSE_ONLYSUB are mutually exclusive flags.
* If combined together results will be unpredictable.<br>
* <b>DO NOT MIX THEM IN ONE ITERATOR.</b>
*
*
* @{
*/
/** @brief Traverse all items in the collection. */
#define COL_TRAVERSE_DEFAULT 0x00000000
/**
* @brief Traverse only the top level.
*
* Traverse only top level
* ignored if the IGNORE flag is
* specified
*/
#define COL_TRAVERSE_ONELEVEL 0x00000001
/**
* @brief Insert end collection marker.
*
* Call the handler once more when the
* end of the collection is reached.
* Specifying this flag would cause a traversing
* function to call a callback once more passing
* in a virtual property of type \ref COL_TYPE_END.
* Good for processing nested collections.
*/
#define COL_TRAVERSE_END 0x00000002
/** @brief Ignore sub collections as if none is present. */
#define COL_TRAVERSE_IGNORE 0x00000004
/**
* @brief Flatten the collection.
*
* Traversing this way would act as if
* all the properties of sub collection are properties
* of the root collection. The referencing properties or
* headers of the referenced collections are skipped.
*
* If we think of the book case example
* this is very useful when one wants to iterate through
* all the books skipping information about
* which shelf they are on.
*/
#define COL_TRAVERSE_FLAT 0x00000008
/**
* @defgroup moreiterflag Additional iterator flags
*
* \note NOTE: These flags ignored by traverse functions and
* can be used only in the iterator.
*
* @{
*/
/**
* @brief Include headers of sub collections.
*
* When one collection is embedded or referenced by another collection
* there are two names we can be interested in. The name of the property
* that defines the reference and the name of the embedded collection.
* It is recommended that they be the same, however there may be cases
* when the name of the referencing property and referenced collection
* should be different. By default only the name of the referencing
* property is returned while iterating through the collection and
* its sub collections. Specifying this flag would cause the names
* of the collection (header elements) be included into the iteration
* process.
*
* Flag is ignored if the \ref COL_TRAVERSE_ONELEVEL flag is
* specified and not ignored.
* Flag is ignored is also ignored if the FLAT flag is specified. */
#define COL_TRAVERSE_SHOWSUB 0x00010000
/**
* @brief Show sub collections.
*
* Show the header of the sub collection instead of the reference.
* Flag is ignored if the \ref COL_TRAVERSE_ONELEVEL flag is
* specified and not ignored.
* Flag is ignored is also ignored if the FLAT flag is specified. */
#define COL_TRAVERSE_ONLYSUB 0x00020000
/**
* @}
*/
/**
* @}
*/
/**
* @defgroup copyconst Constants defining copy modes
*
* The following constants define modes accepted by copy
* collection function(s).
*
* @{
*/
/**
* @brief Perform a deep copy.
*
* Referenced collections of the donor are copied as sub
* collections.
*/
#define COL_COPY_NORMAL 0
/**
* @brief Perform a deep flat copy.
*
* Collection is flattened. No name construction performed.
*/
#define COL_COPY_FLAT 1
/**
* @brief Perform a deep flat copy constructing names.
*
* Collection is flattened. Names are concatenated with dot.
*/
#define COL_COPY_FLATDOT 2
/** @brief Perform a deep copy but leave references as references. */
#define COL_COPY_KEEPREF 3
/** @brief Copy only top level collection. */
#define COL_COPY_TOP 4
/**
* @}
*/
/**
* @defgroup sortconst Constants defining sort order
*
* All flags can be combined in OR operation.
* Flags \ref COL_SORT_ASC and \ref COL_SORT_DESC are
* mutually exclusive. If both specified the
* collection will be sorted in the descending order.
*
* @{
*/
/** @brief Sort in ascending order. */
#define COL_SORT_ASC 0x00000000
/** @brief Sort in descending order. */
#define COL_SORT_DESC 0x00000001
/** @brief Sort all sub collections. */
#define COL_SORT_SUB 0x00000002
/**
* @brief Sort only embedded sub collections.
*
* Ignored if \ref COL_SORT_SUB is not specified.
*/
#define COL_SORT_MYSUB 0x00000004
/**
* @}
*/
/* Public declaration of the private data */
#ifndef COLLECTION_PRIV_H
/**
* @struct collection_item
* @brief Opaque structure that holds one property.
*
* Your implementation can assume that following members
* will always be members of the collection_item.
* but you should use get_item_xxx functions to get them
* and never access internal data directly.
*
* - char *property;
* - int property_len;
* - int type;
* - int length;
* - void *data;
*/
struct collection_item;
/**
* @struct collection_iterator
* @brief Opaque iterator structure.
*
* The iterator structure is used
* when one wants to traverse the collection
* going through its properties and optionally
* sub collections.
*
* Caller should never assume
* anything about internals of this structure.
*/
struct collection_iterator;
#endif /* COLLECTION_PRIV_H */
/**
* @brief Create a collection
*
* The function will create a collection.
* Each collection should have name and class.
*
* @param[out] ci Newly allocated collection object.
* @param[in] name The name is supposed to be a unique identifier of
* the collection. This is useful when the collections
* are stored within other collections or inside other
* aggregation objects. Caller is free to use any name.
* Name should consist of the ASCII characters with codes
* non less than space. Exclamation mark character is
* a special character and can't be used in name of
* collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] cclass Class is used to relate the collection to a specific
* group of the collections of the same structure.
* This is very useful when you try to represent
* objects using collections and you want to check if
* the objects have same structure or not.
* There is no predefined name space for the collection
* classes. Defining classes is left to the application
* developers.<br>
* <b>NOTE:</b>
* If you decide to build an interface using collection
* library pick a range for the classes you are
* going to use and make sure that they do not collide
* with other interfaces built on top of the collection.
*
* @return 0 - Collection was created successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the collection name.
* @return EMSGSIZE - Collection name is too long.
*/
int col_create_collection(struct collection_item **ci,
const char *name,
unsigned cclass);
/**
* @brief Destroy a collection
*
* The function will destroy a collection.
*
* @param[in] ci Collection object.
*
*/
void col_destroy_collection(struct collection_item *ci);
/**
* @brief Cleanup Callback
*
* Signature of the callback that needs to be used when
* the collection is destroyed and a special cleanup operation
* is required for items in the collection.
*
* @param[in] property The name of the property will
* be passed in this parameter.
* @param[in] property_len Length of the property name
* will be passed in this parameter.
* @param[in] type Type of the data will be passed
* in this parameter.
* @param[in] data Pointer to the data will be passed
* in this parameter.
* @param[in] length Length of data will be passed in
* this parameter.
* @param[in] custom_data Custom data will be passed in
* this parameter.
*/
typedef void (*col_item_cleanup_fn)(const char *property,
int property_len,
int type,
void *data,
int length,
void *custom_data);
/**
* @brief Destroy a collection with callback
*
* Execute a provided callback for each item
* in the collection or subcollection immediately
* before freeing item. The callback is executed for each
* element including the collection header.
* It is the responsibility of the callback implementor
* to properly handle gifferent collection elements
* depending upon whether it is a header, reference to
* an embedded or external collection or a normal data
* element.
*
* The function will destroy a collection.
*
* @param[in] ci Collection object.
* @param[in] cb Cleanup callback.
* @param[in] custom_data Application data passed into
* the cleanup callback.
*
*/
void col_destroy_collection_with_cb(struct collection_item *ci,
col_item_cleanup_fn cb,
void *custom_data);
/**
* @brief Copy item callback.
*
* Callback is used by the
* \ref col_copy_collection_with_cb "col_copy_collection_with_cb" function.
* Function is called after the new item is created but not yet
* inserted into the target collection.
* The implementer of the callback can alter the item data
* or indicate to the caller that the item should be skipped.
*
* @param[in] item Newly allocated item that will be inserted
* into the new collection.
* @param[in] ext_data Data the application might want to
* pass to the callback.
* @param[out] skip Pointer to a variable that indicates if the
* item should be skipped or not.
* Set this variable to any nonzero value
* and the item will be skipped.
* @return 0 - Success
* @return Function can return any error code. This code
* will be propagated through the internal functions and
* returned to the application.
*
*/
typedef int (*col_copy_cb)(struct collection_item *item,
void *ext_data,
int *skip);
/**
* @brief Copy collection with data modification.
*
* Function create a deep copy of the current collection.
* Calls caller provided callback before copying each item's data.
* This is useful if the data needs to be resolved in some way.
* The best use is when the template is copied and the values
* in the template are resolved to the actual values.
* The acceptable modes are defined \ref copyconst "here".
*
* @param[out] col_copy Newly created collection object.
* @param[in] col_to_copy Collection object that will be copied.
* @param[in] name_to_use Name of the new collection.
* @param[in] copy_mode How to \ref copyconst "copy".
* @param[in] copy_cb Pointer to a callback \ref col_copy_cb.
* Can be NULL. In this case data is copied
* without modification.
* @param[in] ext_data Data the application might want to
* pass to the callback.
*
* @return 0 - Collection was copied successfully.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return Any error code returned by the callback.
*
*/
int col_copy_collection_with_cb(struct collection_item **col_copy,
struct collection_item *col_to_copy,
const char *name_to_use,
int copy_mode,
col_copy_cb copy_cb,
void *ext_data);
/**
* @brief Copy collection without data modification.
*
* Function creates a deep copy of the current collection.
* It wraps the \ref col_copy_collection_with_cb function.
* The acceptable modes are defined \ref copyconst "here".
*
* @param[out] col_copy Newly created collection object.
* @param[in] col_to_copy Collection object that will be copied.
* @param[in] name_to_use Name of the new collection.
* @param[in] copy_mode How to \ref copyconst "copy".
*
* @return 0 - Collection was copied successfully.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
*
*/
int col_copy_collection(struct collection_item **col_copy,
struct collection_item *col_to_copy,
const char *name_to_use,
int copy_mode);
/**
* @brief Add collection to collection.
*
* Function adds one collection into another
* depending upon a specified \ref addmodes "mode".
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add collection to. If NULL the collection
* is added to the root collection.
* @param[in] as_property Name of the property that will constitute
* the reference. If NULL the name of
* the collection being added will be used.
* If specified the restrictions to
* the name characters and length apply.
* For more details about the name related
* restrictions see
* \ref addproperty "col_add_xxx_property"
* functions.
* @param[in] ci_to_add Collection to add.
* @param[in] mode Specifies \ref addmodes "how"
* the collection should be added.
*
* @return 0 - Collection was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* The attempt to update a property which is
* a reference to a collection or a collection
* name.
* @return ENOENT - Property to update is not found.
*/
int col_add_collection_to_collection(struct collection_item *ci,
const char *subcollection,
const char *as_property,
struct collection_item *ci_to_add,
int mode);
/**
* @brief Search Callback
*
* Signature of the callback that needs to be used when
* traversing a collection or looking for a specific item.
*
* @param[in] property The name of the property will
* be passed in this parameter.
* @param[in] property_len Length of the property name
* will be passed in this parameter.
* @param[in] type Type of the data will be passed
* in this parameter.
* @param[in] data Pointer to the data will be passed
* in this parameter.
* @param[in] length Length of data will be passed in
* this parameter.
* @param[in] custom_data Custom data will be passed in
* this parameter.
* @param[out] stop Pointer to a variable where the handler
* can put nonzero to stop traversing
* of the collection.
* @return 0 - Success
* @return Function can return any error code. This code
* will be propagated through the internal functions and
* returned to the application.
*/
typedef int (*col_item_fn)(const char *property,
int property_len,
int type,
void *data,
int length,
void *custom_data,
int *stop);
/**
* @brief Traverse collection
*
* Function to traverse the entire collection
* including (optionally) sub collections.
*
* @param[in] ci Collection object to traverse.
* @param[in] mode_flags How to traverse.
* See details \ref traverseconst "here".
* @param[in] item_handler Application supplied callback.
* It will be called for each item
* in the collection including headers.
* @param[in] custom_data Custom data that application
* might want to pass to the callback.
*
* @return 0 - Collection was traversed successfully.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return Any error code returned by the callback.
*
*/
int col_traverse_collection(struct collection_item *ci,
int mode_flags,
col_item_fn item_handler,
void *custom_data);
/**
* @brief Search and do function.
*
* Looks up an item in the collection based on the property and type.
* Actually it is a traverse function with special traversing logic.
* It traverses the whole collection but calls the supplied
* callback only for the items that match the search criteria.
* It is the responsibility of the caller to define how the callback
* is going to indicate that the item it was looking for is 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.
*
* @param[in] ci Collection object to traverse.
* @param[in] property_to_find Name of the property to find.
* Parameter supports "x!y"
* notation.
* @param[in] type Type filter. Only properties
* of the given type will match.
* Can be 0 to indicate that all
* types should be evaluated.
* @param[in] mode_flags How to traverse the collection.
* See details \ref traverseconst "here".
* @param[in] item_handler Function to call when the item is found.
* @param[in] custom_data Custom data passed to the callback.
*
* @return 0 - Operation completed successfully.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - The search criteria is incorrect.
* @return ENOMEM - No memory.
* @return Any error code returned by the callback.
*
*/
int col_get_item_and_do(struct collection_item *ci,
const char *property_to_find,
int type,
int mode_flags,
col_item_fn item_handler,
void *custom_data);
/**
* @brief Search function to get an item.
*
* 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 returned 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.
* Working with the internals of the collection item structure directly
* may cause problems in future if the internal implementation changes.
* The caller needs to be aware that function does not return
* error if item is not found. The caller needs to check if
* item is not NULL to determine whether something was found.
* Internally function is a wrapper around the \ref col_get_item_and_do
* function.
*
* Use \ref getitem "item management" functions to work with the item.
*
* @param[in] ci Collection object to traverse.
* @param[in] property_to_find Name of the property to find.
* Parameter supports "x!y"
* notation.
* @param[in] type Type filter. Only properties
* of the given type will match.
* Can be 0 to indicate that all
* types should be evaluated.
* @param[in] mode_flags How to traverse the collection.
* See details \ref traverseconst "here".
* @param[in] item Pointer to found item or NULL
* if item is not found.
*
* @return 0 - No internal errors during search.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - The search criteria is incorrect.
* @return ENOMEM - No memory.
*
*/
int col_get_item(struct collection_item *ci,
const char *property_to_find,
int type,
int mode_flags,
struct collection_item **item);
/**
* @brief Search function to get one of the duplicate items.
*
* Convenience function to get an individual item out of the list of duplicates.
* Caller should be aware that this is not a copy of the item
* but the pointer to actual item stored in the collection.
* The returned 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.
* Working with the internals of the collection item structure directly
* may cause problems in future if the internal implementation changes.
* If collection to search or property to find is NULL function returns NULL.
*
* Use \ref getitem "item management" functions to work with the item.
*
* @param[in] ci Collection object to traverse.
* @param[in] subcollection Name of the sub collection to find
* item in. If NULL, the top level collection
* is used. One can use "foo!bar!baz"
* notation to identify the sub collection.
* @param[in] property_to_find Name of the property to find.
* @param[in] type Type filter. Only properties
* of the given type will match.
* Can be 0 to indicate that all
* types should be evaluated.
* @param[in] idx Index of the duplicate to find.
* 0 - any first instance
* positive - N-th instance (index is 0-based)
* negative - last instance
* @param[in] exact If 0 then if index above is greater than
* actual number of duplicates the last duplicate
* if be returned.
* If non-zero the funtion will return ENOENT
* in case the index is greater than actual
* number of duplicates.
* @return 0 No errors.
* @return EINVAL Invalid argument.
* @return ENOENT Item is not found.
*/
int col_get_dup_item(struct collection_item *ci,
const char *subcollection,
const char *property_to_find,
int type,
int idx,
int exact,
struct collection_item **item);
/**
* @brief Sort collection.
*
* If the sub collections are included in sorting
* each collection is sorted separately (this is not a global sort).
* It might be dangerous to sort sub collections if
* sub collection is not owned by the current collection.
* If it is a reference to an external collection
* there might be an issue. To skip the collections that
* externally referenced use \ref COL_SORT_MYSUB flag.
* Keep in mind that if a collection is referenced
* more than once by other collection and that collection
* is sorted with sub collections the referenced
* collection will be sorted more than once.
*
* NOTE: Current implementation of the sorting
* function is very simple and alternative
* implementations might be provided later.
*
* @param[in] col Collection to sort.
* @param[in] cmp_flags For more information see
* \ref compflags "comparison flags".
* @param[in] sort_flags For more information see
* \ref sortconst "sort flags".
*
* @return 0 - No internal errors during sorting.
* @return EINVAL - The value of some of the arguments is invalid.
*
*/
int col_sort_collection(struct collection_item *col,
unsigned cmp_flags,
unsigned sort_flags);
/**
* @brief Delete property.
*
* Delete property from the collection.
* It is recommended to use a more efficient function
* \ref col_remove_item for the same purpose if
* the property is unique or if the collection
* has a known structure.
* The col_delete_property function has some advantage only
* if it is not known where property
* resides and what is the structure of the collection.
* In this case "foo!bar!baz" notation can be used in
* the property_to_find argument to find and delete
* the property "baz" that is in a sub collection "bar"
* which is in turn a part of a collection "foo".
*
* @param[in] ci Collection to delete property from.
* @param[in] property_to_find Property to delete.
* @param[in] type Use type if names are not unique
* and you know the type of the value
* you want to delete. Otherwise set to 0.
* @param[in] mode_flags The flags define how the collection
* should be searched. For more information
* see \ref traverseconst "traverse constants".
*
* @return 0 - Property was deleted successfully.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOMEM - No memory.
* @return ENOENT - Property not found.
*
*/
int col_delete_property(struct collection_item *ci,
const char *property_to_find,
int type,
int mode_flags);
/**
* @brief Is property in the collection?
*
* Convenience function to check if the property
* is indeed in the collection.
*
* @param[in] ci Collection to search.
* @param[in] property_to_find Property to find.
* @param[in] type Use type if names are not unique
* and you know the type of the value
* you want to check. Otherwise set to 0.
* @param[in] mode_flags The flags define how the collection
* should be searched. For more information
* see \ref traverseconst "traverse constants".
* @param[out] found The variable that will receive the result
* of the search.
* COL_NOMATCH - if not found
* COL_MATCH if found
*
* @return 0 - Search completed successfully.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOMEM - No memory.
*
*/
int col_is_item_in_collection(struct collection_item *ci,
const char *property_to_find,
int type,
int mode_flags,
int *found);
/**
* @brief Get a reference to a collection
*
* Get a pointer to a collection included into another collection.
* If the col_to_find is NULL function returns a reference
* to the top level collection.
* Delete extracted collection after use to decrease reference count.
*
* @param[in] ci Collection to search.
* @param[out] acceptor Variable that accepts pointer to
* an extracted collection.
* Use \ref col_destroy_collection to
* free returned object reference after
* use.
* @param[in] col_to_find Collection to find.
* "foo!bar!baz" notation can be used.
*
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOMEM - No memory.
*/
int col_get_collection_reference(struct collection_item *ci,
struct collection_item **acceptor,
const char *col_to_find);
/**
* @brief Get a reference from the item
*
* Get a pointer to a collection from a current item
* if current item is a reference to the collection.
* If current item is not a reference to a collection an error
* will be returned.
* Delete extracted collection after use to decrease reference count.
*
* @param[in] item Item to extract the reference from.
* @param[out] acceptor Variable that accepts pointer to
* an extracted collection.
* Use \ref col_destroy_collection to
* free returned object reference after
* use.
*
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
*/
int col_get_reference_from_item(struct collection_item *item,
struct collection_item **acceptor);
/**
* @brief Get collection class.
*
* The classes of the collections can be used to convey information
* about the collection's internal structure.
* Some interfaces built on top of the collection might
* impose restrictions on the collection structure.
* For example the interface can decide that it is going
* to deal with the collections that do not have sub collections
* and elements of the collections are always only strings.
* So the interface will define a class of the collection
* and create a function that would take the strings and create
* such a collection. Then other functions of that interface
* would check if the provided collection is of the specified class.
* If not the interface would reject the collection right away.
* If the collection is of the valid class the interface might
* call the validation function to make sure that this is really
* the case however it needs to validate it only once and lower level
* functions can rely on the class value of the collection
* without performing duplicate validation.
*
* @param[in] ci Collection object.
* @param[out] cclass Variable that will receive
* the value of the class.
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
*
*/
int col_get_collection_class(struct collection_item *ci,
unsigned *cclass);
/**
* @brief Set collection class.
*
* Sometimes as a result of the collection modification
* the class of the collection can change.
*
* @param[in] ci Collection object.
* @param[in] cclass New class value.
*
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
*
*/
int col_set_collection_class(struct collection_item *ci,
unsigned cclass);
/**
* @brief Get count of the elements.
*
* It is useful to know how many items are there in the collection.
*
* @param[in] ci Collection object.
* @param[out] count Variable will receive the value
* of the number of the items in
* the collection. Collection
* header or references to external
* collections are counted as well.
* This means that every collection
* has at least one item - the header.
*
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
*
*/
int col_get_collection_count(struct collection_item *ci,
unsigned *count);
/**
* @brief Check the class of collection.
*
* Convenience function to check if the collection is of the specific class.
* In case of internal error assumes that collection is not of the right class.
*
* @param[in] ci Collection object.
* @param[in] cclass Class value to compare to to.
*
* @return 0 - If any internal error or classes do not match.
* @return 1 - No error and classes do match.
*
*/
int col_is_of_class(struct collection_item *ci,
unsigned cclass);
/**
* @defgroup addproperty Add property functions
*
* Functions in this section add properties to a collection.
*
* All the functions in this section add a property of the specified
* type to the collection object.
* They are convenience wrappers around the col_insert_xxx_property
* functions.
* They always append property to the end of the collection.
*
* Common parameters for these functions are:
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
* @{
*/
/**
* @brief Add a string property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] string Null terminated string to add.
* @param[in] length Length of the string. Should include the length
* of the terminating 0.
* If the length is shorter than the full string
* the string will be truncated. If the length is
* longer than the actual string there might be
* garbage at end of the actual string.
* Library will always properly NULL terminate
* the string at the given position dictated
* by length but in no way will inspect the validity
* of the passed in data. This is left to the calling
* application.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_str_property(struct collection_item *ci,
const char *subcollection,
const char *property,
const char *string,
int length);
/**
* @brief Add a binary property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] binary_data Data to add.
* @param[in] length Length of the data.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_binary_property(struct collection_item *ci,
const char *subcollection,
const char *property,
void *binary_data,
int length);
/**
* @brief Add an integer property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Integer value to add. Value is signed.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_int_property(struct collection_item *ci,
const char *subcollection,
const char *property,
int32_t number);
/**
* @brief Add an unsigned integer property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Unsigned integer value to add.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_unsigned_property(struct collection_item *ci,
const char *subcollection,
const char *property,
uint32_t number);
/**
* @brief Add an long property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Long integer value to add. Value is signed.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_long_property(struct collection_item *ci,
const char *subcollection,
const char *property,
int64_t number);
/**
* @brief Add an unsigned long property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Unsigned long integer value to add.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_ulong_property(struct collection_item *ci,
const char *subcollection,
const char *property,
uint64_t number);
/**
* @brief Add a property of type double to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Floating point value.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_double_property(struct collection_item *ci,
const char *subcollection,
const char *property,
double number);
/**
* @brief Add a Boolean property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] logical Boolean value. 0 - false, nonzero - true.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_bool_property(struct collection_item *ci,
const char *subcollection,
const char *property,
unsigned char logical);
/**
* @brief Add a property of a specified type to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] type See type definitions \ref coltypes "here".
* @param[in] data Data to add.
* @param[in] length Length of the data.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_any_property(struct collection_item *ci,
const char *subcollection,
const char *property,
int type,
void *data,
int length);
/**
* @defgroup addprop_withref Add properties with reference
*
* Family of functions that add properties to a collection
* and return reference to an item that holds
* a newly created property.
*
* All the functions in this section append a property of
* the specified type to the collection object.
*
* Parameters for the functions and return values are the same
* as for the \ref addproperty "col_add_xxx_property" functions.
* The only difference is that these functions have one additional
* argument:
*
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @{
*/
/**
* @brief Add a string property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] string Null terminated string to add.
* @param[in] length Length of the string. Should include the length
* of the terminating 0.
* If the length is shorter than the full string
* the string will be truncated. If the length is
* longer than the actual string there might be
* garbage at end of the actual string.
* Library will always properly NULL terminate
* the string at the given position dictated
* by length but in no way will inspect the validity
* of the passed in data. This is left to the calling
* application.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_str_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property,
char *string, int length,
struct collection_item **ret_ref);
/**
* @brief Add a binary property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] binary_data Data to add.
* @param[in] length Length of the data.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_binary_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property,
void *binary_data, int length,
struct collection_item **ret_ref);
/**
* @brief Add an integer property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Integer value to add. Value is signed.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_int_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property, int32_t number,
struct collection_item **ret_ref);
/**
* @brief Add an unsigned integer property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Unsigned integer value to add.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_unsigned_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property, uint32_t number,
struct collection_item **ret_ref);
/**
* @brief Add an long property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Long integer value to add. Value is signed.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_long_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property, int64_t number,
struct collection_item **ret_ref);
/**
* @brief Add an unsigned long property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Unsigned long integer value to add.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_ulong_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property, uint64_t number,
struct collection_item **ret_ref);
/**
* @brief Add a property of type double to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] number Floating point value.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_double_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property, double number,
struct collection_item **ret_ref);
/**
* @brief Add a Boolean property to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] logical Boolean value. 0 - false, nonzero - true.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_bool_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property, unsigned char logical,
struct collection_item **ret_ref);
/**
* @brief Add a property of a specified type to a collection.
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
* @param[in] type See type definitions \ref coltypes "here".
* @param[in] data Data to add.
* @param[in] length Length of the data.
* @param[out] ret_ref Reference to the newly added item that
* holds the property.
*
* @return 0 - Property was added successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection is not found.
*
*/
int col_add_any_property_with_ref(struct collection_item *ci,
const char *subcollection,
const char *property,
int type, void *data, int length,
struct collection_item **ret_ref);
/**
* @}
*/
/**
* @}
*/
/**
* @defgroup insertproperty Insert property functions
*
* Functions in this section insert properties into a collection
* at a specified position.
*
* Common parameters for these functions are:
*
* @param[in] ci Root collection object.
* @param[in] subcollection Name of the inner collection to
* add property to. If NULL the property
* is added to the root collection.
* @param[in] disposition Defines relation point.
* For more information see
* \ref dispvalues "disposition defines".
* @param[in] refprop Property to relate to
* @param[in] idx Index (see comments below).
* @param[in] flags Flags that control naming issues.
* @param[in] property Name of the property.<br>
* Name should consist of the ASCII characters
* with codes non less than space.
* Exclamation mark character is
* a special character and can't be used
* in name of collection or property.<br>
* Maximum allowed length is defined at compile time.
* The default value is 64k.
*
*
* Other arguments are the same as the arguments for the
* \ref addproperty "col_add_xxx_property" functions.
*
* @return 0 - Property was insterted successfully.
* @return ENOMEM - No memory.
* @return EINVAL - Invalid characters in the property name.
* Value argument is invalid in some way.
* @return EMSGSIZE - Property name is too long.
* @return ENOENT - Sub collection or property to relate to is not found.
* @return EEXIST - Property with given name already exists.
* This error is returned if collection
* should hold unique names.
* For more information see description of the
* "flags" argument.
* @return ENOSYS - Flag or disposition value is not implemented.
* @{
*/
/** @brief Insert a string property. */
int col_insert_str_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
const char *string,
int length);
/** @brief Insert a binary property. */
int col_insert_binary_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
void *binary_data,
int length);
/** @brief Insert an integer property. */
int col_insert_int_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
int32_t number);
/** @brief Insert an unsigned property. */
int col_insert_unsigned_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
uint32_t number);
/** @brief Insert a long property. */
int col_insert_long_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
int64_t number);
/** @brief Insert an unsigned long property. */
int col_insert_ulong_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
uint64_t number);
/** @brief Insert a property with a floating point value. */
int col_insert_double_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
double number);
/** @brief Insert a property with a Boolean value. */
int col_insert_bool_property(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
unsigned char logical);
/** @brief Insert a string property and get back a reference. */
int col_insert_str_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
const char *string,
int length,
struct collection_item **ret_ref);
/** @brief Insert a binary property and get back a reference. */
int col_insert_binary_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
void *binary_data,
int length,
struct collection_item **ret_ref);
/** @brief Insert an integer property and get back a reference. */
int col_insert_int_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
int32_t number,
struct collection_item **ret_ref);
/** @brief Insert an unsigned property and get back a reference. */
int col_insert_unsigned_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
uint32_t number,
struct collection_item **ret_ref);
/** @brief Insert a long property and get back a reference. */
int col_insert_long_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
int64_t number,
struct collection_item **ret_ref);
/** @brief Insert an unsigned long property and get back a reference. */
int col_insert_ulong_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
uint64_t number,
struct collection_item **ret_ref);
/**
* @brief Insert a property with a floating
* point value and get back a reference.
*/
int col_insert_double_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
double number,
struct collection_item **ret_ref);
/** @brief Insert a property with a Boolean value and get back a reference. */
int col_insert_bool_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
unsigned char logical,
struct collection_item **ret_ref);
/** @brief Insert property of any type and get back a reference. */
int col_insert_property_with_ref(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
unsigned flags,
const char *property,
int type,
const void *data,
int length,
struct collection_item **ret_ref);
/**
* @}
*/
/**
* @defgroup updateproperty Update property functions
*
* Functions in this section update properties in a collection.
*
* All update functions search the property using the
* internal traverse function.
* Use same "x!y" notation to specify a property.
* For more details about the search logic see
* \ref col_get_item_and_do function.
*
* The existing value of the property is destroyed and lost.
*
* It is not possible to rename the property using these functions.
* To do more advanced modifications see \ref col_modify_item function
* and \ref modwrap "item modification wrappers" .
*
* Common parameters for these functions are:
*
* @param[in] ci Root collection object.
* @param[in] property Name of the property.
* @param[in] mode_flags Specify how the collection
* should to be traversed.
*
* The rest of the arguments specify the new values for
* the property. For more details about these arguments see
* the description of the \ref addproperty "col_add_xxx_property"
* corresponding function.
*
*
* @return 0 - Property was updated successfully.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* The attempt to update a property which is
* a reference to a collection or a collection
* name.
* @return ENOENT - Property to update is not found.
*
* @{
*/
/**
* Update a property with a string value.
* Length should include the terminating 0.
*/
int col_update_str_property(struct collection_item *ci,
const char *property,
int mode_flags,
char *string,
int length);
/**
* Update a property with a binary value.
*/
int col_update_binary_property(struct collection_item *ci,
const char *property,
int mode_flags,
void *binary_data,
int length);
/**
* Update a property with an integer value.
*/
int col_update_int_property(struct collection_item *ci,
const char *property,
int mode_flags,
int32_t number);
/**
* Update a property with an unsigned value.
*/
int col_update_unsigned_property(struct collection_item *ci,
const char *property,
int mode_flags,
uint32_t number);
/**
* Update a property with a long value.
*/
int col_update_long_property(struct collection_item *ci,
const char *property,
int mode_flags,
int64_t number);
/**
* Update a property with an unsigned long value.
*/
int col_update_ulong_property(struct collection_item *ci,
const char *property,
int mode_flags,
uint64_t number);
/**
* Update a property with a floating point value.
*/
int col_update_double_property(struct collection_item *ci,
const char *property,
int mode_flags,
double number);
/**
* Update a property with a Boolean value.
*/
int col_update_bool_property(struct collection_item *ci,
const char *property,
int mode_flags,
unsigned char logical);
/**
* Update a property with a value by specifying type
* and value. See definitions of the type constants
* \ref coltypes "here".
* All other col_update_xxx_property functions are wrappers
* around this one.
*/
int col_update_property(struct collection_item *ci,
const char *property,
int type,
void *new_data,
int length,
int mode_flags);
/**
* @}
*/
/**
* @defgroup getitem Item management
*
* Group of functions that allows retrieving individual elements
* of the \ref collection_item hiding the internal implementation.
*
* @{
*/
/**
* @defgroup compflags Comparison flags
*
* This section describes the flags used in item comparison.
*
* Flags:
* - \ref COL_CMPIN_PROP_EQU
* - \ref COL_CMPIN_PROP_BEG
* - \ref COL_CMPIN_PROP_MID
* - \ref COL_CMPIN_PROP_END
*
* are mutually exclusive.
*
* All other flags can be provided in any combination.
*
* @{
*/
/** @brief Properties should be exactly equal */
#define COL_CMPIN_PROP_EQU 0x000000004
/** @brief Properties should start with the same substring. */
#define COL_CMPIN_PROP_BEG 0x000000005
/** @brief One property should be a substring of another. */
#define COL_CMPIN_PROP_MID 0x000000006
/** @brief Properties should have the same substring at the end. */
#define COL_CMPIN_PROP_END 0x000000007
/**
* @brief Make sure that there is a dot.
*
* Useful with _BEG, _MID and _END flags to check that the there is
* a dot (if present) in the right place (before, after or both).
* For example the first item is named "foo.bar" and the second
* is "bar". Using _END the "bar" will be found but if _DOT flag is
* used too the function will also check if there was a "." before the found
* string in this case.
* Ignored in case of _EQU.
*/
#define COL_CMPIN_PROP_DOT 0x000000008
/** @brief Compare property lengths. */
#define COL_CMPIN_PROP_LEN 0x000000010
/** @brief Compare types. */
#define COL_CMPIN_TYPE 0x000000020
/** @brief Compare data lengths. */
#define COL_CMPIN_DATA_LEN 0x000000040
/**
* @brief Compare data.
*
* Compares data (up to the length of the second one)
* if type is the same. If type is different
* function will assume data is different
* without performing actual comparison.
*/
#define COL_CMPIN_DATA 0x000000080
/**
* @}
*/
/**
* @defgroup outflags Comparison results flags
*
* This section describes the flags set as a result of
* a comparison operation.
*
* @{
*/
/**
* @brief Second item's property is greater.
*
* If _EQU was specified and the property of the second item
* is greater the following bit will be set
*/
#define COL_CMPOUT_PROP_STR 0x00000001
/**
* @brief Second item's property is longer.
*
* If told to compare property lengths
* and the second is longer this bit will be set.
*/
#define COL_CMPOUT_PROP_LEN 0x00000002
/**
* @brief Second item's data is longer.
*
* If told to compare data lengths
* and second is longer this bit will be set
*/
#define COL_CMPOUT_DATA_LEN 0x00000004
/**
* @brief Second item's data is greater.
*
* If told to compare data
* and types are the same, then
* if the second one is greater this bit will
* be set. If data is binary flag is never set.
*/
#define COL_CMPOUT_DATA 0x00000008
/**
* @}
*/
/**
* @defgroup dispvalues Disposition constants
*
* Possible dispositions for insert, extract and delete function(s).
* Not all of these dispositions are implemented day one.
* If disposition is not implemented the function
* will return error ENOSYS.
*
* Other dispositions might be possible in future.
*
* @{
*/
/**
* @brief Relate to the end of the collection
*
* For "insert":
* - Add property to the end of the collection.
*
* For "extract" or "delete":
* - Extract or delete the last property in the collection.
*/
#define COL_DSP_END 0
/**
* @brief Relate to the beginning of the collection
*
* For "insert":
* - Add property to the beginning of the collection right after the header.
*
* For "extract" or "delete":
* - Extract or delete the first property in the collection.
* This is the one right after the header.
*/
#define COL_DSP_FRONT 1
/**
* @brief Before the given property
*
* For "insert":
* - Add property before the referenced property.
*
* For "extract" or "delete":
* - Extract or delete the property that stands
* before the referenced property in the collection.
* If given property is the first in the collection
* ENOENT is returned.
*/
#define COL_DSP_BEFORE 2
/**
* @brief After the given property
*
* For "insert":
* - Add property immediately the referenced property.
*
* For "extract" or "delete":
* - Extract or delete the property that stands
* after the referenced property in the collection.
* If given property is the last in the collection
* ENOENT is returned.
*/
#define COL_DSP_AFTER 3
/**
* @brief Use index
*
* For "insert":
* - The COL_DSP_INDEX adds the item as N-th item after header in the list.
* Index is zero based.
* If there are less than N items in the list the item is added to the end.
* The index value of 0 means that the item will be added immediately
* after the header. Index of 1 will mean that it is added after first data
* item and so on.
*
* For "extract" or "delete":
* - In case of extraction or deletion the N-th item of the collection
* will be extracted or deleted.
* Index is zero based.
* If there are less than N+1 items in the list the function will return ENOENT.
*
*/
#define COL_DSP_INDEX 4
/**
* @brief Use first among duplicates
*
* This mode applies only to the list of duplicate
* properties that are going one after another.
*
* For "insert":
* - Add property as a first dup of the given property.
* The property name is taken from the item
* and the value refprop is ignored.
*
* For "extract" or "delete":
* - Delete or extract first duplicate property.
* The property name is taken from the refprop.
* The property will be extracted or deleted if found
* regardless of whether there are any duplicates or not.
*/
#define COL_DSP_FIRSTDUP 5
/**
* @brief Use last among duplicates
*
* This mode applies only to the list of duplicate
* properties that are going one after another.
*
* For "insert":
* - Add property as the last dup of the given property.
* The property name is taken from the item
* and the value refprop is ignored.
*
* For "extract" or "delete":
* - Delete or extract the last duplicate of the property.
* The property name is taken from the refprop.
* Extracts or deletes last duplicate property in the uninterrupted
* sequence of properties with the same name.
* The property will be extracted or deleted if found
* regardless of whether there are any duplicates or not.
*/
#define COL_DSP_LASTDUP 6
/**
* @brief Use N-th among duplicates
*
* This mode applies only to the list of duplicate
* properties that are going one after another.
*
* For "insert":
* - Add property as a N-th dup of the given property.
* The property name is taken from the item
* and the value refprop is ignored.
* Index is zero based.
* The COL_DSP_NDUP is used in case of the multi value property
* to add a new property with the same name into specific place
* in the list of properties with the same name.
* The index of 0 will mean to add the property before the first
* instance of the property with the same name.
* If the property does not exist ENOENT will be returned.
* If the index is greater than the last property with the same
* name the item will be added immediately after last
* property with the same name.
*
* For "extract" or "delete":
* - Delete or extract N-th duplicate property.
* Index is zero based.
* The property name is taken from the refprop.
* If index is greater than number of duplicate
* properties in the sequence ENOENT is returned.
*
*/
#define COL_DSP_NDUP 7
/**
* @brief Use last among nonsequential duplicates
*
* This mode applies to the list of duplicates that might be scattered
* across the collection
*
* For "insert":
* - Add property as the last dup of the given property.
* The property name is taken from the item
* and the value refprop is ignored.
*
* For "extract" or "delete":
* - Delete or extract the last duplicate of the property.
* The property name is taken from the refprop.
* Extracts or deletes last duplicate property in the uninterrupted
* sequence of properties with the same name.
* The property will be extracted or deleted if found
* regardless of whether there are any duplicates or not.
*/
#define COL_DSP_LASTDUPNS 8
/**
* @brief Use N-th among nonsequential duplicates
*
* This mode applies only to the list of duplicate
* properties that are going one after another.
*
* For "insert":
* - Add property as a N-th dup of the given property.
* The property name is taken from the item
* and the value refprop is ignored.
* Index is zero based.
* The COL_DSP_NDUPNS is used in case of the multi value property
* to add a new property with the same name into specific place
* in the list of properties with the same name.
* The index of 0 will mean to add the property before the first
* instance of the property with the same name.
* If the property does not exist ENOENT will be returned.
* If the index is greater than the last property with the same
* name the item will be added immediately after last
* property with the same name.
*
* For "extract" or "delete":
* - Delete or extract N-th duplicate property.
* Index is zero based.
* The property name is taken from the refprop.
* If index is greater than number of duplicate
* properties in the sequence ENOENT is returned.
*
*/
#define COL_DSP_NDUPNS 9
/**
* @}
*/
/**
* @defgroup insflags Flags used in insert item functions
*
* Flags that can be used with insert functions.
*
* In future can more flags might be added.
*
* <b>NOTE:</b> Use of the duplicate checking flags is costly
* since it requires a forward look up of the whole
* collection before the item is inserted.
* Do not use it until it is absolutely necessary.
*
* @{
*/
/** @brief This is the default mode - no dup checks on insert */
#define COL_INSERT_NOCHECK 0
/**
* @brief Check for duplicate name and overwrite.
* Position arguments are ignored.
*/
#define COL_INSERT_DUPOVER 1
/**
* @brief Check for duplicate name and type and overwrite.
* Position arguments are ignored.
*/
#define COL_INSERT_DUPOVERT 2
/** @brief Return error EEXIST if the entry with the same name exists. */
#define COL_INSERT_DUPERROR 3
/**
* @brief Return error EEXIST if the entry
* with the same name and type exists.
*/
#define COL_INSERT_DUPERRORT 4
/** @brief Check for duplicates, overwrite,
* extract and then move to the position requested.
*/
#define COL_INSERT_DUPMOVE 5
/** @brief Check for duplicate name and type, overwrite,
* extract and then move to the position requested.
*/
#define COL_INSERT_DUPMOVET 6
/**
* @}
*/
/**
* @brief Get item property.
*
* Get name of the property from the item. If the item is a header
* the name of the property is the name of the collection.
* The element that denotes the collection header has
* type \ref COL_TYPE_COLLECTION.
* Optionally the property length can be retrieved too.
*
* @param[in] ci Item to get property from.
* If item is invalid the function
* will cause a segment violation.
* @param[out] property_len If not NULL the variable
* will receive the length
* of the property not counting
* terminating 0.
*
* @return Property name.
*
*/
const char *col_get_item_property(struct collection_item *ci,
int *property_len);
/**
* @brief Get item type.
*
* Get type from the item.
*
* @param[in] ci Item to get type from.
* If item is invalid the function
* will cause a segment violation.
*
* @return Item type.
*
*/
int col_get_item_type(struct collection_item *ci);
/**
* @brief Get value length from the item.
*
* Get value length from the item. For strings this includes
* NULL terminating zero.
*
* @param[in] ci Item to get value length from.
* If item is invalid the function
* will cause a segment violation.
*
* @return Value length.
*
*/
int col_get_item_length(struct collection_item *ci);
/**
* @brief Get value from the item.
*
* Get value from the item.
*
* @param[in] ci Item to get value from.
* If item is invalid the function
* will cause a segment violation.
*
* @return Property value.
*
*/
void *col_get_item_data(struct collection_item *ci);
/**
* @brief Get hash value from the item.
*
* Get hash value from the item. The hash value is
* 64-bit hash created from the property name.
* It is done to optimize the searches.
*
* This function is exposed for some corner cases
* that require low level operations, for example
* for custom search callbacks to take advantage
* of the internal hashes.
*
* @param[in] ci Item to get hash from.
* If item is invalid the function
* will cause a segment violation.
*
* @return Hash value.
*
*/
uint64_t col_get_item_hash(struct collection_item *ci);
/**
* @brief Calculate hash value for a string.
*
* Calculates hash value of the string using internal hashing
* algorithm. Populates "length" with length
* of the string not counting 0.
*
* This function is useful if you want to build a custom
* search or collection sorting function.
*
* @param[in] string String to hash. If NULL hash is 0.
* @param[in] sub_len If it is greater than zero
* it is used to count how many
* characters from string should
* be included into hash calculation.
* If 0 the actual length of the string
* is determined and used.
* @param[out] length Will receive the calculated length
* of the provided string.
* Length argument can be NULL.
*
* @return Hash value.
*/
uint64_t col_make_hash(const char *string, int sub_len, int *length);
/**
* @brief Compare two items.
*
* The second item is evaluated against the first.
* Function returns 0 if two items are the same
* and non-zero otherwise.
* The \ref compflags "in_flags" is a bit mask that
* defines how the items should be compared.
*
* If items are different they might be sorted following
* some order. For example one can order items by name
* but not by type.
* If the result of the function is non-zero
* the \ref outflags "out_flags" (if provided) will be
* set to indicate if the second item is greater
* then the first.
*
* @param[in] first First item to compare.
* @param[in] second Second item to compare.
* @param[in] in_flags See \ref compflags "comparison flags".
* @param[out] out_flags See \ref outflags "output flags".
*
*
* @return 0 if items are the same and nonzero otherwise.
*/
int col_compare_items(struct collection_item *first,
struct collection_item *second,
unsigned in_flags,
unsigned *out_flags);
/**
* @brief Modify any item element.
*
* This function is useful if you want to modify the item that
* you got as a result of \ref iterfunc "iterating" through
* collection or by calling \ref col_get_item.
* Previous type and data of the item is destroyed.
*
* If you want to rename an item provide a new name in the property
* argument otherwise keep it NULL.
*
* If you want the data to remain unchanged use 0 as a length parameter.
*
* If item is a reference or a collection the call will return an error.
*
* The are several convenience function that are wrappers
* around this function. For more information
* see \ref modwrap "item modification wrappers".
*
* @param[in] item Item to modify.
* @param[in] property Property name. Use NULL to leave the property
* unchanged.
* @param[in] type See \ref coltypes "types" for more information.
* @param[in] data New value.
* @param[in] length New value. Use 0 to leave the value and its type
* unchanged.
*
* @return 0 - Item was successfully modified.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* The attempt to modify an item which is
* a reference to a collection or a collection
* name.
*/
int col_modify_item(struct collection_item *item,
const char *property,
int type,
const void *data,
int length);
/**
* @defgroup modwrap Item modification wrappers
*
* The functions in this section are convenience wrappers
* around \ref col_modify_item.
* They return same error codes.
*
* @{
*/
/**
* @brief Modify item property.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It is equivalent to: col_modify_item(item, property, 0, NULL, 0);
*
*/
int col_modify_item_property(struct collection_item *item,
const char *property);
/**
* @brief Modify item value to be a string.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided string.
* If property is not NULL it also renames the property.
* If the length argument is not zero the string will be truncated to
* this length. If the length is 0 the length will be calculated based
* on the length of the actual string.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_str_item(struct collection_item *item,
const char *property,
const char *string,
int length);
/**
* @brief Modify item value to be a binary blob.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided binary buffer.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_binary_item(struct collection_item *item,
const char *property,
void *binary_data,
int length);
/**
* @brief Modify item value to be a Boolean.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided logical value.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_bool_item(struct collection_item *item,
const char *property,
unsigned char logical);
/**
* @brief Modify item value to be an integer.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided integer value.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_int_item(struct collection_item *item,
const char *property,
int32_t number);
/**
* @brief Modify item value to be a long integer.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided long integer value.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_long_item(struct collection_item *item,
const char *property,
int64_t number);
/**
* @brief Modify item value to be an unsigned long.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided unsigned long value.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_ulong_item(struct collection_item *item,
const char *property,
uint64_t number);
/**
* @brief Modify item value to be an unsigned integer.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided unsigned integer value.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_unsigned_item(struct collection_item *item,
const char *property,
uint32_t number);
/**
* @brief Modify item value to be a floating point.
*
* This function is a convenience wrapper around \ref col_modify_item.
* It sets a value of the item to a provided floating point value.
* If property is not NULL it also renames the property.
* Original value is always destroyed.
*
* @return - same error values as \ref col_modify_item.
*/
int col_modify_double_item(struct collection_item *item,
const char *property,
double number);
/**
* @}
*/
/**
* @brief Extract item from the collection.
*
* Function to find and remove an item from the collection.
* Function does not destroy the item instead it returns a reference
* to the item so it can be used later and inserted back into this or
* other collection.
* The function assumes that the caller knows the collection
* the property is stored in.
* The header of the collection can't be extracted with this function
* but the reference to the collection can.
*
* Function allows specifying relative position of the item in the
* collection. One can specify that he wants to extract an item
* that is first in the collection or last, or after other item
* in the collection. For more details see parameter definitions.
*
* After extracting the item from the collection the caller has to
* either insert it back into some collection using \ref col_insert_item
* or delete it using \ref col_delete_item.
*
*
* @param[in] ci Collection object.
* @param[in] subcollection Name of the sub collection to extract
* item from. If NULL, the top level collection
* is used. One can use "foo!bar!baz"
* notation to identify the sub collection.
* @param[in] disposition Constant that controls how the relative
* position of the item to extract is determined.
* For more information see \ref dispvalues
* "disposition constants".
* @param[in] refprop Name of the property to relate to.
* This can be used to specify that function
* should extract next item after the item
* with this name. Leave NULL if the
* disposition you are using does not
* relate to an item in the collection.
* @param[in] idx Index of the property to extract.
* Useful for multi-value properties where
* several properties have same name in a row.
* @param[in] type Type filter. Only the item of the matching
* type will be used. It can be a bit mask of
* more than one type. Use 0 if you do not
* need to filter by type.
* @param[out] ret_ref Variable will receive the value of the
* pointer to the extracted item.
*
* @return 0 - Item was successfully extracted.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - Sub collection is not found.
* The position can't be determined. For example
* extracting next item after item with name "foo"
* will cause this error if item "foo" is the last
* item in the collection. There are other cases
* when this error can be returned but the common
* theme is that something was not found.
* @return ENOSYS Unknown disposition value.
*/
int col_extract_item(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
int type,
struct collection_item **ret_ref);
/**
* @brief Extract item from the current collection.
*
* Function is similar to the \ref col_extract_item.
* It acts exactly the same as \ref col_extract_item when the
* subcollection parameter of the \ref col_extract_item is set to NULL.
*
* @param[in] ci Collection object.
* @param[in] disposition Constant that controls how the relative
* position of the item to extract is determined.
* For more information see \ref dispvalues
* "disposition constants".
* @param[in] refprop Name of the property to relate to.
* This can be used to specify that function
* should extract next item after the item
* with this name. Leave NULL if the
* disposition you are using does not
* relate to an item in the collection.
* @param[in] idx Index of the property to extract.
* Useful for multi-value properties where
* several properties have same name in a row.
* @param[in] type Type filter. Only the item of the matching
* type will be used. It can be a bit mask of
* more than one type. Use 0 if you do not
* need to filter by type.
* @param[out] ret_ref Variable will receive the value of the
* pointer to the extracted item.
*
* @return 0 - Item was successfully extracted.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - Sub collection is not found.
* The position can't be determined. For example
* extracting next item after item with name "foo"
* will cause this error if item "foo" is the last
* item in the collection. There are other cases
* when this error can be returned but the common
* theme is that something was not found.
* @return ENOSYS Unknown disposition value.
*/
int col_extract_item_from_current(struct collection_item *ci,
int disposition,
const char *refprop,
int idx,
int type,
struct collection_item **ret_ref);
/**
* @brief Remove item from the collection.
*
* Function internally calls \ref col_extract_item and then
* \ref col_delete_item for the extracted item.
*
* Function is similar to \ref col_delete_property function
* but allows more specific information about what item (property)
* to remove.
*
* The header will not be considered for deletion.
*
* @param[in] ci Collection object.
* @param[in] subcollection Name of the sub collection to remove
* item from. If NULL, the top level collection
* is used. One can use "foo!bar!baz"
* notation to identify the sub collection.
* @param[in] disposition Constant that controls how the relative
* position of the item to remove is determined.
* For more information see \ref dispvalues
* "disposition constants".
* @param[in] refprop Name of the property to relate to.
* This can be used to specify that function
* should remove next item after the item
* with this name. Leave NULL if the
* disposition you are using does not
* relate to an item in the collection.
* @param[in] idx Index of the property to remove.
* Useful for multi-value properties where
* several properties have same name in a row.
* @param[in] type Type filter. Only the item of the matching
* type will be used. It can be a bit mask of
* more than one type. Use 0 if you do not
* need to filter by type.
*
* @return 0 - Item was successfully removed.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - Sub collection is not found.
* The position can't be determined. For example
* deleting next item after item with name "foo"
* will cause this error if item "foo" is the last
* item in the collection. There are other cases
* when this error can be returned but the common
* theme is that something was not found.
* @return ENOSYS Unknown disposition value.
*/
int col_remove_item(struct collection_item *ci,
const char *subcollection,
int disposition,
const char *refprop,
int idx,
int type);
/**
* @brief Remove item from the current collection.
*
* Function is similar to the \ref col_remove_item.
* It acts exactly the same as \ref col_remove_item when the
* subcollection parameter of the \ref col_remove_item is set to NULL.
*
* @param[in] ci Collection object.
* @param[in] disposition Constant that controls how the relative
* position of the item to remove is determined.
* For more information see \ref dispvalues
* "disposition constants".
* @param[in] refprop Name of the property to relate to.
* This can be used to specify that function
* should remove next item after the item
* with this name. Leave NULL if the
* disposition you are using does not
* relate to an item in the collection.
* @param[in] idx Index of the property to remove.
* Useful for multi-value properties where
* several properties have same name in a row.
* @param[in] type Type filter. Only the item of the matching
* type will be used. It can be a bit mask of
* more than one type. Use 0 if you do not
* need to filter by type.
*
* @return 0 - Item was successfully removed.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - Sub collection is not found.
* The position can't be determined. For example
* deleting next item after item with name "foo"
* will cause this error if item "foo" is the last
* item in the collection. There are other cases
* when this error can be returned but the common
* theme is that something was not found.
* @return ENOSYS Unknown disposition value.
*/
int col_remove_item_from_current(struct collection_item *ci,
int disposition,
const char *refprop,
int idx,
int type);
/**
* @brief Insert item to the collection.
*
* <b>WARNING:</b> Only use this function to insert items
* that were extracted using \ref col_extract_item or
* \ref col_extract_item_from_current.
* <b>NEVER</b> use it with items that were returned by:
* - \ref col_get_item
* - \ref addproperty "add property" functions
* - \ref addprop_withref "add property with reference" functions
* - \ref insertproperty "instert property" functions.
*
* The fundamental difference is that when you extracted item
* using col_extract_item() it stops to be managed by a collection.
* With such item you can:
* - a) Insert this item into another (or same) collection
* - b) Get item information using corresponding item management functions.
* - c) Destroy item using col_delete_item().
*
* You are required to do either a) or c) with such item.
*
* @param[in] ci Collection object.
* @param[in] subcollection Name of the sub collection to insert
* item into. If NULL, the top level collection
* is used. One can use "foo!bar!baz"
* notation to identify the sub collection.
* @param[in] item Item to insert.
* @param[in] disposition Constant that controls where to insert
* the item.
* For more information see \ref dispvalues
* "disposition constants".
* @param[in] refprop Name of the property to relate to.
* This can be used to specify that function
* should insert the item after the item
* with this name. Leave NULL if the
* disposition you are using does not
* relate to an item in the collection.
* @param[in] idx Index of the property to insert.
* Useful for multi-value properties where
* several properties have same name in a row.
* @param[in] flags Flags that control naming issues.
* See \ref insflags "insert flags"
* for more details.
*
* @return 0 - Item was successfully extracted.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - Sub collection is not found.
* The position can't be determined. For example
* extracting next item after item with name "foo"
* will cause this error if item "foo" is the last
* item in the collection. There are other cases
* when this error can be returned but the common
* theme is that something was not found.
* @return ENOSYS Unknown disposition value.
* @return EEXIST If duplicate name/type checking is turned on
* and duplicate name/type is detected.
*
*/
int col_insert_item(struct collection_item *ci,
const char *subcollection,
struct collection_item *item,
int disposition,
const char *refprop,
int idx,
unsigned flags);
/**
* @brief Insert item to the current collection.
*
* Function is equivalent to \ref col_insert_item with
* subcollection parameter equal NULL.
*
* @param[in] ci Collection object.
* @param[in] item Item to insert.
* @param[in] disposition Constant that controls where to insert
* the item.
* For more information see \ref dispvalues
* "disposition constants".
* @param[in] refprop Name of the property to relate to.
* This can be used to specify that function
* should insert the item after the item
* with this name. Leave NULL if the
* disposition you are using does not
* relate to an item in the collection.
* @param[in] idx Index of the property to insert.
* Useful for multi-value properties where
* several properties have same name in a row.
* @param[in] flags Flags that control naming issues.
* See \ref insflags "insert flags"
* for more details.
*
* @return 0 - Item was successfully extracted.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
* @return ENOENT - Sub collection is not found.
* The position can't be determined. For example
* extracting next item after item with name "foo"
* will cause this error if item "foo" is the last
* item in the collection. There are other cases
* when this error can be returned but the common
* theme is that something was not found.
* @return ENOSYS Unknown disposition value.
* @return EEXIST If duplicate name/type checking is turned on
* and duplicate name/type is detected.
*
*/
int col_insert_item_into_current(struct collection_item *ci,
struct collection_item *item,
int disposition,
const char *refprop,
int idx,
unsigned flags);
/**
* @brief Delete extracted item.
*
* <b>NEVER</b> use this function to delete an item
* that was not previously extracted from the collection.
*
* There is currently no function to create an item aside and
* then insert it into the collection so the col_delete_item
* has only one use. In future this may change.
*
* @param[in] item Item to delete.
*
*/
void col_delete_item(struct collection_item *item);
/**
* @}
*/
/**
* @defgroup iterfunc Iterator interface
*
* The functions in this section allow iterating
* through a collection in a loop where the caller
* implements the loop. It is different from the search and
* traverse functions described in other sections because those
* functions implement the loop themselves and call provided
* callback in a specific situation.
*
* @{
*/
/**
* @brief Bind iterator to a collection.
*
* This function creates an iterator object and binds it to the collection.
*
* @param[out] iterator Newly created iterator object.
* @param[in] ci Collection to iterate.
* @param[in] mode_flags Flags define how to traverse the collection.
* For more information see \ref traverseconst
* "constants defining traverse modes".
*
* @return 0 - Iterator was created successfully.
* @return ENOMEM - No memory.
* @return EINVAL - The value of some of the arguments is invalid.
*
*/
int col_bind_iterator(struct collection_iterator **iterator,
struct collection_item *ci,
int mode_flags);
/**
* @brief Unbind the iterator from the collection.
*
* @param[in] iterator Iterator object to free.
*/
void col_unbind_iterator(struct collection_iterator *iterator);
/**
* @brief Iterate collection.
*
* Advance to next item in the collection. After the iterator is
* bound it does not point to any item in the collection.
* Use this function in the loop to step through all items
* in the collection. See unit test for code examples.
*
* @param[in] iterator Iterator object to use.
* @param[out] item Pointer to the collection item.
* Do not destroy or alter this pointer
* in any ways. To access the internals
* of the item use \ref getitem "item management"
* functions.
* The value of the item will be set to NULL if
* the end of the collection is reached.
*
* @return 0 - Item was successfully retrieved.
* @return EINVAL - The value of some of the arguments is invalid.
*/
int col_iterate_collection(struct collection_iterator *iterator,
struct collection_item **item);
/**
* @brief Move up
*
* Stop processing this sub collection and move to the next item in the
* collection some levels up.
*
* @param[in] iterator Iterator object to use.
* @param[in] level Indicates how many levels up you want to jump.
* If 0 - call is a no op.
* If the depth is less then requested level
* the iterator will get to the 0 level and
* next call to \ref col_iterate_collection
* will return NULL item.
*
* @return 0 - Iterator was successfully repositioned.
* @return EINVAL - The value of some of the arguments is invalid.
*/
int col_iterate_up(struct collection_iterator *iterator, unsigned level);
/**
* @brief Get current depth
*
* How deep are we relative to the top level?
* This function will report depth that in some cases might look
* misleading. The reason is that traverse flags affect the internal
* level we are on at each moment.
* For example the default traverse behavior is to show
* references to the sub collections.
* So when the item reference is returned the
* depth automatically adjusted to level inside the sub collection.
* So if function is called in this situation the level returned will
* denote the level inside collection.
* Now imagine that this collection is empty so the attempt to read
* element will push you automatically one level up (in absence of the
* \ref COL_TRAVERSE_END flag). If in this situation you encounter another
* collection the reference will be returned and level automatically
* adjusted to level inside the collection.
* The point is that the level is reliable only after
* a data item was returned.
* To avoid this ambiguity another function \ref col_get_item_depth
* was introduced.
*
* @param[in] iterator Iterator object to use.
* @param[in] depth The variable will receive the depth
* the iterator is on. The value is 0
* if the iterator is on the top level.
*
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
*/
int col_get_iterator_depth(struct collection_iterator *iterator, int *depth);
/**
* @brief Get depth of the last returned item.
*
* @param[in] iterator Iterator object to use.
* @param[in] depth The variable will receive the depth
* the iterator is on.
* Item from the top level will have
* depth equal to 0. The value of 0
* will also be returned if no item
* was read so far.
*
* @return 0 - Success.
* @return EINVAL - The value of some of the arguments is invalid.
*/
int col_get_item_depth(struct collection_iterator *iterator, int *depth);
/**
* @brief Pin iterator
*
* Pins down the iterator to loop around current point.
*
* This feature allows some search optimization.
* The idea is to be able to put a 'pin'
* into a specific place while iterating
* the collection and make this place a new
* "wrap around" place for the collection.
* This means that next time you
* iterate this collection you will start
* iterating from the next item and
* the item you got before setting pin will be
* the last in your iteration cycle.
*
* Here is the example:
*
* Assume you have two collections that you need
* to compare and perform some action on collection
* 1 based on the presence of the item in collection 2.
* - Collection1 = A, B, C, D, E, F
* - Collection2 = A, C, F
*
* The usual approach is to try A from collection 1
* against A, B, C from collection 2. "A" will be found
* right away. But to find "F" it has to be compared
* to "A" and "C" first. The fact that the collections
* are to some extent ordered can in some cases
* help to reduce the number of comparisons.
* If we found "C" in the list we can put a "pin"
* into the collection there causing the iterator
* to warp at this "pin" point. Since "D" and "E"
* are not in the second collection we will have
* to make same amount of comparisons in traditional
* or "pinned" case to not find them.
* To find "F" in pinned case there will be just one
* comparison.
* - Traditional case = 1 + 3 + 2 + 3 + 3 + 3 = 15
* - Pinned case = 1 + 3 + 1 + 3 + 3 + 1 = 12
*
* It is a 20% comparison reduction.
*
* @param[in] iterator Iterator object to use.
*/
void col_pin_iterator(struct collection_iterator *iterator);
/**
* @brief Rewind iterator
*
* Rewinds iterator to the current pin point which is by
* default the beginning of the collection until changed by
* \ref col_pin_iterator function.
*
* @param[in] iterator Iterator object to use.
*/
void col_rewind_iterator(struct collection_iterator *iterator);
/**
* @}
*/
/**
* @}
*/
#endif
More information about the sssd-devel
mailing list