Elektra  0.9.6
Modules | Macros | Enumerations | Functions
Key

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

Collaboration diagram for Key:

Modules

 Meta Info Manipulation Methods
 Methods to do various operations on Key metadata.
 
 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.
 

Macros

#define KDB_PATH_SEPARATOR   '/'
 / is used to separate key names. More...
 
#define KDB_PATH_ESCAPE   '\\'
 \ is used as escape character in the key name. More...
 

Enumerations

enum  elektraKeyFlags {
  KEY_NAME = 1 , KEY_VALUE = 1 << 1 , KEY_FLAGS = 3 , KEY_COMMENT = 1 << 3 ,
  KEY_BINARY = 1 << 4 , KEY_SIZE = 1 << 11 , KEY_META = 1 << 15 , KEY_NULL = 1 << 16 ,
  KEY_END = 0
}
 Allows keyNew() to determine which information comes next. More...
 
enum  elektraCopyFlags {
  KEY_CP_NAME = 1 << 0 , KEY_CP_STRING = 1 << 1 , KEY_CP_VALUE = 1 << 2 , KEY_CP_META = 1 << 3 ,
  KEY_CP_ALL = KEY_CP_NAME | KEY_CP_VALUE | KEY_CP_META
}
 Copy options. More...
 
enum  elektraLockFlags { KEY_LOCK_NAME = 1 << 17 , KEY_LOCK_VALUE = 1 << 18 , KEY_LOCK_META = 1 << 19 }
 Lock options. More...
 
enum  elektraNamespace {
  KEY_NS_NONE = 0 , KEY_NS_CASCADING = 1 , KEY_NS_META = 2 , KEY_NS_SPEC = 3 ,
  KEY_NS_PROC = 4 , KEY_NS_DIR = 5 , KEY_NS_USER = 6 , KEY_NS_SYSTEM = 7 ,
  KEY_NS_DEFAULT = 8
}
 Elektra currently supported Key namespaces. More...
 

Functions

Key * keyNew (const char *name,...)
 A practical way to fully create a Key object in one step. More...
 
Key * keyCopy (Key *dest, const Key *source, elektraCopyFlags flags)
 Copy or clear a key. More...
 
int keyDel (Key *key)
 A destructor for Key objects. More...
 
int keyClear (Key *key)
 Will clear all internal data of a Key. More...
 
ssize_t keyIncRef (Key *key)
 Increment the reference counter of a Key object. More...
 
ssize_t keyDecRef (Key *key)
 Decrement the reference counter of a Key object. More...
 
ssize_t keyGetRef (const Key *key)
 Return how many references the Key has. More...
 
int keyLock (Key *key, elektraLockFlags what)
 Permanently lock parts of a Key. More...
 
int keyIsLocked (const Key *key, elektraLockFlags what)
 Checks which parts of a Key are locked. More...
 

Detailed Description

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

To use it include:

#include <kdb.h>

Key properties are:

ABI
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.
Reference Counting
Every key has its reference counter (see keyGetRef() for longer explanation) that 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 keyIncRef()) and the key can't be deleted by a keyDel().
As you can imagine this refcounting allows you to put the Key in your own data structures. It can be a very powerful feature, e.g. if you need your own-defined ordering or different Models of your configuration.

Macro Definition Documentation

◆ KDB_PATH_ESCAPE

#define KDB_PATH_ESCAPE   '\\'

\ is used as escape character in the key name.

See also
description about key names .

◆ KDB_PATH_SEPARATOR

#define KDB_PATH_SEPARATOR   '/'

/ is used to separate key names.

See also
description about key names .

Enumeration Type Documentation

◆ elektraCopyFlags

Copy options.

See also
keyCopy()
Enumerator
KEY_CP_NAME 

Flag for copying the key name

KEY_CP_STRING 

Flag for copying the key value, if it is a string

KEY_CP_VALUE 

Flag for copying the key value

KEY_CP_META 

Flag for copying the key metadata

KEY_CP_ALL 

Shorthand for copying name, value and metadata

◆ elektraKeyFlags

Allows keyNew() to determine which information comes next.

See also
keyNew()
Enumerator
KEY_NAME 

Flag for the key name

KEY_VALUE 

Flag for the key data

KEY_FLAGS 

Allows to define multiple flags at once.

KEY_COMMENT 

Flag for the key comment

KEY_BINARY 

Flag if the key is binary

KEY_SIZE 

Flag for maximum size to limit value

KEY_META 

Flag for metadata

KEY_NULL 

Is not a flag, only as return value

