Git init
[pkgs/e/elektra.git] / src / libelektra / keyvalue.c
1  /***************************************************************************
2                       keyvalue.c  -  Methods for Key manipulation
3                              -------------------
4     begin                : Fri Sep 26 2008
5     copyright            : (C) 2008 by Markus Raab
6     email                : elektra@markus-raab.org
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the BSD License (revised).                      *
13  *                                                                         *
14  ***************************************************************************/
15
16
17
18 /**
19  * @defgroup keyvalue Key :: Value Manipulation Methods
20  * @brief Methods to do various operations on Key values.
21  *
22  * A key can contain a value in different format. The most
23  * likely situation is, that the value is interpreted as
24  * text. Use keyGetString() for that.
25  * You can save any Unicode Symbols and Elektra will
26  * take care that you get the same back, independent of
27  * your current environment.
28  *
29  * In some situations this idea fails. When you need exactly
30  * the same value back without any interpretation of the
31  * characters, there is keySetBinary(). If you use that, its
32  * very likely that your Configuration is not according
33  * to the standard. Also for Numbers, Booleans and Date you
34  * should use keyGetString(). To do so, you might use strtod()
35  * strtol() and then atol() or atof() to convert back.
36  *
37  * To use them:
38  * @code
39 #include <kdb.h>
40  * @endcode
41  *
42  *
43  */
44
45
46
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #if DEBUG && HAVE_STDIO_H
53 #include <stdio.h>
54 #endif
55
56 #ifdef HAVE_STDARG_H
57 #include <stdarg.h>
58 #endif
59
60 #ifdef HAVE_STRING_H
61 #include <string.h>
62 #endif
63
64 #ifdef HAVE_STDLIB_H
65 #include <stdlib.h>
66 #endif
67
68 #include "kdb.h"
69 #include "kdbprivate.h"
70
71
72
73 /******************************************* 
74  *    General value manipulation methods   *
75  *******************************************/
76
77
78
79
80
81 /**
82  * Return a pointer to the real internal @p key value.
83  *
84  * This is a much more efficient version of keyGetString()
85  * keyGetBinary(), and you should use it if you are responsible enough to
86  * not mess up things. You are not allowed to modify anything
87  * in the returned string. If you need a copy of the Value, consider
88  * to use keyGetString() or keyGetBinary() instead.
89  *
90  * @section string String Handling
91  *
92  * If @p key is string (keyIsString()), you may cast the returned as a
93  * @c "char *" because you'll get a NULL terminated regular string.
94  *
95  * keyValue() returns "" in string mode when there is no value. The reason is
96  * @code
97 key=keyNew(0);
98 keySetString(key,"");
99 keyValue(key); // you would expect "" here
100 keyDel(key);
101  * @endcode
102  *
103  * @section binary Binary Data Handling
104  *
105  * If the data is binary, the size of the value must be determined by
106  * keyGetValueSize(), any strlen() operations are not suitable to determine
107  * the size.
108  *
109  * keyValue() returns 0 in binary mode when there is no value. The reason is
110  * @code
111 int i=23;
112 key=keyNew(0);
113 keySetBinary(key, 0, 0);
114 keyValue(key); // you would expect 0 here
115
116 keySetBinary(key,"", 1);
117 keyValue(key); // you would expect "" (a pointer to '\0') here
118
119 keySetBinary(key, (void*)&i, 4);
120 (int*)keyValue(key); // you would expect a pointer to (int)23 here
121 keyDel(key);
122  * @endcode
123  *
124  * @note Note that the Key structure keeps its own size field that is calculated
125  * by library internal calls, so to avoid inconsistencies, you
126  * must never use the pointer returned by keyValue() method to set a new
127  * value. Use keySetString() or keySetBinary() instead.
128  *
129  * @warning Binary keys will return a NULL pointer when there is no data in contrast
130  * to keyName(), keyBaseName(), keyOwner() and keyComment(). For string value the
131  * behaviour is the same.
132  *
133  * @par Example:
134  * @code
135 KDB *handle = kdbOpen();
136 KeySet *ks=ksNew(0);
137 Key *current=0;
138
139 kdbGetByName(handle,ks,"system/sw/my",KDB_O_SORT|KDB_O_RECURSIVE);
140
141 ksRewind(ks);
142 while(current=ksNext(ks)) {
143         size_t size=0;
144         
145         if (keyIsBin(current)) {
146                 size=keyGetValueSize(current);
147                 printf("Key %s has a value of size %d bytes. Value: <BINARY>\nComment: %s",
148                         keyName(current),
149                         size,
150                         keyComment(current));
151         } else {
152                 size=kdbiStrLen((char *)keyValue(current));
153                 printf("Key %s has a value of size %d bytes. Value: %s\nComment: %s",
154                         keyName(current),
155                         size,
156                         (char *)keyValue(current),
157                         keyComment(current));
158         }
159 }
160
161 ksDel (ks);
162 kdbClose (handle);
163  * @endcode
164  *
165  * @param key the key object to work with
166  * @return a pointer to internal value
167  * @return "" when there is no data and key is not binary
168  * @return 0 where there is no data and key is binary
169  * @return 0 on NULL pointer
170  * @see keyGetValueSize(), keyGetString(), keyGetBinary()
171  * @ingroup keyvalue
172  */
173 const void *keyValue(const Key *key)
174 {
175         if (!key) return 0;
176
177         if (!key->data)
178         {
179                 /*errno=KDB_ERR_NOKEY;*/
180                 if (keyIsBinary(key)) return 0;
181                 else return "";
182         }
183
184         return key->data;
185 }
186
187
188 const void *takeout_keyValue(Key *key)
189 {
190    void *ret;
191         if (!key) return 0;
192
193         if (!key->data)
194         {
195                 /*errno=KDB_ERR_NOKEY;*/
196                 if (keyIsBinary(key)) return 0;
197                 else return strdup("");
198         }
199
200    ret = key->data;
201    key->data = NULL;
202         return ret;
203 }
204
205
206
207
208 /**
209  * Returns the number of bytes needed to store the key value, including the
210  * NULL terminator.
211  *
212  * It returns the correct size, independent of the Key Type.
213  * If it is a binary there might be '\\0' values in it.
214  *
215  * For an empty string you need one byte to store the ending NULL.
216  * For that reason 1 is returned. This is not true for binary data,
217  * so there might be returned 0 too.
218  *
219  * A binary key has no '\\0' termination. String types have it, so to there
220  * length will be added 1 to have enough space to store it.
221  *
222  * This method can be used with malloc() before keyGetString() or keyGetBinary()
223  * is called.
224  *
225  * @code
226 char *buffer;
227 buffer = malloc (keyGetValueSize (key));
228 // use this buffer to store the value (binary or string)
229 // pass keyGetValueSize (key) for maxSize
230  * @endcode
231  *
232  * @param key the key object to work with
233  * @return the number of bytes needed to store the key value
234  * @return 1 when there is no data and type is not binary
235  * @return 0 when there is no data and type is binary
236  * @return -1 on null pointer
237  * @see keyGetString(), keyGetBinary(), keyValue()
238  * @ingroup keyvalue
239  */
240 ssize_t keyGetValueSize(const Key *key)
241 {
242         if (!key) return -1;
243
244         if (!key->data)
245         {
246                 /*errno=KDB_ERR_NODATA;*/
247                 if (keyIsBinary(key)) return 0;
248                 else return 1;
249         }
250
251         return key->dataSize;
252 }
253
254
255
256
257 /**
258  * Get the value of a key as a string.
259  *
260  * When there is no value inside the string, 1 will
261  * be returned and the returnedString will be empty
262  * "" to avoid programming errors that old strings are
263  * shown to the user.
264  *
265  * For binary values see keyGetBinary() and keyIsBinary().
266  *
267  * @par Example:
268  * @code
269 Key *key = keyNew ("user/keyname", KEY_END);
270 char buffer[300];
271
272 if (keyGetString(key,buffer,sizeof(buffer)) == -1)
273 {
274         // handle error
275 } else {
276         printf ("buffer: %s\n", buffer);
277 }
278  * @endcode
279  *
280  * @param key the object to gather the value from
281  * @param returnedString pre-allocated memory to store a copy of the key value
282  * @param maxSize number of bytes of allocated memory in @p returnedString
283  * @return the number of bytes actually copied to @p returnedString, including
284  *      final NULL
285  * @return 1 if the string is empty
286  * @return -1 on NULL pointer
287  * @return -1 on type mismatch
288  * @return maxSize is 0, too small for string or is larger than SSIZE_MAX
289  * @see keyValue(), keyGetValueSize(), keySetString()
290  * @see keyGetBinary() for working with binary data
291  * @ingroup keyvalue
292  */
293 ssize_t keyGetString(const Key *key, char *returnedString, size_t maxSize)
294 {
295         if (!key) return -1;
296
297         if (!maxSize) return -1;
298         if (!returnedString) return -1;
299         if (maxSize > SSIZE_MAX) return -1;
300
301         if (!keyIsString(key))
302         {
303                 /*errno=KDB_ERR_TYPEMISMATCH;*/
304                 return -1;
305         }
306
307         if (!key->data) {
308                 returnedString[0]=0;
309                 return 1;
310         }
311
312         if (key->dataSize > maxSize) {
313                 /*errno=KDB_ERR_TRUNC;*/
314                 return -1;
315         }
316
317
318         strncpy(returnedString,key->data, maxSize);
319         return key->dataSize;
320 }
321
322
323
324 /**
325  * Set the value for @p key as @p newStringValue.
326  *
327  * The function will allocate and save a private copy of @p newStringValue, so
328  * the parameter can be freed after the call.
329  *
330  * String values will be saved in backend storage, when kdbSetKey() will be
331  * called, in UTF-8 universal encoding, regardless of the program's current
332  * encoding, when compiled with --enable-iconv.
333  *
334  * The type will be set to KEY_TYPE_STRING.
335  * When the type of the key is already a string type it won't be changed.
336  *
337  * @param key the key to set the string value
338  * @param newStringValue NULL-terminated text string to be set as @p key's
339  *      value
340  * @return the number of bytes actually saved in private struct including final
341  *      NULL
342  * @return -1 on NULL pointer
343  * @see keyGetString(), keyValue()
344  * @ingroup keyvalue
345  */
346 ssize_t keySetString(Key *key, const char *newStringValue)
347 {
348         ssize_t ret=0;
349
350         if (!key) return -1;
351
352         if (!newStringValue || newStringValue[0] == '\0') ret=keySetRaw(key,0,0);
353         else ret=keySetRaw(key,newStringValue,kdbiStrLen(newStringValue));
354
355         if (!keyIsString(key)) keySetType(key, KEY_TYPE_STRING);
356
357         return ret;
358 }
359
360
361
362
363
364 /**
365  * Get the value of a key as a binary.
366  *
367  * If the type is not binary -1 will be returned.
368  *
369  * When the binary data is empty (this is not the same as ""!)
370  * 0 will be returned and the returnedBinary will not be changed.
371  *
372  * For string values see keyGetString() and keyIsString().
373  *
374  * When the returnedBinary is to small to hold the data
375  * (its maximum size is given by maxSize),
376  * the returnedBinary will not be changed and -1 is returned.
377  *
378  * @par Example:
379  * @code
380 Key *key = keyNew ("user/keyname", KEY_TYPE, KEY_TYPE_BINARY, KEY_END);
381 char buffer[300];
382
383 if (keyGetBinary(key,buffer,sizeof(buffer)) == -1)
384 {
385         // handle error
386 }
387  * @endcode
388  *
389  * @param key the object to gather the value from
390  * @param returnedBinary pre-allocated memory to store a copy of the key value
391  * @param maxSize number of bytes of pre-allocated memory in @p returnedBinary
392  * @return the number of bytes actually copied to @p returnedBinary
393  * @return 0 if the binary is empty
394  * @return -1 on NULL pointers
395  * @return -1 when maxSize is 0, too small to hold the value or larger than SSIZE_MAX
396  * @return -1 on typing error when the key is not binary
397  * @see keyValue(), keyGetValueSize(), keySetBinary()
398  * @see keyGetString() and keySetString() as preferred alternative to binary
399  * @see keyIsBinary() to see how to check for binary type
400  * @ingroup keyvalue
401  */
402 ssize_t keyGetBinary(const Key *key, void *returnedBinary, size_t maxSize)
403 {
404         if (!key) return -1;
405         if (!returnedBinary) return -1;
406         if (!maxSize) return -1;
407
408         if (maxSize > SSIZE_MAX) return -1;
409
410         if (!keyIsBinary(key))
411         {
412                 /*errno=KDB_ERR_TYPEMISMATCH;*/
413                 return -1;
414         }
415
416         if (!key->data)
417         {
418                 return 0;
419         }
420
421         if (key->dataSize > maxSize)
422         {
423                 /*errno=KDB_ERR_TRUNC;*/
424                 return -1;
425         }
426
427
428         memcpy(returnedBinary,key->data,key->dataSize);
429         return key->dataSize;
430 }
431
432
433
434 /**
435  * Set the value of a key as a binary.
436  *
437  * A private copy of @p newBinary will allocated and saved inside @p key,
438  * so the parameter can be deallocated after the call.
439  *
440  * The @c filesys backend, when used through a kdbSetKey(), will make the
441  * value be kdbbEncoded into a human readable hex-digit text format.
442  *
443  * Consider using a string key instead.
444  *
445  * When newBinary is a NULL pointer the binary will be freed and 0 will
446  * be returned.
447  *
448  * @note When the type of the key is already a binary type it won't be changed.
449  *
450  * @param key the object on which to set the value
451  * @param newBinary is a pointer to any binary data or NULL to free the previous set data
452  * @param dataSize number of bytes to copy from @p newBinary
453  * @return the number of bytes actually copied to internal struct storage
454  * @return 0 when the internal binary was freed
455  * @return -1 on NULL pointer
456  * @return -1 when dataSize is 0 (but newBinary not NULL) or larger than SSIZE_MAX
457  * @see keyGetBinary()
458  * @see keyIsBinary() to check if the type is binary
459  * @see keyGetString() and keySetString() as preferred alternative to binary
460  * @ingroup keyvalue
461  */
462 ssize_t keySetBinary(Key *key, const void *newBinary, size_t dataSize)
463 {
464         ssize_t ret=0;
465
466         if (!key) return -1;
467         if (!dataSize && newBinary) return -1;
468         if (dataSize > SSIZE_MAX) return -1;
469
470         ret = keySetRaw(key,newBinary,dataSize);
471
472         if (!keyIsBinary(key)) keySetType(key, KEY_TYPE_BINARY);
473
474         return ret;
475 }
476
477 /*
478  * Set raw  data as the value of a key.
479  * If NULL pointers are passed, key value is cleaned.
480  * This method will not change or set the key type, and should not be
481  * used unless working with user-defined value types.
482  *
483  * @param key the key object to work with
484  * @param newBinary array of bytes to set as the value
485  * @param dataSize number bytes to use from newBinary, including the final NULL
486  * @return The number of bytes actually set in internall buffer.
487  * @see keySetType(), keySetString(), keySetBinary()
488  * @ingroup keyvalue
489  */
490 ssize_t keySetRaw(Key *key, const void *newBinary, size_t dataSize)
491 {
492         if (!dataSize || !newBinary) {
493                 if (key->data) {
494                         free(key->data);
495                         key->data=0;
496                 }
497                 key->dataSize = 0;
498                 key->flags |= KEY_FLAG_SYNC;
499                 if (keyIsBinary(key)) return 0;
500                 return 1;
501         }
502
503         key->dataSize=dataSize;
504         if (key->data) {
505                 char *p=0;
506                 p=realloc(key->data,key->dataSize);
507                 if (NULL==p) return -1;
508                 key->data=p;
509         } else {
510                 key->data=malloc(key->dataSize);
511         }
512
513         if (!key->data) return -1;
514
515         memcpy(key->data,newBinary,key->dataSize);
516         key->flags |= KEY_FLAG_SYNC;
517         return keyGetValueSize (key);
518 }
519
520
521
522
523
524 /********************************************* 
525  *    General comment manipulation methods   *
526  *********************************************/
527
528
529
530
531 /**
532  * Return a pointer to the real internal @p key comment.
533  *
534  * This is a much more efficient version of keyGetComment() and you
535  * should use it if you are responsible enough to not mess up things.
536  * You are not allowed to change anything in the memory region the
537  * returned pointer points to.
538  *
539  * keyComment() returns "" when there is no keyComment. The reason is
540  * @code
541 key=keyNew(0);
542 keySetComment(key,"");
543 keyComment(key); // you would expect "" here
544 keyDel(key);
545  * @endcode
546  *
547  * See keySetComment() for more information on comments.
548  *
549  * @note Note that the Key structure keeps its own size field that is calculated
550  * by library internal calls, so to avoid inconsistencies, you
551  * must never use the pointer returned by keyComment() method to set a new
552  * value. Use keySetComment() instead.
553  *
554  * @param key the key object to work with
555  * @return a pointer to the internal managed comment
556  * @return "" when there is no comment
557  * @return 0 on NULL pointer
558  * @see keyGetCommentSize() for size and keyGetComment() as alternative
559  * @ingroup keyvalue
560  */
561 const char *keyComment(const Key *key)
562 {
563         if (!key) return 0;
564
565         if (!key->comment)
566         {
567                 /*errno=KDB_ERR_NOKEY;*/
568                 return "";
569         }
570
571         return key->comment;
572 }
573
574
575
576
577 /**
578  * Calculates number of bytes needed to store a key comment, including
579  * final NULL.
580  *
581  * Use this method to know to size for allocated memory to retrieve
582  * a key comment.
583  *
584  * See keySetComment() for more information on comments.
585  *
586  * For an empty key name you need one byte to store the ending NULL.
587  * For that reason 1 is returned.
588  *
589  * @code
590 char *buffer;
591 buffer = malloc (keyGetCommentSize (key));
592 // use this buffer to store the comment
593 // pass keyGetCommentSize (key) for maxSize
594  * @endcode
595  *
596  * @param key the key object to work with
597  * @return number of bytes needed
598  * @return 1 if there is no comment
599  * @return -1 on NULL pointer
600  * @see keyGetComment(), keySetComment()
601  * @ingroup keyvalue
602  */
603 ssize_t keyGetCommentSize(const Key *key)
604 {
605         if (!key) return -1;
606
607         if (!key->comment)
608         {
609                 /*errno=KDB_ERR_NODESC;*/
610                 return 1;
611         }
612
613         return key->commentSize;
614 }
615
616
617
618 /**
619  * Get the key comment.
620  *
621  * @section comment Comments
622  *
623  * A Key comment is description for humans what this key is for. It may be a
624  * textual explanation of valid values, when and why a user or administrator
625  * changed the key or any other text that helps the user or administrator related
626  * to that key.
627  *
628  * Don't depend on a comment in your program. A user is
629  * always allowed to remove or change it in any way he wants to. But you are
630  * allowed or even encouraged to always show the content of the comment
631  * to the user and allow him to change it.
632  *
633  * @param key the key object to work with
634  * @param returnedComment pre-allocated memory to copy the comments to
635  * @param maxSize number of bytes that will fit returnedComment
636  * @return the number of bytes actually copied to @p returnedString, including
637  *      final NULL
638  * @return 1 if the string is empty
639  * @return -1 on NULL pointer
640  * @return -1 if maxSize is 0, not enough to store the comment or when larger then SSIZE_MAX
641  * @see keyGetCommentSize(), keySetComment()
642  * @ingroup keyvalue
643  */
644 ssize_t keyGetComment(const Key *key, char *returnedComment, size_t maxSize)
645 {
646         if (!key) return -1;
647
648         if (!maxSize) return -1;
649         if (!returnedComment) return -1;
650         if (maxSize > SSIZE_MAX) return -1;
651
652
653         if (!key->comment)
654         {
655                 /*errno=KDB_ERR_NODESC;*/
656                 returnedComment[0]=0;
657                 return 1;
658         }
659
660         strncpy(returnedComment,key->comment,maxSize);
661         if (maxSize < key->commentSize) {
662                 /*errno=KDB_ERR_TRUNC;*/
663                 return -1;
664         }
665         return key->commentSize;
666 }
667
668
669
670
671
672 /**
673  * Set a comment for a key.
674  *
675  * A key comment is like a configuration file comment.
676  * See keySetComment() for more information.
677  *
678  * @param key the key object to work with
679  * @param newComment the comment, that can be freed after this call.
680  * @return the number of bytes actually saved including final NULL
681  * @return 1 when the comment was freed
682  * @return -1 on NULL pointer or memory problems
683  * @see keyGetComment()
684  * @ingroup keyvalue
685  */
686 ssize_t keySetComment(Key *key, const char *newComment)
687 {
688         ssize_t size=0;
689
690         if (!key) return -1;
691
692         if (newComment && (size=kdbiStrLen(newComment)) > 1)
693         {
694                 if (key->comment) {
695                         char *p=0;
696                         p=realloc(key->comment,size);
697                         if (NULL==p) {
698                                 key->commentSize = 0;
699                                 /*errno=KDB_ERR_NOMEM;*/
700                                 return -1;
701                         }
702                         key->comment=p;
703                 } else {
704                         key->comment=malloc(size);
705                         if (!key->comment) {
706                                 key->commentSize = 0;
707                                 /*errno=KDB_ERR_NOMEM;*/
708                                 return -1;
709                         }
710                 }
711
712                 strcpy(key->comment,newComment);
713                 key->flags |= KEY_FLAG_SYNC;
714                 key->commentSize=size;
715         } else if (key->comment) {
716                 free(key->comment);
717                 key->comment=0;
718                 key->commentSize=1;
719                 key->flags |= KEY_FLAG_SYNC;
720         }
721         return key->commentSize;
722 }
723