Elektra  0.8.6
Modules | Enumerations | Functions
Key

A Key is the essential class that encapsulates key name , value and metainfo . More...

Collaboration diagram for Key:

Modules

 Basic Methods
 Key construction and initialization methods.
 Meta Info Manipulation Methods
 Methods to do various operations on Key metainfo.
 Methods for Making Tests
 Methods to do various tests on Keys.
 Name Manipulation Methods
 Methods to do various operations on Key names.
 Value Manipulation Methods
 Methods to do various operations on Key values.

Enumerations

enum  keyswitch_t {
  KEY_NAME = 1, KEY_VALUE = 1<<1, KEY_OWNER = 1<<2, KEY_COMMENT = 1<<3,
  KEY_BINARY = 1<<4, KEY_UID = 1<<5, KEY_GID = 1<<6, KEY_MODE = 1<<7,
  KEY_ATIME = 1<<8, KEY_MTIME = 1<<9, KEY_CTIME = 1<<10, KEY_SIZE = 1<<11,
  KEY_DIR = 1<<14, KEY_END = 0
}

Functions

Key * keyNew (const char *keyName,...)
Key * keyDup (const Key *source)
int keyCopy (Key *dest, const Key *source)
int keyDel (Key *key)
int keyClear (Key *key)
ssize_t keyIncRef (Key *key)
ssize_t keyDecRef (Key *key)
ssize_t keyGetRef (const Key *key)

Detailed Description

A Key is the essential class that encapsulates key name , value and metainfo .

Enumeration Type Documentation

Switches to denote the various Key attributes in methods throughout this library.

This enum switch provide a flag for every metadata in a key.

In case of keyNew() they give Information what Parameter comes next.

See Also
keyNew()
ksToStream(), keyToStream()
Enumerator:
KEY_NAME 

Flag for the key name

KEY_VALUE 

Flag for the key data

KEY_OWNER 

Flag for the key user domain

KEY_COMMENT 

Flag for the key comment

KEY_BINARY 

Flag if the key is binary

KEY_UID 

Flag for the key UID

KEY_GID 

Flag for the key GID

KEY_MODE 

Flag for the key permissions

KEY_ATIME 

Flag for the key access time

KEY_MTIME 

Flag for the key change time

KEY_CTIME 

Flag for the key status change time

KEY_SIZE 

Flag for maximum size to limit value

KEY_DIR 

Flag for the key directories

KEY_END 

Used as a parameter terminator to keyNew()

Function Documentation

int keyClear ( Key *  key)

Key Object Cleaner.

Will reset all internal data.

After this call you will receive a fresh key.

The reference counter will stay unmodified.

Note
that you might also clear() all aliases with this operation.
int f (Key *k)
{
keyClear (k);
// you have a fresh key k here
keySetString (k, "value");
// the caller will get an empty key k with an value
}
Returns
returns 0 on success
-1 on null pointer
Parameters
keythe key object to work with
int keyCopy ( Key *  dest,
const Key *  source 
)

Copy or Clear a key.

Most often you may prefer keyDup() which allocates a new key and returns a duplication of another key.

But when you need to copy into an existing key, e.g. because it was passed by a pointer in a function you can do so:

void h (Key *k)
{
// receive key c
keyCopy (k, c);
// the caller will see the changed key k
}

The reference counter will not be changed for both keys. Affiliation to keysets are also not affected.

When you pass a NULL-pointer as source the data of dest will be cleaned completely (except reference counter, see keyClear()) and you get a fresh dest key.

void g (Key *k)
{
keyCopy (k, 0);
// k is now an empty and fresh key
}

The meta data will be duplicated for the destination key. So it will not take much additional space, even with lots of metadata.

If you want to copy all metadata, but keep the old value you can use keyCopy() too.

void j (Key *k)
{
size_t size = keyGetValueSize (k);
char *value = malloc (size);
int bstring = keyIsString (k);
// receive key c
memcpy (value, keyValue(k), size);
keyCopy (k, c);
if (bstring) keySetString (k, value);
else keySetBinary (k, value, size);
free (value);
// the caller will see the changed key k
// with the metadata from c
}
Note
Next to the value itself we also need to remember if the value was string or binary. So in fact the meta data of the resulting key k in that example is not a complete duplicate, because the meta data "binary" may differ. Similar considerations might be necessary for the type of the key and so on, depending on the concrete situation.
Parameters
destthe key which will be written to
sourcethe key which should be copied or NULL to clean the destination key
Returns
-1 on failure when a NULL pointer was passed for dest or a dynamic property could not be written. Both name and value are empty then.
0 when dest was cleaned
1 when source was successfully copied
See Also
keyDup() to get a duplication of a Key
ssize_t keyDecRef ( Key *  key)

Decrement the viability of a key object.