Deprecated:
do not use
KEY_END 

Used as a parameter terminator to keyNew()

◆ elektraLockFlags

Lock options.

See also
keyLock(), keyIsLocked()
Enumerator
KEY_LOCK_NAME 

lock the name of a key

KEY_LOCK_VALUE 

lock the value of a key

KEY_LOCK_META 

lock the meta data of a key

◆ elektraNamespace

Elektra currently supported Key namespaces.

See also
kdbGet(), keyGetNamespace()
Enumerator
KEY_NS_NONE 

no key given as parameter to keyGetNamespace()

KEY_NS_CASCADING 

cascading key, starts with /, abstract name for any of the namespaces below

KEY_NS_META 

metakey, i.e. any key name not under other categories

KEY_NS_SPEC 

spec contains the specification of the other namespaces

KEY_NS_PROC 

proc contains process-specific configuration

KEY_NS_DIR 

dir contains configuration from a specific directory

KEY_NS_USER 

user key in the home directory of the current user

KEY_NS_SYSTEM 

system key is shared for a computer system

KEY_NS_DEFAULT 

default key used as a fallback if no other key is found

Function Documentation

◆ keyClear()

int keyClear ( Key *  key)

Will clear all internal data of a Key.

After this call you will receive a fresh Key - with no value, metadata or name.

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
}
int keyClear(Key *key)
Will clear all internal data of a Key.
Definition: key.c:562
ssize_t keySetString(Key *key, const char *newStringValue)
Set the value for key as newStringValue.
Definition: keyvalue.c:372
Parameters
keythe Key that should be cleared
Return values
0on success
-1on NULL pointer
Since
1.0.0
See also
keyDel() for completely deleting a Key

◆ keyCopy()

Key* keyCopy ( Key *  dest,
const Key *  source,
elektraCopyFlags  flags 
)

Copy or clear a key.

Depending on the chosen flags keyCopy() only copies certain parts of source into dest.

  • If KEY_CP_NAME is set, the key name will be copied from source to dest.
  • If KEY_CP_META is set, the meta keys will be copied from source to dest.
  • If KEY_CP_VALUE is set, the key value will be copied from source to dest. Additionally, if source is a binary key (keyIsBinary()), dest will also be marked as binary. This means that even if KEY_CP_META is not set, the binary meta key will be copied with KEY_CP_VALUE.
  • If KEY_CP_STRING is set, the key value will be copied from source to dest, but only, if source is not a binary key (keyIsBinary()). If source is binary, keyCopy() fails. If dest is binary, it will still be marked as binary after the copy. This cannot be used together with KEY_CP_VALUE. The main purpose of KEY_CP_STRING is for copying into known string keys. It ensure that you don't accidentally convert string keys into binary keys.

There is also the shorthand KEY_CP_ALL. It is equivalent to KEY_CP_NAME | KEY_CP_VALUE | KEY_CP_META, i.e. all key data supported by keyCopy() will be copied from source to dest.

Use this function 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:

keyCopy (copy, orig, KEY_CP_ALL);
Key * keyCopy(Key *dest, const Key *source, elektraCopyFlags flags)
Copy or clear a key.
Definition: key.c:335
@ KEY_CP_ALL
Definition: kdbenum.c:112

Most often you will want to duplicate an existing key. For this purpose the alias keyDup() exists. Calling

copy = keyDup (orig, KEY_CP_ALL);

is equivalent to

copy = keyCopy (keyNew ("/", KEY_END), orig, KEY_CP_ALL);
Key * keyNew(const char *name,...)
A practical way to fully create a Key object in one step.
Definition: key.c:150
@ KEY_END
Definition: kdbenum.c:97

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

Since metadata uses copy-on-write semantics there is only a constant memory cost to copying metadata.

When you pass a NULL-pointer as source the pieces of dest specified by flags will be cleared.

Calling keyCopy (dest, NULL, KEY_CP_ALL) is different from calling keyClear(). The key will not be fully reset, the reference counter and internal flags will remain unchanged. Additionally, keyCopy() respects keyLock() state, while keyClear() always works.

