Main Page | Modules | Data Structures | File List | Data Fields

KeySet :: Class Methods

Methods to manipulate KeySets. A KeySet is a linked list to group a number of Keys. Key Sets have an internal cursor to help in the Key navigation. More...

Functions

KeySetksNew ()
 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 contained by ks.
int ksRewind (KeySet *ks)
 Resets a KeySet internal cursor.
KeyksNext (KeySet *ks)
 Returns the next Key in a KeySet.
KeyksCurrent (const KeySet *ks)
 Return the current Key.
KeyksHead (KeySet *ks)
 Return the first key in the KeySet, whithout changing the KeySet's internal cursor.
KeyksTail (KeySet *ks)
 Return the last key in the KeySet, whithout changing the KeySet's internal cursor.
KeyksLookupByName (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.
KeyksLookupByValue (KeySet *ks, const char *value, unsigned long options)
 Lookup for a Key contained in ks KeySet that matches value, starting from ks' ksNext() position.
KeyksLookupByBinaryValue (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 begining of the KeySet.
KeyksPop (KeySet *ks)
 Remove and return the first key of ks.
KeyksPopLast (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.
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.

Detailed Description

Methods to manipulate KeySets. A KeySet is a linked list to group a number of Keys. Key Sets 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. To use them:

#include <kdb.h>

Function Documentation

KeySet* ksNew  ) 
 

Allocate, initialize and return a new KeySet object.

Objects created with ksNew() must be destroyed with ksDel().

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, and allocate and free memory for them with ksNew() and ksDel() respectively. See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135

See also:
ksDel()
Returns:
a ready to use KeySet object

Definition at line 70 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()). There is the ksFree() macro if you prefer this method name.

See also:
ksNew(), ksClose()
Returns:
whatever is returned by ksClose()

Definition at line 89 of file keyset.c.

References ksClose().

Referenced by commandEdit(), and commandList().

int ksRewind KeySet ks  ) 
 

Resets a KeySet internal cursor.

Use it to set the cursor to the begining of the KeySet

Returns:
allways 0
See also:
ksNext(), ksCurrent(), kdbMonitorKeys() for an example

Definition at line 127 of file keyset.c.

References _KeySet::cursor.

Referenced by commandEdit(), commandImport(), and commandList().

Key* ksNext KeySet ks  ) 
 

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 begining of the KeySet and the first key is returned.

Returns:
the new current Key
See also:
ksRewind(), ksCurrent()

Definition at line 147 of file keyset.c.

References _KeySet::cursor, _Key::next, and _KeySet::start.

Referenced by commandEdit(), commandImport(), commandList(), kdbMonitorKeys_default(), kdbSetKeys_default(), ksLookupByBinaryValue(), ksLookupByName(), ksLookupByValue(), and ksLookupRE().

Key* ksCurrent const KeySet ks  ) 
 

Return the current Key.

Returns:
pointer to the Key pointed by ks's cursor
See also:
ksNext(), ksRewind()

kdbMonitorKeys() for a usage example

Definition at line 163 of file keyset.c.

References _KeySet::cursor.

Referenced by commandEdit(), commandImport(), kdbMonitorKeys_default(), and kdbSetKeys_default().

Key* ksHead KeySet ks  ) 
 

Return the first key in the KeySet, whithout changing the KeySet's internal cursor.

See also:
ksTail(), ksCurrent(), ksNext()

ksRewind() which also resets the internal cursor.

Definition at line 176 of file keyset.c.

References _KeySet::start.

Referenced by commandList().

Key* ksTail KeySet ks  ) 
 

Return the last key in the KeySet, whithout changing the KeySet's internal cursor.

See also:
ksHead(), ksCurrent(), ksNext()

Definition at line 188 of file keyset.c.

References _KeySet::end.

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.

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.

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*().

Parameters:
ks where to look for
name key name you are looking for
options some KDB_O_* option bits. Currently suported:
  • KDB_O_NOCASE
    Lookup ignoring case.
Returns:
pointer to the Key found, 0 otherwise
See also:
ksLookupRE() for powerfull regular expressions based lookups

keyCompare() for very powerfull Key lookups in KeySets

ksCurrent(), ksRewind(), ksNext()

