$darkmode
Elektra 0.11.0
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_VALUE = 1 << 1 , KEY_FLAGS = 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...
 
uint16_t keyIncRef (Key *key)
 Increment the reference counter of a Key object. More...
 
uint16_t keyDecRef (Key *key)
 Decrement the reference counter of a Key object. More...
 
uint16_t keyGetRef (const Key *key)
 Return the current reference counter value of a Key object. 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.
Copy-On-Write
Keys employ copy-on-write techniques to minimize memory footprint. If keys are copied or duplicated, they will point at the same name and value as the source key. Only if this data is changed, additional memory is allocated.

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_VALUE 

Flag for the key data

KEY_FLAGS 

Allows to define multiple flags at once.

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:518
ssize_t keySetString(Key *key, const char *newStringValue)
Set the value for key as newStringValue.
Definition: keyvalue.c:381
Postcondition
key's name is "/"
key's metadata is empty
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:319
@ KEY_CP_ALL
Definition: kdbenum.c:110

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:144
@ KEY_END
Definition: kdbenum.c:95

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)
dest must not have read-only flags set
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()

uint16_t keyDecRef ( Key *  key)

Decrement the reference counter of a Key object.

As long as the reference counter is non-zero, keyDel() operations on key will be a no-op and return an error code.

Postcondition
key's reference counter is >= 0
key's reference counter is < SSIZE_MAX
Parameters
keythe Key object whose reference counter should get decreased
Returns
the updated value of the reference counter
Return values
UINT16_MAXon NULL pointer
0when the reference counter already was the minimum value 0, the reference counter will not be modified in this case
Since
1.0.0
See also
keyGetRef() to retrieve the current reference count
keyIncRef() for increasing the reference counter and for a more complete explanation of the reference counting system
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().

When the reference counter of key is non-zero, this function will do nothing and simply return the current value of the reference counter.

It is therefore safe to call keyDel (k) on any Key * k.

Postcondition
all memory related to key will be freed
Parameters
keythe Key object to delete
Return values
0when the Key was freed
-1on NULL pointers
Returns
the value of the reference counter, if it was non-zero
Since
1.0.0
See also
keyNew() for creating a new Key
keyIncRef() for more information about the reference counter

◆ keyGetRef()

uint16_t keyGetRef ( const Key *  key)

Return the current reference counter value of a Key object.

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() for increasing the reference counter and for a more complete explanation of the reference counting system
keyDecRef() for decreasing the reference counter

◆ keyIncRef()

uint16_t keyIncRef ( Key *  key)

Increment the reference counter of a Key object.

As long as the reference counter is non-zero, keyDel() operations on key will be a no-op and return an error code.

Elektra's system for reference counting is not based on a concept of shared ownership. It is more similar to a shared lock, where the counter is used to keep track of how many clients hold the lock.

Initially, the reference counter will be 0. This is can be interpreted as the lock being unlocked. When you increment the reference counter, the lock becomes locked and keyDel() is blocked and fails. Only when the reference counter is fully decremented back down to 0 again, will keyDel() work again.

Note
The reference counter can never exceed UINT16_MAX - 1. UINT16_MAX is reserved as an error code.
Postcondition
key's reference counter is > 0
key's reference counter is <= UINT16_MAX - 1
Parameters
keythe Key object whose reference counter should be increased
Returns
the updated value of the reference counter
Return values
UINT16_MAXon NULL pointer
UINT16_MAXwhen the reference counter already was the maximum value UINT16_MAX - 1, the reference counter will not be modified in this case
Since
1.0.0
See also
keyGetRef() to retrieve the current reference count
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.

Postcondition
keyIsLocked(key, what) == what
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:

// Create and initialize a key with a name and nothing else
Key *k=keyNew("user:/some/example", KEY_END);
// work with it
keyDel (k);
int keyDel(Key *key)
A destructor for Key objects.
Definition: key.c:459

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

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:88
  • 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:91
  • KEY_META
    Next two parameter is a metaname and a metavalue. See keySetMeta().
    Key *k=keyNew("user:/tmp/ex3",
    KEY_META, "comment/#0", "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:92
  • 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:90
  • 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
    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_META, "comment/#0", "value is truncated",
    KEY_END); // end of args
    Precondition
    name is a valid Key name
    Variable arguments are a valid combination
    Postcondition
    returns a new, fully initialized Key object with the valid Key name and all data given by variable arguments
    Parameters
    namea valid name to the key (see keySetName())
    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() for deallocating a created Key object
    keySetName() for rules about which names are considered valid