The references will be decremented for ksPop() or successful calls of ksLookup() with the option KDB_O_POP. It will also be decremented with an following keyDel() in the case that an old key is replaced with another key with the same name.

The reference counter can't be decremented once it reached 0. In that situation nothing will happen and 0 will be returned.

Note
keyDup() will reset the references for dupped key.
Returns
the value of the new reference counter
-1 on null pointer
0 when the key is ready to be freed
Parameters
keythe key object to work with
See Also
keyGetRef(), keyDel(), keyIncRef()
int keyDel ( Key *  key)

A destructor for Key objects.

Every key created by keyNew() must be deleted with keyDel().

It is save to delete keys which are in a keyset, the number of references will be returned then.

It is save to delete a nullpointer, -1 will be returned then.

It is also save to delete a multiple referenced key, nothing will happen then and the reference counter will be returned.

Parameters
keythe key object to delete
See Also
keyNew(), keyInc(), keyGetRef()
Returns
the value of the reference counter if the key is within keyset(s)
0 when the key was freed
-1 on null pointers
Key* keyDup ( const Key *  source)

Return a duplicate of a key.

Memory will be allocated as needed for dynamic properties.

The new key will not be member of any KeySet and will start with a new reference counter at 0. A subsequent keyDel() will delete the key.

int f (const Key * source)
{
Key * dup = keyDup (source);
// work with duplicate
keyDel (dup);
// everything related to dup is freed
// and source is unchanged
}

Like for a new key after keyNew() a subsequent ksAppend() makes a KeySet to take care of the lifecycle of the key.

int g (const Key * source, KeySet * ks)
{
Key * dup = keyDup (source);
// work with duplicate
ksAppendKey (ks, dup);
// ksDel(ks) will also free the duplicate
// source remains unchanged.
}

Duplication of keys should be preferred to keyNew(), because data like owner can be filled with a copy of the key instead of asking the environment. It can also be optimized in the checks, because the keyname is known to be valid.

Parameters
sourcehas to be an initializised source Key
Returns
0 failure or on NULL pointer
a fully copy of source on success
See Also
ksAppend(), keyDel(), keyNew()
ssize_t keyGetRef ( const Key *  key)

Return how many references the key has.

The references will be incremented on successful calls to ksAppendKey() or ksAppend().

Note
keyDup() will reset the references for dupped key.

For your own applications you can use keyIncRef() and keyDecRef() for reference counting. Keys with zero references will be deleted when using keyDel().

Parameters
keythe key object to work with
Returns
the number of references
-1 on null pointer
See Also
keyIncRef() and keyDecRef()
ssize_t keyIncRef ( Key *  key)

Increment the viability of a key object.

This function is intended for applications using their own reference counter for key objects. With it you can increment the reference and thus avoid destruction of the object in a subsequent keyDel().

Key *k;
keyInc (k);
function_that_keyDec(k);
// work with k
keyDel (k); // now really free it

The reference counter can't be incremented once it reached SSIZE_MAX. In that situation nothing will happen and SSIZE_MAX will be returned.

Note
keyDup() will reset the references for dupped key.
Returns
the value of the new reference counter
-1 on null pointer
SSIZE_MAX when maximum exceeded
Parameters
keythe key object to work with
See Also
keyGetRef(), keyDecRef(), keyDel()
Key* keyNew ( const char *  keyName,
  ... 
)

A practical way to fully create a Key object in one step.

This function tries to mimic the C++ way for constructors.

To just get a key object, simple do:

Key *k = keyNew(0);
// work with it
keyDel (k);

If you want the key object to contain a name, value, comment and other meta info read on.

Note
When you already have a key with similar properties its easier and cheaper to keyDup() the key.

Due to ABI compatibility, the Key structure is not defined in kdb.h, only declared. So you can only declare pointers to Keys in your program, and allocate and free memory for them with keyNew() and keyDel() respectively. See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135

You can call it in many different ways depending on the attribute tags you pass as parameters. Tags are represented as the keyswitch_t values, and tell keyNew() which Key attribute comes next.

The simplest and minimum way to use it is with no tags, only a key name:

Key *nullKey,*emptyNamedKey;
// Create a key that has no name, is completely empty, but is initialized
nullKey=keyNew(0);
keyDel (nullKey);
// Is the same as above
nullKey=keyNew("", KEY_END);
keyDel (nullKey);
// Create and initialize a key with a name and nothing else
emptyNamedKey=keyNew("user/some/example",KEY_END);
keyDel (emptyNamedKey);

keyNew() allocates memory for a key object and cleans everything up. After that, it processes the given argument list.