This "optimization" makes comparing keys double when equals currentNameSize=current->key?strblen(current->key):0; if (currentNameSize != nameSize) continue;

Definition at line 247 of file keyset.c.

References _KeySet::cursor, _Key::key, keyStealName(), ksNext(), 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.

Parameters:
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:
Returns:
some of KEY_SWITCH_NAME, KEY_SWITCH_VALUE, KEY_SWITCH_OWNER, KEY_SWITCH_COMMENT switches ORed to indicate where the regex matched.
See also:
ksLookupByName(), ksLookupByValue(), keyCompare() for other types of lookups.

kdbGetChildKeys(), ksSort()

Example:
// 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(&regex,".* /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,&regex,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,&regex,KDB_O_NOSPANPARENT);
            
            if (match) processOption(ksCurrent(ks));
        } while (match);
    }
} while (match);

regfree(&regex); // free regex resources
Examples of regular expressions:
regex_t regex;

// The spaces between '*' and '/' and '*' chars are Doxygen mirages :)

regcomp(&regex,
    "some value .* more text",  // match this
    REG_NEWLINE | REG_NOSUB);   // all in a single line

regcomp(&regex,
    "Device/.* /Options/ *",      // only interested in option keys
    REG_ICASE | REG_NOSUB);      // ignore case

regcomp(&regex,
    "^system/folder/.* /basename$", // match real system/ keys that end with 'basename'
    REG_NOSUB);       // allways use REG_NOSUB to increase performance

regcomp(&regex,
    "^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(&regex);        // don't forget to free resources

Definition at line 378 of file keyset.c.

References _Key::comment, _KeySet::cursor, _Key::data, _Key::key, KEY_TYPE_BINARY, keyGetNameSize(), keyGetParentName(), keyGetParentNameSize(), keyIsUser(), ksNext(), _Key::type, and _Key::userDomain.

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.

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.

Example:
ksRewind(ks);
while (key=ksLookupByValue(ks,"my value",0)) {
    // show all keys which value="my value"
    keyToStream(key,stdout,0);
}
Parameters:
ks where to look for
value the value which owner key you want to find
options some KDB_O_* option bits. Currently supported:
  • KDB_O_NOCASE
    Lookup ignoring case.
Returns:
the Key found, 0 otherwise
See also:
ksLookupByBinaryValue()

keyCompare() for very powerfull Key lookups in KeySets

ksCurrent(), ksRewind(), ksNext()

Definition at line 470 of file keyset.c.

References _KeySet::cursor, _Key::data, _Key::dataSize, KEY_TYPE_BINARY, ksNext(), strblen(), and _Key::type.

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.

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.

Parameters:
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
Returns:
the Key found, NULL otherwise
See also:
ksLookupByValue()

keyCompare() for very powerfull Key lookups in KeySets

ksCurrent(), ksRewind(), ksNext()

Definition at line 519 of file keyset.c.

References _KeySet::cursor, _Key::data, _Key::dataSize, and ksNext().

ssize_t ksInsert KeySet ks,
Key toInsert
 

Insert a new Key in the begining 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.

Returns:
the size of the KeySet after insertion
Parameters:
ks KeySet that will receive the key
toInsert Key that will be inserted into ks
See also:
ksAppend(), ksInsertKeys(), ksAppendKeys(), ksDel(), keyNew()

Definition at line 566 of file keyset.c.

References _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.

Referenced by kdbGetRootKeys().

Key* ksPop KeySet ks  ) 
 

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.

Returns:
the first key of ks, or NULL if ks is empty
Parameters:
ks KeySet to work with
See also:
ksInsert(), ksRewind()

commandList() for an example

Definition at line 586 of file keyset.c.

References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.

Referenced by commandList().

Key* ksPopLast KeySet ks  ) 
 

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.

Returns:
the last key of ks, or NULL if ks is empty
Parameters:
ks KeySet to work with
See also:
ksAppend(), ksRewind()

commandList() and ksCompare() for examples

Definition at line 613 of file keyset.c.

References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.

ssize_t ksInsertKeys KeySet ks,
KeySet toInsert
 

Transfers all keys from toInsert to the begining of ks.

After this call, toInsert will be empty and can be deleted with ksDel().

