Functions | |
KeySet * | ksNew () |
Allocate, initialize and return a new KeySet object. | |
int | ksDel (KeySet *ks) |
A destructor for KeySet objects. | |
ssize_t | ksGetSize (KeySet *ks) |
Return the number of keys that ks contains. | |
int | ksRewind (KeySet *ks) |
Resets a KeySet internal cursor. | |
Key * | ksNext (KeySet *ks) |
Returns the next Key in a KeySet. | |
Key * | ksCurrent (const KeySet *ks) |
Return the current Key. | |
Key * | ksHead (KeySet *ks) |
Return the first key in the KeySet, without changing the KeySet's internal cursor. | |
Key * | ksTail (KeySet *ks) |
Return the last key in the KeySet, without changing the KeySet's internal cursor. | |
Key * | ksLookupByName (KeySet *ks, const char *name, unsigned long options) |
Look for a Key contained in ks that matches name , starting from ks' ksNext() position. | |
uint32_t | ksLookupRE (KeySet *ks, uint32_t where, const regex_t *regexp, unsigned long options) |
Lookup for a key which any of its where components matches the regex regular expression. | |
Key * | ksLookupByValue (KeySet *ks, const char *value, unsigned long options) |
Lookup for a Key contained in ks KeySet that matches value , starting from ks' ksNext() position. | |
Key * | ksLookupByBinaryValue (KeySet *ks, void *value, size_t size, unsigned long options) |
Lookup for a Key contained in ks KeySet that matches the binary value , starting from ks' ksNext() position. | |
ssize_t | ksInsert (KeySet *ks, Key *toInsert) |
Insert a new Key in the beginning of the KeySet. | |
Key * | ksPop (KeySet *ks) |
Remove and return the first key of ks . | |
Key * | ksPopLast (KeySet *ks) |
Remove and return the last key of ks . | |
ssize_t | ksInsertKeys (KeySet *ks, KeySet *toInsert) |
Transfers all keys from toInsert to the begining of ks . | |
ssize_t | ksAppend (KeySet *ks, Key *toAppend) |
Appends a new Key to the end of ks . | |
ssize_t | ksAppendKeys (KeySet *ks, KeySet *toAppend) |
Transfers all toAppend contained keys to the end of the ks . | |
int | ksCompare (KeySet *ks1, KeySet *ks2, KeySet *removed) |
Compare 2 KeySets. | |
ssize_t | ksToStream (const KeySet *ks, FILE *stream, unsigned long options) |
Writes to stream an XML version of the ks object. | |
ssize_t | ksGetCommonParentName (const KeySet *ks, char *returnedCommonParent, const size_t maxSize) |
Calculates the common parent to all keys in ks . | |
void | ksSort (KeySet *ks) |
Sorts a KeySet aphabetically by Key name, using qsort(). | |
int | ksInit (KeySet *ks) |
KeySet object initializer. | |
int | ksClose (KeySet *ks) |
KeySet object cleaner. |
A KeySet is a linked list to group a number of Keys. KeySets have an internal cursor to help in the Key navigation.
These are the methods to make various manipulations in the objects of class KeySet. Methods for sorting , merging , comparing , and internal cursor manipulation are provided.
KeySet has a fundamental meaning inside elektra. It makes it possible to get and store many keys at once inside the database. In addition to that the class can be used as high level datastructure in applications. With ksLookupByName it is possible to fetch easily specific keys out of the list of keys.
To use them:
#include <kdb.h>
KeySet* ksNew | ( | ) |
Allocate, initialize and return a new KeySet object.
Objects created with ksNew() must be destroyed with ksDel().
Use this function if you want to create a new KeySet.
Due to ABI compatibility, the KeySet
structure is only declared in kdb.h, and not defined. So you can only declare pointers
to KeySets
in your program.
See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135
Definition at line 93 of file keyset.c.
References ksInit().
Referenced by commandEdit(), commandImport(), and commandList().
int ksDel | ( | KeySet * | ks | ) |
A destructor for KeySet objects.
Cleans all internal dynamic attributes, keyDel() all contained Keys, and free()s the release the KeySet object memory (that was previously allocated by ksNew()).
Definition at line 111 of file keyset.c.
References ksClose().
Referenced by commandEdit(), commandImport(), and commandList().
ssize_t ksGetSize | ( | KeySet * | ks | ) |
Return the number of keys that ks
contains.
ks
contains. Definition at line 127 of file keyset.c.
References _KeySet::size.
Referenced by commandEdit(), and listAllKeys().
int ksRewind | ( | KeySet * | ks | ) |
Resets a KeySet internal cursor.
Use it to set the cursor to the beginning of the KeySet. ksCurrent() will then always return NULL afterwards. So you want to ksNext() first.
Definition at line 155 of file keyset.c.
References _KeySet::cursor.
Referenced by commandEdit(), commandImport(), ksLookupByName(), ksLookupRE(), listAllKeys(), and listAllKeysForShell().
Returns the next Key in a KeySet.
KeySets have an internal cursor that can be reset with ksRewind(). Every time ksNext() is called the cursor is incremented and the new current Key is returned.
You'll get a NULL pointer if the end of KeySet was reached. After that, if ksNext() is called again, it will set the cursor to the beginning of the KeySet and the first key is returned.
Definition at line 177 of file keyset.c.
References _KeySet::cursor, _Key::next, and _KeySet::start.
Referenced by commandEdit(), commandImport(), kdbMonitorKeys_default(), kdbSetKeys_default(), ksLookupByBinaryValue(), ksLookupByName(), ksLookupByValue(), ksLookupRE(), listAllKeys(), and listAllKeysForShell().
Return the current Key.
The pointer is NULL if you reached the end or after ksRewind().
ks's
cursor kdbMonitorKeys() for a usage example
Definition at line 196 of file keyset.c.
References _KeySet::cursor.
Referenced by commandEdit(), commandImport(), kdbMonitorKeys_default(), and kdbSetKeys_default().
Return the first key in the KeySet, without changing the KeySet's internal cursor.
ksRewind() which also resets the internal cursor.
Definition at line 209 of file keyset.c.
References _KeySet::start.
Referenced by listAllKeys().
Return the last key in the KeySet, without changing the KeySet's internal cursor.
Definition at line 221 of file keyset.c.
References _KeySet::end.
Look for a Key contained in ks
that matches name
, starting from ks'
ksNext() position.
The ksLookup*
() set of methods are designed to let you work with entirely pre-loaded KeySets, so instead of kdbGetKey(), key by key, the idea is to fully kdbGetChildKeys() for your application root key (which is more performatic), and process it all at once with ksLookup*
().
The lookup process stops if the end of ks
is reached. The idea behind it is that your keyset processing logic consider a sorted KeySet and process it in a alphabetical order. So your logic should first lookup key aaa, then bbb, then ccc. This way you avoid going back to a position in an already processed point.
This behavior changes if KDB_O_ALL
option is used: all the KeySet is searched, and if not found, it will stop with the current key.
If found, ks
internal cursor will be positioned in the matched key (also accessible by ksCurrent()), and a pointer to the Key is returned. If not found, ks
internal cursor will not move, and a NULL pointer is returned.
Cascading is done if the first character is a /. This leads to ignoring the prefix like system/ and user/.
if (kdbGetChildKeys("user/myapp", myConfig, 0 ) == -1) BailOut ("Could not get Keys"); if (kdbGetChildKeys("system/myapp", myConfig, 0 ) == -1) BailOut ("Could not get Keys"); if ((myKey = ksLookupByName (myConfig, "/myapp/key", 0)) == NULL) BailOut ("Could not Lookup Key");
This is the way multi user Programs should get there configuration and search after the values. It is guaranteed that more namespaces can be added easily and that all values can be set by admin and user.
ks | where to look for | |
name | key name you are looking for | |
options | some KDB_O_* option bits. Currently suported:
|
keyCompare() for very powerfull Key lookups in KeySets
Definition at line 294 of file keyset.c.
References _KeySet::cursor, KDB_O_ALL, KDB_O_NOCASE, _Key::key, keyStealName(), ksNext(), ksRewind(), _KeySet::start, and strblen().
uint32_t ksLookupRE | ( | KeySet * | ks, | |
uint32_t | where, | |||
const regex_t * | regexp, | |||
unsigned long | options | |||
) |
Lookup for a key which any of its where
components matches the regex
regular expression.
ks | the KeySet to lookup into | |
where | any of KEY_SWITCH_NAME , KEY_SWITCH_VALUE , KEY_SWITCH_OWNER , KEY_SWITCH_COMMENT ORed. | |
regexp | a regcomp(3) pre-compiled regular expression | |
options | some KDB_O_* ORed options to change lookup behavior. Currently supported options:
|
KEY_SWITCH_NAME
, KEY_SWITCH_VALUE
, KEY_SWITCH_OWNER
, KEY_SWITCH_COMMENT
switches ORed to indicate where
the regex
matched.// This code will process all Devices options, device by device. // Look how we use nested loops, palying with KDB_O_NOSPANPARENT. // We can do more interesting things when playing with 2 or more regular // expressions. regex_t regex; // you are NOT seeing spaces in this regex regcomp(®ex,".* /InputDevices/.* /Options/.*",REG_NOSUB); where=KEY_SWITCH_NAME; // look for it only in key names ksRewind(ks); do { // show all keys that match this name, and are siblings of the first match match=ksLookupRE(ks,where,®ex,0); if (match) { // We found a device and its first option, processOption(ksCurrent(ks)); // now process other options of this same device do { // fetch only the options with same parent with the // help of KDB_O_NOSPANPARENT match=ksLookupRE(ks,where,®ex,KDB_O_NOSPANPARENT); if (match) processOption(ksCurrent(ks)); } while (match); } } while (match); regfree(®ex); // free regex resources
regex_t regex; // The spaces between '*' and '/' and '*' chars are Doxygen mirages :) regcomp(®ex, "some value .* more text", // match this REG_NEWLINE | REG_NOSUB); // all in a single line regcomp(®ex, "Device/.* /Options/ *", // only interested in option keys REG_ICASE | REG_NOSUB); // ignore case regcomp(®ex, "^system/folder/.* /basename$", // match real system/ keys that end with 'basename' REG_NOSUB); // allways use REG_NOSUB to increase performance regcomp(®ex, "^system/sw/xorg/.* /Screen[0-9]* /Displays/[0-9]* /Depth$", // we want all X.org's depths of all displays of all screens REG_ICASE | REG_NOSUB); // we don't care about the case regfree(®ex); // don't forget to free resources
Definition at line 438 of file keyset.c.
References _Key::comment, _KeySet::cursor, _Key::data, KDB_O_ALL, KDB_O_NOSPANPARENT, _Key::key, KEY_SWITCH_COMMENT, KEY_SWITCH_NAME, KEY_SWITCH_OWNER, KEY_SWITCH_VALUE, KEY_TYPE_STRING, keyGetNameSize(), keyGetParentName(), keyGetParentNameSize(), keyIsUser(), ksNext(), ksRewind(), _KeySet::start, _Key::type, and _Key::userDomain.
Lookup for a Key contained in ks
KeySet that matches value
, starting from ks' ksNext() position.
If found, ks
internal cursor will be positioned in the matched key (also accessible by ksCurrent()), and a pointer to the Key is returned. If not found, ks
internal cursor won't move, and a NULL pointer is returned.
This method jumps binary keys, unless value
is NULL.
ksRewind(ks); while (key=ksLookupByValue(ks,"my value",0)) { // show all keys which value="my value" keyToStream(key,stdout,0); }
ks | where to look for | |
value | the value which owner key you want to find | |
options | some KDB_O_* option bits. Currently supported:
|
keyCompare() for very powerfull Key lookups in KeySets
TODO: Use macro instead
Definition at line 546 of file keyset.c.
References _KeySet::cursor, _Key::data, _Key::dataSize, KDB_O_NOCASE, KEY_TYPE_STRING, ksNext(), strblen(), and _Key::type.
Lookup for a Key contained in ks
KeySet that matches the binary value
, starting from ks' ksNext() position.
If found, ks
internal cursor will be positioned in the matched key. That means it is also accessible by ksCurrent(). A pointer to the Key is returned. If not found, ks
internal cursor won't move, and a NULL pointer is returned.
ks | where to look for | |
value | the value which owner key you want to find | |
size | the size of value | |
options | some KDB_O_* option bits, for future use |
keyCompare() for very powerfull Key lookups in KeySets
TODO: use macro to check if dir!
Definition at line 596 of file keyset.c.
References _KeySet::cursor, _Key::data, _Key::dataSize, and ksNext().
Insert a new Key in the beginning of the KeySet.
A reference to the key will be stored, and not a copy of the key. So a future ksClose() or ksDel() on ks
will keyDel() the toInsert
object.
The KeySet internal cursor is not moved.
Do not ksInsert() Keys that are already members of other KeySets.
ks | KeySet that will receive the key | |
toInsert | Key that will be inserted into ks |
Definition at line 645 of file keyset.c.
References _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
Referenced by kdbGetRootKeys().
Remove and return the first key of ks
.
If ks'
cursor was positioned in the poped key, ks
will be ksRewind()ed.
ksInsert() provides the 'push' bahavior.
ks
, or NULL if ks
is empty ks | KeySet to work with |
commandList() for an example
Definition at line 665 of file keyset.c.
References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
Referenced by commandList().
Remove and return the last key of ks
.
If ks'
cursor was positioned in the poped key, ks
will be ksRewind()ed.
ksAppend() provides the 'push' bahavior.
ks
, or NULL if ks
is empty ks | KeySet to work with |
commandList() and ksCompare() for examples
Definition at line 692 of file keyset.c.
References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
Transfers all keys from toInsert
to the begining of ks
.
After this call, toInsert
will be empty and can be deleted with ksDel().
ks | the KeySet that will receive the keys | |
toInsert | the KeySet that provides the keys that will be transfered |
Definition at line 732 of file keyset.c.
References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
Appends a new Key to the end of ks
.
A reference to the key will be stored, and not a private copy. So a future ksClose() or ksDel() on ks
will keyDel() the toAppend
object. The KeySet internal cursor is not moved.
Do not ksAppend() Keys that are already contained by other KeySets.
ks | KeySet that will receive the key | |
toAppend | Key that will be appended to ks |
Definition at line 762 of file keyset.c.
References _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
Referenced by commandEdit(), commandList(), and ksCompare().
Transfers all toAppend
contained keys to the end of the ks
.
After this call, the toAppend
KeySet will be empty, and can be deleted with ksDel().
ks | the KeySet that will receive the keys | |
toAppend | the KeySet that provides the keys that will be transfered |
Definition at line 784 of file keyset.c.
References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
Referenced by commandList(), and ksCompare().
Compare 2 KeySets.
This is a c-helper function, you need not implement it in a binding.
This method behavior is the following:
ks1
and ks2
, and has something different, will be transfered from ks2
to ks1
, and ks1's
(old) version deleted.ks1
, but not in ks2
will be transfered from ks1
to removed
.ks1
and ks2
will be keyDel()eted from ks2
.ks2
but not in ks1
will be transfered to ks1
.
In the end, ks1
will have all the keys that matter, and ks2
will be empty.
After ksCompare(), you should, in this order:
ks1
to commit all changed keysremoved
KeySet
ks1 | first and main KeySet | |
ks2 | second KeySet | |
removed | (generally empty) KeySet that will be filled with keys removed from ks1 |
commandEdit() at the KeyDB :: Class Methods command
KeySet *ks1,*ks2,*removed; Key *key; ks1=ksNew(); ks2=ksNew(); removed=ksNew(); // ... // Populate ks1 and ks2.... // ... ksCompare(ks1,ks2,removed); ksDel(ks2); // second KeySet is allways empty after ksCompare() kdbSetKeys(ks1); // commit changed keys ksDel(ks1); // don't need ks1 anymore // Remove all keys that disapeared from ks1... ksSort(removed); // Sort it first so then we ensure child keys are removed // before their parents while (key=ksPopLast(removed)) { kdbRemoveKey(key); keyDel(key); } ksDel(removed); // free the KeySet memory
Definition at line 879 of file keyset.c.
References _KeySet::end, KEY_SWITCH_DOMAIN, KEY_SWITCH_NAME, KEY_SWITCH_NEEDSYNC, keyCompare(), keyDel(), ksAppend(), ksAppendKeys(), _Key::next, _KeySet::size, and _KeySet::start.
Referenced by commandEdit().
ssize_t ksToStream | ( | const KeySet * | ks, | |
FILE * | stream, | |||
unsigned long | options | |||
) |
Writes to stream
an XML version of the ks
object.
String generated is of the form:
<?xml version="1.0" encoding="UTF-8"?> <!-- Generated by Elektra API. Total of n keys. --> <keyset xmlns="http://www.libelektra.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.libelektra.org elektra.xsd"> <key name=...>...</key> <key name=...>...</key> <key name=...>...</key> </keyset>
OR, if KDBOptions::KDB_O_HIER is used, the form will be:
<?xml version="1.0" encoding="UTF-8"?> <!-- Generated by Elektra API. Total of n keys. --> <keyset xmlns="http://www.libelektra.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.libelektra.org elektra.xsd" parent="smallest/parent/name"> <key basename=...>...</key> <key name=...>...</key> <!-- a key thats not under this keyset's parent --> <key basename=...>...</key> </keyset>
stream | where to write output: a file or stdout | |
options | accepted KDBOptions ORed:
|
commandList() for usage example
Definition at line 1029 of file keyset.c.
References KDB_O_HIER, KDB_O_XMLHEADERS, keyToStream(), keyToStreamBasename(), ksGetCommonParentName(), _Key::next, _KeySet::size, and _KeySet::start.
Referenced by commandEdit(), and commandList().
ssize_t ksGetCommonParentName | ( | const KeySet * | ks, | |
char * | returnedCommonParent, | |||
const size_t | maxSize | |||
) |
Calculates the common parent to all keys in ks
.
This is a c-helper function, you need not implement it in bindings.
Given the ks
KeySet, calculates the parent name for all the keys. So if ks
contains this keys:
system/sw/xorg/Monitors/Monitor1/vrefresh system/sw/xorg/Monitors/Monitor1/hrefresh system/sw/xorg/Devices/Device1/driver system/sw/xorg/Devices/Device1/mode
The common parent is system/sw/xorg
.
On the other hand, if we have this KeySet:
system/some/thing system/other/thing user/unique/thing
No common parent is possible, so returnedCommonParent
will contain nothing.
This method will work correctly only on sorted KeySets .
returnedCommonParent | a pre-allocated buffer that will receive the common parent, if found | |
maxSize | size of the pre-allocated returnedCommonParent buffer |
errno
must be checked. Definition at line 1148 of file keyset.c.
References KDB_RET_TRUNC, _Key::key, keyGetNameSize(), _Key::next, _KeySet::start, and strblen().
Referenced by ksToStream().
void ksSort | ( | KeySet * | ks | ) |
Sorts a KeySet aphabetically by Key name, using qsort().
ks | KeySet to be sorted |
Definition at line 1198 of file keyset.c.
References _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.
int ksInit | ( | KeySet * | ks | ) |
KeySet object initializer.
You should always use ksNew() instead of ksInit().
Every KeySet object that will be used must be initialized first, to setup pointers, counters, etc. After use, all ksInit()ialized KeySets must be cleaned with ksClose().
Definition at line 1239 of file keyset.c.
References _KeySet::cursor, _KeySet::end, _KeySet::size, and _KeySet::start.
Referenced by ksNew().
int ksClose | ( | KeySet * | ks | ) |
KeySet object cleaner.
Will keyDel() all contained keys, reset internal pointers and counters.
After this call, the ks
object is ready to be freed by you.
ksAppend() for details on how keys are inserted in KeySets
Definition at line 1258 of file keyset.c.
References _KeySet::cursor, _KeySet::end, keyDel(), _Key::next, _KeySet::size, and _KeySet::start.
Referenced by ksDel().