The Key attribute tags are the following:

  • keyswitch_t::KEY_TYPE
    Next parameter is a type of the value. Default assumed is KEY_TYPE_UNDEFINED. Set this attribute so that a subsequent KEY_VALUE can toggle to keySetString() or keySetBinary() regarding to keyIsString() or keyIsBinary(). If you don't use KEY_TYPE but a KEY_VALUE follows afterwards, KEY_TYPE_STRING will be used.
  • keyswitch_t::KEY_SIZE
    Define a maximum length of the value. This is especially useful for setting a binary key. So make sure you use that before you KEY_VALUE for binary keys.
  • keyswitch_t::KEY_VALUE
    Next parameter is a pointer to the value that will be set to the key If no keyswitch_t::KEY_TYPE was used before, keyswitch_t::KEY_TYPE_STRING is assumed. If KEY_TYPE was previously passed with a KEY_TYPE_BINARY, you should have passed KEY_SIZE before! Otherwise it will be cut of with first \0 in string!
  • keyswitch_t::KEY_UID, keyswitch_t::KEY_GID
    Next parameter is taken as the UID (uid_t) or GID (gid_t) that will be defined on the key. See keySetUID() and keySetGID().
  • keyswitch_t::KEY_MODE
    Next parameter is taken as mode permissions (mode_t) to the key. See keySetMode().
  • keyswitch_t::KEY_DIR
    Define that the key is a directory rather than a ordinary key. This means its executable bits in its mode are set. This option allows the key to have subkeys. See keySetDir().
  • keyswitch_t::KEY_OWNER
    Next parameter is the owner. See keySetOwner().
  • keyswitch_t::KEY_COMMENT
    Next parameter is a comment. See keySetComment().
  • keyswitch_t::KEY_END
    Must be the last parameter passed to keyNew(). It is always required, unless the keyName is 0.
Example:
KeySet *ks=ksNew(0);
ksAppendKey(ks,keyNew(0)); // an empty key
ksAppendKey(ks,keyNew("user/sw", // the name of the key
KEY_END)); // no more args
ksAppendKey(ks,keyNew("user/tmp/ex1",
KEY_VALUE,"some data", // set a string value
KEY_END)); // end of args
ksAppendKey(ks,keyNew("user/tmp/ex2",
KEY_VALUE,"some data", // with a simple value
KEY_MODE,0777, // permissions
KEY_END)); // end of args
ksAppendKey(ks,keyNew("user/tmp/ex4",
KEY_TYPE,KEY_TYPE_BINARY, // key type
KEY_SIZE,7, // assume binary length 7
KEY_VALUE,"some data", // value that will be truncated in 7 bytes
KEY_COMMENT,"value is truncated",
KEY_OWNER,"root", // owner (not uid) is root
KEY_UID,0, // root uid
KEY_END)); // end of args
ksAppendKey(ks,keyNew("user/tmp/ex5",
KEY_TYPE,
KEY_TYPE_DIR | KEY_TYPE_BINARY,// dir key with a binary value
KEY_VALUE,"some data", // value that will be truncated in 7 bytes
KEY_COMMENT,"value is truncated",
KEY_OWNER,"root", // owner (not uid) is root
KEY_UID,0, // root uid
KEY_END)); // end of args
ksDel(ks);

The reference counter (see keyGetRef()) will be initialized with 0, that means a subsequent call of keyDel() will delete the key. If you append the key to a keyset the reference counter will be incremented by one (see keyInc()) and the key can't be be deleted by a keyDel().

Key *k = keyNew(0); // ref counter 0
ksAppendKey(ks, k); // ref counter of key 1
ksDel(ks); // key will be deleted with keyset
*

If you increment only by one with keyInc() the same as said above is valid:

Key *k = keyNew(0); // ref counter 0
keyIncRef(k); // ref counter of key 1
keyDel(k); // has no effect
keyDecRef(k); // ref counter back to 0
keyDel(k); // key is now deleted
*

If you add the key to more keySets:

Key *k = keyNew(0); // ref counter 0
ksAppendKey(ks1, k); // ref counter of key 1
ksAppendKey(ks2, k); // ref counter of key 2
ksDel(ks1); // ref counter of key 1
ksDel(ks2); // k is now deleted
*

or use keyInc() more than once:

Key *k = keyNew(0); // ref counter 0
keyIncRef(k); // ref counter of key 1
keyDel (k); // has no effect
keyIncRef(k); // ref counter of key 2
keyDel (k); // has no effect
keyDecRef(k); // ref counter of key 1
keyDel (k); // has no effect
keyDecRef(k); // ref counter is now 0
keyDel (k); // k is now deleted
*

they key won't be deleted by a keyDel() as long refcounter is not 0.

The key's sync bit will always be set for any call, except:

Key *k = keyNew(0);
// keyNeedSync() will be false
Parameters
keyNamea valid name to the key, or NULL to get a simple initialized, but really empty, object
See Also
keyDel()
Returns
a pointer to a new allocated and initialized Key object.
Return values
NULLon malloc error or if an invalid keyName was passed (see keySetName()).