Returns:
the size of the KeySet after insertion
Parameters:
ks the KeySet that will receive the keys
toInsert the KeySet that provides the keys that will be transfered
See also:
ksAppend(), ksInsert(), ksAppendKeys()

Definition at line 653 of file keyset.c.

References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.

ssize_t ksAppend KeySet ks,
Key toAppend
 

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.

Returns:
the size of the KeySet after insertion
Parameters:
ks KeySet that will receive the key
toAppend Key that will be appended to ks
See also:
ksInsert(), ksInsertKeys(), ksAppendKeys(), keyNew(), ksDel()

Definition at line 683 of file keyset.c.

References _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.

Referenced by commandEdit(), commandList(), and ksCompare().

ssize_t ksAppendKeys KeySet ks,
KeySet toAppend
 

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().

Returns:
the size of the KeySet after transfer
Parameters:
ks the KeySet that will receive the keys
toAppend the KeySet that provides the keys that will be transfered
See also:
ksAppend(), ksInsert(), ksInsertKeys()

Definition at line 705 of file keyset.c.

References _KeySet::cursor, _KeySet::end, _Key::next, _KeySet::size, and _KeySet::start.

Referenced by commandList(), and ksCompare().

int ksCompare KeySet ks1,
KeySet ks2,
KeySet removed
 

Compare 2 KeySets.

This method behavior is the following:

  • A key (by full name) that is present on ks1 and ks2, and has something different, will be transfered from ks2 to ks1, and ks1's (old) version deleted.
  • Keys present in ks1, but not in ks2 will be transfered from ks1 to removed.
  • Keys that are keyCompare() equal in ks1 and ks2 will be keyDel()eted from ks2.
  • Keys present in 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:

  1. ksDel(ks2)
  2. call kdbSetKeys() on ks1 to commit all changed keys
  3. kdbRemoveKey() for all keys in the removed KeySet
  4. ksDel(removed)

Parameters:
ks1 first and main KeySet
ks2 second KeySet
removed (generally empty) KeySet that will be filled with keys removed from ks1
See also:
keyCompare()

commandEdit() at the kdb command

Returns:
allways 0
Example
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 798 of file keyset.c.

References _KeySet::end, KEY_SWITCH_NAME, 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>

Parameters:
stream where to write output: a file or stdout
options accepted KDBOptions ORed:
  • KDBOptions::KDB_O_NUMBERS
    Do not convert UID and GID into user and group names.
  • KDBOptions::KDB_O_CONDENSED
    Less human readable, more condensed output.
  • KDBOptions::KDB_O_XMLHEADERS
    Use it. Include the correct XML headers in the output. If not used, the <?xml?> and schema info inside the <keyset> object will not be generated.
  • KDBOptions::KDB_O_HIER
    Will generate a <keyset> node containing a parent attribute, and <key> nodes with a basename relative to that parent. The parent is calculated by taking the smallest key name in the keyset, so it is a good idea to have only related keys on the keyset. Otherwise, a valid consistent XML document still will be generated with regular absolute name attribute for the <key> nodes, due to a clever keyToStreamBasename() implementation.
See also:
keyToStream()

commandList() for usage example

Returns:
number of bytes written to output, or -1 if some error occurs

Definition at line 942 of file keyset.c.

References _Key::key, keyGetFullName(), keyIsUser(), keyToStream(), keyToStreamBasename(), _Key::next, _KeySet::size, _KeySet::start, and strblen().

Referenced by commandEdit(), and commandList().

void ksSort KeySet ks  ) 
 

Sorts a KeySet aphabetically by Key name, using qsort().

Parameters:
ks KeySet to be sorted

Definition at line 1022 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().

See also:
ksNew(), ksClose(), keyInit()
Returns:
allways 0

Definition at line 1063 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.

See also:
keyDel(), ksInit(), keyClose()

ksAppend() for details on how keys are inserted in KeySets

Returns:
allways 0

Definition at line 1082 of file keyset.c.

References _KeySet::cursor, _KeySet::end, keyDel(), _Key::next, _KeySet::size, and _KeySet::start.

Referenced by commandList(), and ksDel().


Generated on Sun Feb 19 10:05:37 2006 for Elektra Project by  doxygen 1.3.9.1