keyCopy (k, NULL, KEY_CP_ALL);
// name, value and metadata of k have now been clear
// lock flags, reference count, etc. remain unchanged
Precondition
dest must be a valid Key (created with keyNew)
source must be a valid Key or NULL
Invariant
Key name stays valid until delete
Postcondition
Value from Key source is written to Key dest
Parameters
destthe key which will be written to
sourcethe key which should be copied or NULL to clear the data of dest
flagsspecifies which parts of the key should be copied
Returns
dest
Return values
NULLon memory allocation problems
NULLwhen a part of dest that should be modified (e.g. name, value) was marked read-only, e.g. the name of dest will be read-only if dest is part of a KeySet
NULLwhen dest is NULL
NULLwhen both KEY_CP_VALUE and KEY_CP_STRING are set in flags
NULLwhen both KEY_CP_STRING is set in flags and source is a binary key (keyIsBinary())
Since
0.9.5
See also
keyDup() for duplicating an existing Key

◆ keyDecRef()

ssize_t keyDecRef ( Key *  key)

Decrement the reference counter 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 reaches 0. In that situation nothing will happen and 0 will be returned.

Note
keyDup() will reset the references for duplicated Key.
Parameters
keythe Key object whose reference counter should get decreased
Returns
the updated value of the reference counter
Return values
-1on NULL pointer
0when the Key is ready to be freed
Since
1.0.0
See also
keyGetRef() for addtional explanations about reference counting
keyIncRef() for increasing the reference counter
keyDel() for deleting a Key

◆ keyDel()

int keyDel ( Key *  key)

A destructor for Key objects.

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

Keys contained in a KeySet will not be deleted and the number of references will be returned instead.

It is safe to delete a NULL pointer, -1 will be returned then.

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

Parameters
keythe Key object to delete
Returns
the value of the reference counter if the Key is within KeySets
Return values
0when the Key was freed
-1on NULL pointers
Since
1.0.0
See also
keyNew() for creating a new Key
keyIncRef(), keyGetRef() for changing the reference counter of the Key

◆ keyGetRef()

ssize_t keyGetRef ( const Key *  key)

Return how many references the Key has.

The reference counting is the essential property of Keys to make sure that they can be put safely into data structures. E.g. if you put a Key into a KeySet:

Key *k = keyNew("user:/proper_name", KEY_END); // ref counter = 0
KeySet *ks = ksNew (1, k, KS_END);
keyDel(k); // key will not be deleted, because its in the keyset
ksDel(ks); // now the key will be deleted
int keyDel(Key *key)
A destructor for Key objects.
Definition: key.c:509
int ksDel(KeySet *ks)
A destructor for KeySet objects.
Definition: keyset.c:451
KeySet * ksNew(size_t alloc,...)
Allocate, initialize and return a new KeySet object.
Definition: keyset.c:229
#define KS_END
End of a list of keys.
Definition: kdbenum.c:158

You can even add the Key to more KeySets:

Key *k = keyNew("user:/proper_name", KEY_END); // ref counter 0
KeySet *ks1 = ksNew(1, k, KS_END); // ref counter of k 1
KeySet *ks2 = ksNew(1, k, KS_END); // ref counter of k 2
ksDel(ks1); // ref counter of k 1
ksDel(ks2); // k is now deleted

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

Key *k = keyNew("/", KEY_END); // ref counter = 0
keyIncRef(k); // ref counter = 1
keyDel(k); // key will not be deleted
keyDel(k);
ssize_t keyDecRef(Key *key)
Decrement the reference counter of a Key object.
Definition: key.c:657
ssize_t keyIncRef(Key *key)
Increment the reference counter of a Key object.
Definition: key.c:619

or use keyIncRef() more than once:

Key *k = keyNew("/", KEY_END); // 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

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

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

Note
keyDup() will reset the references for duplicated Keys.

For your own applications you can use keyIncRef() and keyDecRef() for reference counting, too.

Parameters
keythe Key whose reference counter to retrieve
Returns
the value of the key's reference counter
Return values
-1on NULL pointer
Since
1.0.0
See also
keyIncRef(), keyDecRef() for increasing / decreasing the reference counter

◆ keyIncRef()

ssize_t keyIncRef ( Key *  key)

Increment the reference counter 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().

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 duplicated Keys.
Parameters
keythe Key object whose reference counter should get increased
Returns
the updated value of the reference counter
Return values
-1on NULL pointer
SSIZE_MAXwhen reference counter reached SSIZE_MAX
Since
1.0.0
See also
keyGetRef() for addtional explanations about reference counting
keyDecRef() for decreasing the reference counter
keyDel() for deleting a Key

◆ keyIsLocked()

int keyIsLocked ( const Key *  key,
elektraLockFlags  what 
)

Checks which parts of a Key are locked.

Parameters
keythe Key that should be checked for locks
whatthe parts of the Key that should checked for locks
Returns
the bits that are locked
Return values
0if nothing is locked
-1on error (NULL pointer)
Since
1.0.0
See also
keyLock() for locking a Key

