| Elektra 0.11.0

Modules | Macros | Enumerations | Functions
Key

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

## 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.
#define | KDB_PATH_ESCAPE '\\'
| `\` is used as escape character in the key name.

## 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.
Key * | keyCopy (Key *dest, const Key *source, elektraCopyFlags flags)
| Copy or clear a key.
int | keyDel (Key *key)
| A destructor for Key objects.
int | keyClear (Key *key)
| Will clear all internal data of a Key.
uint16_t | keyIncRef (Key *key)
| Increment the reference counter of a Key object.
uint16_t | keyDecRef (Key *key)
| Decrement the reference counter of a Key object.
uint16_t | keyGetRef (const Key *key)
| Return the current reference counter value of a Key object.
int | keyLock (Key *key, elektraLockFlags what)
| Permanently lock parts of a Key.
int | keyIsLocked (const Key *key, elektraLockFlags what)
| Checks which parts of a Key are locked.

## Detailed Description

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

To use it include:

#include <kdb.h>

Key properties are:

- Key name
- Key value
- Key metadata , including but not limited to:
  - Key comment
  - Key owner
  - UID, GID and filesystem-like mode permissions
  - Mode, change and modification times

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

enum 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

enum 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

enum 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

enum 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
}
keyClear
int keyClear(Key *key)
Will clear all internal data of a Key.
Definition key.c:518
keySetString
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

  key | the Key that should be cleared

Return values

  0 | on success
  -1 | on 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);
keyCopy
Key * keyCopy(Key *dest, const Key *source, elektraCopyFlags flags)
Copy or clear a key.
Definition key.c:319
KEY_CP_ALL
@ 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);
keyNew
Key * keyNew(const char *name,...)
A practical way to fully create a Key object in one step.
Definition key.c:144

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

  dest | the key which will be written to
  source | the key which should be copied or NULL to clear the data of `dest`
  flags | specifies which parts of the key should be copied

Returns
  `dest`

Return values

  NULL | on memory allocation problems
  NULL | when 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
  NULL | when `dest` is NULL
  NULL | when both KEY_CP_VALUE and KEY_CP_STRING are set in `flags`
  NULL | when 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

  key | the Key object whose reference counter should get decreased

Returns
  the updated value of the reference counter

Return values

  UINT16_MAX | on NULL pointer
  0 | when 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

  key | the Key object to delete

Return values

  0 | when the Key was freed
  -1 | on 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

  key | the Key whose reference counter to retrieve

Returns
  the value of the `key's` reference counter

Return values

  -1 | on 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

  key | the Key object whose reference counter should be increased

Returns
  the updated value of the reference counter

Return values

  UINT16_MAX | on NULL pointer
  UINT16_MAX | when 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

  key | the Key that should be checked for locks
  what | the parts of the Key that should checked for locks

Returns
  the bits that are locked

Return values

  0 | if nothing is locked
  -1 | on 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

  key | the Key that should be locked
  what | the parts of the Key that should be locked (see above)

Returns
  the bits that were successfully locked

Return values

  0 | if everything was locked before
  -1 | if 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);
keyDel
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_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
  @ 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_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
  @ 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_BINARY,
  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

  name | a valid name to the key (see keySetName())

Returns
  a pointer to a new allocated and initialized Key object.

Return values

  NULL | on 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