◆ keyLock()

int keyLock ( Key *  key,
elektraLockFlags  what 
)

Permanently lock parts of a Key.

This can be:

  • KEY_LOCK_NAME to lock the name
  • KEY_LOCK_VALUE to lock the value
  • KEY_LOCK_META to lock the metadata

To unlock the Key, duplicate it.

It is also possible to lock the Key when it is created with keyNew().

Some data structures need to lock the Key (most likely its name), so that the ordering does not get confused.

Parameters
keythe Key that should be locked
whatthe parts of the Key that should be locked (see above)
Returns
the bits that were successfully locked
Return values
0if everything was locked before
-1if it could not be locked (NULL pointer)
Since
1.0.0
See also
keyIsLocked() for checking whether a Key is locked
keyNew() for creating a new Key
keyDup() for duplicating an existing Key
ksAppendKey() appends a Key to a KeySet (and locks it)

◆ keyNew()

Key* keyNew ( const char *  name,
  ... 
)

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

To just get a key object, simple do:

Key *k = keyNew("/", KEY_END);
// work with it
keyDel (k);

keyNew() allocates memory for a key object and keyDel() cleans everything up.

We can also give an empty key name and a KEY_END tag with the same effect as before:

Key *k =keyNew("", KEY_END); // Has the same effect as above
// work with it
keyDel (k);

But we can also give the key a proper name right from the start:

// Create and initialize a key with a name and nothing else
Key *k=keyNew("user:/some/example", KEY_END);
// 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 to keyDup() the key.

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

  • KEY_VALUE
    Next parameter is a pointer to the value that will be used. If no KEY_BINARY was used before, a string is assumed.
    // Create and initialize a key with a name and nothing else
    Key *k=keyNew("user:/tmp/ex0",
    KEY_VALUE, "some data", // set a string value
    KEY_END); // end of args
    @ KEY_VALUE
    Definition: kdbenum.c:89
  • KEY_SIZE
    Define a maximum length of the value. This is only used when setting a binary key.
    // Create and initialize a key with a name and nothing else
    Key *k=keyNew("user:/tmp/ex1",
    KEY_SIZE, 4, // has no effect on strings
    KEY_VALUE, "some data", // set a string value
    KEY_END); // end of args
    @ KEY_SIZE
    Definition: kdbenum.c:93
  • KEY_META
    Next two parameter is a metaname and a metavalue. See keySetMeta().
    Key *k=keyNew("user:/tmp/ex3",
    KEY_META, "comment", "a comment", // with a comment
    KEY_META, "owner", "root", // and an owner
    KEY_META, "special", "yes", // and any other metadata
    KEY_END); // end of args
    @ KEY_META
    Definition: kdbenum.c:94
  • KEY_END
    Must be the last parameter passed to keyNew(). It is always required, unless the keyName is 0.
  • KEY_FLAGS
    Bitwise disjunction of flags, which don't require one or more values. recommended way to set multiple flags. overrides previously defined flags.
    Key *k=keyNew("user:/tmp/ex3",
    KEY_BINARY, // binary key
    KEY_SIZE, 7, // assume binary length 7
    KEY_VALUE, "some data", // value that will be truncated in 7 bytes
    KEY_END); // end of args
    @ KEY_BINARY
    Definition: kdbenum.c:92
  • KEY_BINARY
    Allows one to change the key to a binary key. Make sure that you also pass KEY_SIZE before you set the value. Otherwise it will be cut off with first \0 in the string. So this flag toggle from keySetString() to keySetBinary(). If no value (nor size) is given, it will be a NULL key.

    // Create and initialize a key with a name and nothing else
    Key *k=keyNew("user:/tmp/ex2",
    KEY_SIZE, 4, // now the size is important
    KEY_VALUE, "some data", // sets the binary value ("some")
    KEY_END); // end of args
    Deprecated:
    The flags below are deprecated and KEY_META should be preferred. They remain some time, however, for compatibility:
  • KEY_COMMENT
    Next parameter is a comment. See keySetComment().
    Key *k=keyNew("user:/tmp/ex4",
    KEY_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_END); // end of args
    @ KEY_COMMENT
    Definition: kdbenum.c:91
Parameters
namea valid name to the key, or NULL to get a simple initialized, but really empty, object
Returns
a pointer to a new allocated and initialized Key object.
Return values
NULLon allocation error or if an invalid name was passed (see keySetName()).
Since
1.0.0
See also
keyDel()