Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #ifndef ELEKTRA_KEY_HPP
10 : #define ELEKTRA_KEY_HPP
11 :
12 : #include <cstdarg>
13 : #include <cstring>
14 : #include <functional>
15 : #include <locale>
16 : #include <sstream>
17 : #include <string>
18 :
19 : #include <keyexcept.hpp>
20 :
21 : #include <kdb.h>
22 :
23 : namespace kdb
24 : {
25 :
26 : #ifndef ELEKTRA_WITHOUT_ITERATOR
27 : class NameIterator;
28 : class NameReverseIterator;
29 : #endif
30 :
31 : /**
32 : * @copydoc key
33 : *
34 : * This class is an wrapper for an optional, refcounted ckdb::Key.
35 : * It is like an shared_ptr<ckdb::Key>, but the
36 : * shared_ptr functionality is already within the Key and exposed
37 : * with this wrapper.
38 : *
39 : * @par optional
40 : * A key can be constructed with an null pointer, by using
41 : * Key (static_cast<ckdb::Key*>(0));
42 : * or made empty afterwards by using release() or assign a null key.
43 : * To check if there is an associated managed object the user
44 : * can use isNull().
45 : *
46 : * @par references
47 : * Copies of keys are cheap because they are only flat.
48 : * If you really need a deep copy, you can use copy() or dup().
49 : * If you release() an object, the reference counter will
50 : * stay
51 : * All other operations operate on references.
52 : *
53 : * @par documentation
54 : * Note that the documentation is typically copied from the underlying
55 : * function which is wrapped and sometimes extended with C++ specific
56 : * details. So you might find C examples within the C++ documentation.
57 : *
58 : *
59 : * @invariant Key either has a working underlying Elektra Key
60 : * object or a null pointer.
61 : * The Key, however, might be invalid (see isValid()) or null
62 : * (see isNull()).
63 : *
64 : * @note that the reference counting in the keys is mutable,
65 : * so that const keys can be passed around by value.
66 : */
67 : class Key
68 : {
69 : public:
70 : // constructors
71 :
72 : inline Key ();
73 : inline Key (ckdb::Key * k);
74 : inline Key (Key & k);
75 : inline Key (Key const & k);
76 :
77 : inline explicit Key (const char * keyName, ...);
78 : inline explicit Key (const std::string keyName, ...);
79 : inline explicit Key (const char * keyName, va_list ap);
80 :
81 :
82 : // reference handling
83 :
84 : inline void operator++ (int) const;
85 : inline void operator++ () const;
86 :
87 : inline void operator-- (int) const;
88 : inline void operator-- () const;
89 :
90 : inline ssize_t getReferenceCounter () const;
91 :
92 :
93 : // basic methods
94 :
95 :
96 : inline Key & operator= (ckdb::Key * k);
97 : inline Key & operator= (const Key & k);
98 :
99 : inline void copy (const Key & other);
100 : inline void clear ();
101 : inline ckdb::Key * operator-> () const;
102 :
103 : inline Key * operator-> ();
104 :
105 : inline ckdb::Key * getKey () const;
106 : inline ckdb::Key * operator* () const;
107 :
108 : inline ckdb::Key * release ();
109 : inline ckdb::Key * dup () const;
110 : inline ~Key ();
111 :
112 :
113 : // name operations
114 :
115 :
116 : inline std::string getName () const;
117 : inline ssize_t getNameSize () const;
118 :
119 : inline std::string getBaseName () const;
120 : inline ssize_t getBaseNameSize () const;
121 :
122 : inline void setName (const std::string & newName);
123 : inline void addName (const std::string & addedName);
124 : inline void setBaseName (const std::string & baseName);
125 : inline void addBaseName (const std::string & baseName);
126 : inline void delBaseName ();
127 :
128 : inline ssize_t getFullNameSize () const;
129 : inline std::string getFullName () const;
130 :
131 : #ifndef ELEKTRA_WITHOUT_ITERATOR
132 : typedef NameIterator iterator;
133 : typedef NameIterator const_iterator;
134 : typedef NameReverseIterator reverse_iterator;
135 : typedef NameReverseIterator const_reverse_iterator;
136 :
137 : iterator begin ();
138 : const_iterator begin () const;
139 : iterator end ();
140 : const_iterator end () const;
141 : reverse_iterator rbegin ();
142 : const_reverse_iterator rbegin () const;
143 : reverse_iterator rend ();
144 : const_reverse_iterator rend () const;
145 :
146 : const_iterator cbegin () const noexcept;
147 : const_iterator cend () const noexcept;
148 : const_reverse_iterator crbegin () const noexcept;
149 : const_reverse_iterator crend () const noexcept;
150 : #endif // ELEKTRA_WITHOUT_ITERATOR
151 :
152 :
153 : // operators
154 :
155 :
156 : inline bool operator== (const Key & k) const;
157 : inline bool operator!= (const Key & k) const;
158 : inline bool operator< (const Key & other) const;
159 : inline bool operator<= (const Key & other) const;
160 : inline bool operator> (const Key & other) const;
161 : inline bool operator>= (const Key & other) const;
162 :
163 : inline bool isNull () const;
164 : inline operator bool () const;
165 : inline bool needSync () const;
166 :
167 :
168 : // value operations
169 :
170 :
171 : template <class T>
172 : inline T get () const;
173 :
174 : template <class T>
175 : inline void set (T x);
176 :
177 : inline std::string getString () const;
178 : inline void setString (std::string newString);
179 : inline ssize_t getStringSize () const;
180 :
181 : typedef void (*func_t) ();
182 : inline func_t getFunc () const;
183 :
184 : typedef ckdb::Key * (*callback_t) (ckdb::KeySet * ks, ckdb::Key * key, ckdb::Key * found, option_t options);
185 : inline void setCallback (callback_t fct);
186 :
187 : inline const void * getValue () const;
188 : inline std::string getBinary () const;
189 : inline ssize_t getBinarySize () const;
190 : inline ssize_t setBinary (const void * newBinary, size_t dataSize);
191 :
192 :
193 : // metadata
194 : //
195 : //
196 : inline bool hasMeta (const std::string & metaName) const;
197 :
198 : template <class T>
199 : inline T getMeta (const std::string & metaName) const;
200 :
201 : template <class T>
202 : inline void setMeta (const std::string & metaName, T x);
203 :
204 : inline void delMeta (const std::string & metaName);
205 :
206 : inline void copyMeta (const Key & other, const std::string & metaName);
207 : inline void copyAllMeta (const Key & other);
208 :
209 : inline void rewindMeta ();
210 : inline const Key nextMeta ();
211 : inline const Key currentMeta () const;
212 :
213 :
214 : // Methods for Making tests
215 :
216 :
217 : inline bool isValid () const;
218 : inline std::string getNamespace () const;
219 : inline bool isCascading () const;
220 : inline bool isSpec () const;
221 : inline bool isProc () const;
222 : inline bool isDir () const;
223 : inline bool isUser () const;
224 : inline bool isSystem () const;
225 :
226 : inline bool isString () const;
227 : inline bool isBinary () const;
228 :
229 : inline bool isInactive () const;
230 :
231 : inline bool isBelow (const Key & k) const;
232 : inline bool isBelowOrSame (const Key & k) const;
233 : inline bool isDirectBelow (const Key & k) const;
234 :
235 : private:
236 : inline int del ();
237 :
238 : ckdb::Key * key; ///< holds an elektra key
239 : };
240 :
241 :
242 : #ifndef ELEKTRA_WITHOUT_ITERATOR
243 : /**
244 : * For C++ forward Iteration over Names.
245 : * (External Iterator)
246 : * @code
247 : for (std::string s:k3)
248 : {
249 : std::cout << s << std::endl;
250 : }
251 : * @endcode
252 : */
253 : class NameIterator
254 : {
255 : public:
256 : typedef std::string value_type;
257 : typedef std::string reference;
258 : typedef std::string pointer; // STL typedef is required by SWIG
259 : typedef int difference_type; // STL typedef is required by SWIG
260 : typedef std::bidirectional_iterator_tag iterator_category;
261 :
262 9208 : NameIterator (Key const & k, bool last)
263 36832 : : begin (static_cast<const char *> (keyUnescapedName (*k))), end (begin + keyGetUnescapedNameSize (*k)),
264 18416 : current (last ? end : begin)
265 : {
266 9208 : }
267 :
268 4325 : NameIterator (const char * begin_, const char * end_, const char * current_) : begin (begin_), end (end_), current (current_)
269 : {
270 : }
271 :
272 3869 : std::string get () const
273 : {
274 3873 : if (current == end || current == begin - 1) return "";
275 7730 : return std::string (current);
276 : }
277 :
278 : const char * pos () const
279 : {
280 : return current;
281 : }
282 :
283 7852 : const char * findNext () const
284 : {
285 7852 : const char * c = current;
286 7852 : if (c >= end) return end;
287 :
288 7852 : if (c == begin && *c == 0)
289 : {
290 : // special handling of cascading key names
291 355 : return ++c;
292 : }
293 :
294 : do
295 : {
296 44858 : ++c;
297 44858 : } while (c < end && *c != 0);
298 7497 : if (c != end)
299 : {
300 7497 : ++c; // skip past null character
301 : }
302 :
303 : return c;
304 : }
305 :
306 : const char * findPrevious () const
307 : {
308 1389 : const char * c = current;
309 1329 : if (c <= begin) return begin;
310 :
311 1389 : --c; // go from start of string to null
312 : do
313 : {
314 9068 : --c;
315 9068 : } while (c > begin && *c != 0);
316 1389 : if (c != begin && c + 1 != current)
317 : {
318 : ++c; // jump back to not-null
319 : }
320 15 : else if (c == begin && *c == 0)
321 : {
322 : // special handling of cascading key names
323 : return ++c;
324 : }
325 :
326 : return c;
327 : }
328 :
329 : // Forward iterator requirements
330 : reference operator* () const
331 : {
332 3788 : return get ();
333 : }
334 : NameIterator & operator++ ()
335 : {
336 3539 : current = findNext ();
337 : return *this;
338 : }
339 : NameIterator operator++ (int)
340 : {
341 8578 : NameIterator ret (begin, end, current);
342 4289 : current = findNext ();
343 : return ret;
344 : }
345 :
346 : // Bidirectional iterator requirements
347 1317 : NameIterator & operator-- ()
348 : {
349 2634 : current = findPrevious ();
350 1317 : return *this;
351 : }
352 12 : NameIterator operator-- (int)
353 : {
354 24 : NameIterator ret (begin, end, current);
355 24 : current = findPrevious ();
356 12 : return ret;
357 : }
358 :
359 : protected:
360 : const char * begin;
361 : const char * end;
362 : const char * current;
363 : };
364 :
365 :
366 : // Forward iterator requirements
367 : inline bool operator== (const NameIterator & lhs, const NameIterator & rhs)
368 : {
369 2583 : return lhs.pos () == rhs.pos ();
370 : }
371 :
372 : inline bool operator!= (const NameIterator & lhs, const NameIterator & rhs)
373 : {
374 8486 : return lhs.pos () != rhs.pos ();
375 : }
376 :
377 : // some code duplication because std::reverse_iterator
378 : // needs a difference_type
379 : /**
380 : * For C++ reverse Iteration over Names.
381 : * (External Iterator)
382 : */
383 : class NameReverseIterator : private NameIterator
384 : {
385 : public:
386 : typedef std::string value_type;
387 : typedef std::string reference;
388 : typedef std::string pointer; // STL typedef is required by SWIG
389 : typedef int difference_type; // STL typedef is required by SWIG
390 : typedef std::bidirectional_iterator_tag iterator_category;
391 :
392 60 : NameReverseIterator (Key const & k, bool last) : NameIterator (k, last)
393 : {
394 60 : if (!last)
395 : {
396 27 : current = begin - 1;
397 : }
398 : else
399 : {
400 33 : current = findPrevious ();
401 : }
402 60 : }
403 :
404 48 : NameReverseIterator (const char * begin_, const char * end_, const char * current_) : NameIterator (begin_, end_, current_)
405 : {
406 : }
407 :
408 67 : const char * findPrevious () const
409 : {
410 67 : if (current <= begin) return begin - 1;
411 60 : return NameIterator::findPrevious ();
412 : }
413 :
414 : const char * findNext () const
415 : {
416 32 : if (current == begin - 1) return begin;
417 24 : return NameIterator::findNext ();
418 : }
419 :
420 85 : std::string get () const
421 : {
422 93 : if (current == begin - 1) return "";
423 81 : return NameIterator::get ();
424 : }
425 :
426 : const char * pos () const
427 : {
428 92 : return NameIterator::pos ();
429 : }
430 :
431 : // Forward iterator requirements
432 : reference operator* () const
433 : {
434 85 : return get ();
435 : }
436 : NameReverseIterator & operator++ ()
437 : {
438 26 : current = findPrevious ();
439 : return *this;
440 : }
441 : NameReverseIterator operator++ (int)
442 : {
443 16 : NameReverseIterator ret (begin, end, current);
444 8 : current = findPrevious ();
445 : return ret;
446 : }
447 :
448 : // Bidirectional iterator requirements
449 : NameReverseIterator & operator-- ()
450 : {
451 16 : current = findNext ();
452 : return *this;
453 : }
454 : NameReverseIterator operator-- (int)
455 : {
456 32 : NameReverseIterator ret (begin, end, current);
457 16 : current = findNext ();
458 : return ret;
459 : }
460 : };
461 :
462 :
463 : // Forward iterator requirements
464 : inline bool operator== (const NameReverseIterator & lhs, const NameReverseIterator & rhs)
465 : {
466 56 : return lhs.pos () == rhs.pos ();
467 : }
468 :
469 : inline bool operator!= (const NameReverseIterator & lhs, const NameReverseIterator & rhs)
470 : {
471 36 : return lhs.pos () != rhs.pos ();
472 : }
473 :
474 :
475 : inline Key::iterator Key::begin ()
476 : {
477 153 : return Key::iterator (*this, false);
478 : }
479 :
480 : inline Key::const_iterator Key::begin () const
481 : {
482 1676 : return Key::const_iterator (*this, false);
483 : }
484 :
485 : inline Key::iterator Key::end ()
486 : {
487 1477 : return Key::iterator (*this, true);
488 : }
489 :
490 : inline Key::const_iterator Key::end () const
491 : {
492 5842 : return Key::const_iterator (*this, true);
493 : }
494 :
495 : inline Key::reverse_iterator Key::rbegin ()
496 : {
497 20 : return Key::reverse_iterator (*this, true);
498 : }
499 :
500 : inline Key::const_reverse_iterator Key::rbegin () const
501 : {
502 13 : return Key::const_reverse_iterator (*this, true);
503 : }
504 :
505 : inline Key::reverse_iterator Key::rend ()
506 : {
507 14 : return Key::reverse_iterator (*this, false);
508 : }
509 :
510 : inline Key::const_reverse_iterator Key::rend () const
511 : {
512 13 : return Key::const_reverse_iterator (*this, false);
513 : }
514 :
515 : inline Key::const_iterator Key::cbegin () const noexcept
516 : {
517 : return Key::const_iterator (*this, true);
518 : }
519 :
520 : inline Key::const_iterator Key::cend () const noexcept
521 : {
522 : return Key::const_iterator (*this, false);
523 : }
524 :
525 : inline Key::const_reverse_iterator Key::crbegin () const noexcept
526 : {
527 : return Key::const_reverse_iterator (*this, true);
528 : }
529 :
530 : inline Key::const_reverse_iterator Key::crend () const noexcept
531 : {
532 : return Key::const_reverse_iterator (*this, false);
533 : }
534 : #endif // ELEKTRA_WITHOUT_ITERATOR
535 :
536 :
537 : /**
538 : * Constructs an empty, invalid key.
539 : *
540 : * @note That this is not a null key, so the key will
541 : * evaluate to true.
542 : *
543 : * @see isValid(), isNull()
544 : */
545 63300 : inline Key::Key () : key (ckdb::keyNew (nullptr))
546 : {
547 61550 : operator++ ();
548 : }
549 :
550 : /**
551 : * Constructs a key out of a C key.
552 : *
553 : * @note If you pass a null pointer here, the key will
554 : * evaluate to false.
555 : *
556 : * @param k the key to work with
557 : *
558 : * @see isValid(), isNull()
559 : */
560 840222 : inline Key::Key (ckdb::Key * k) : key (k)
561 : {
562 840326 : operator++ ();
563 : }
564 :
565 : /**
566 : * Takes a reference of another key.
567 : *
568 : * The key will not be copied, but the reference
569 : * counter will be increased.
570 : *
571 : * @param k the key to work with
572 : */
573 10494 : inline Key::Key (Key & k) : key (k.key)
574 : {
575 10453 : operator++ ();
576 : }
577 :
578 : /**
579 : * Takes a reference of another key.
580 : *
581 : * The key will not be copied, but the reference
582 : * counter will be increased.
583 : *
584 : * @param k the key to work with
585 : */
586 57811 : inline Key::Key (Key const & k) : key (k.key)
587 : {
588 53820 : operator++ ();
589 : }
590 :
591 : /**
592 : * @copydoc keyNew
593 : *
594 : * @throw bad_alloc if key could not be constructed (allocation problems)
595 : *
596 : * @param keyName the name of the new key
597 : */
598 153666 : inline Key::Key (const char * keyName, ...)
599 : {
600 : va_list ap;
601 :
602 153666 : va_start (ap, keyName);
603 153666 : key = ckdb::keyVNew (keyName, ap);
604 153666 : va_end (ap);
605 :
606 153666 : if (!key) throw std::bad_alloc ();
607 :
608 153666 : operator++ ();
609 153666 : }
610 :
611 : /**
612 : * @copydoc keyNew
613 : *
614 : * @throw bad_alloc if key could not be constructed (allocation problems)
615 : *
616 : * @warning Not supported on some compilers, e.g.
617 : * clang which requires you to only pass non-POD
618 : * in varg lists.
619 : *
620 : * @param keyName the name of the new key
621 : */
622 43778 : inline Key::Key (const std::string keyName, ...)
623 : {
624 : va_list ap;
625 :
626 43778 : va_start (ap, keyName);
627 43778 : key = ckdb::keyVNew (keyName.c_str (), ap);
628 43778 : va_end (ap);
629 :
630 43778 : if (!key) throw std::bad_alloc ();
631 :
632 43778 : operator++ ();
633 43778 : }
634 :
635 : /**
636 : * @copydoc keyNew
637 : *
638 : * @throw bad_alloc if key could not be constructed (allocation problems)
639 : *
640 : * @param keyName the name of the new key
641 : * @param ap the variable argument list pointer
642 : */
643 : inline Key::Key (const char * keyName, va_list ap)
644 : {
645 : key = ckdb::keyVNew (keyName, ap);
646 :
647 : if (!key) throw std::bad_alloc ();
648 :
649 : operator++ ();
650 : }
651 :
652 : /**
653 : * @copydoc keyIncRef
654 : */
655 : void Key::operator++ (int) const
656 : {
657 : operator++ ();
658 : }
659 :
660 : /**
661 : * @copydoc keyIncRef
662 : */
663 : void Key::operator++ () const
664 : {
665 1657948 : ckdb::keyIncRef (key);
666 : }
667 :
668 : /**
669 : * @copydoc keyDecRef
670 : */
671 : void Key::operator-- (int) const
672 : {
673 : operator-- ();
674 : }
675 :
676 : /**
677 : * @copydoc keyDecRef
678 : */
679 : void Key::operator-- () const
680 : {
681 1315385 : ckdb::keyDecRef (key);
682 : }
683 :
684 : /**
685 : * @copydoc keyGetRef
686 : */
687 : inline ssize_t Key::getReferenceCounter () const
688 : {
689 0 : return ckdb::keyGetRef (key);
690 : }
691 :
692 : /**
693 : * Assign a C key.
694 : *
695 : * Will call del() on the old key.
696 : */
697 : inline Key & Key::operator= (ckdb::Key * k)
698 : {
699 300 : if (key != k)
700 : {
701 298 : del ();
702 298 : key = k;
703 : operator++ ();
704 : }
705 : return *this;
706 : }
707 :
708 : /**
709 : * Assign a key.
710 : *
711 : * Will call del() on the old key.
712 : */
713 : inline Key & Key::operator= (const Key & k)
714 : {
715 46153 : if (this != &k)
716 : {
717 488379 : del ();
718 488379 : key = k.key;
719 : operator++ ();
720 : }
721 : return *this;
722 : }
723 :
724 : /**
725 : * @copydoc keyCopy
726 : */
727 : inline void Key::copy (const Key & other)
728 : {
729 4 : ckdb::keyCopy (key, other.key);
730 : }
731 :
732 : /**
733 : * Clears/Invalidates a key.
734 : *
735 : * Afterwards the object is empty again.
736 : *
737 : * @note This is not a null key, so it will
738 : * evaluate to true.
739 : * isValid() will, however, be false.
740 : *
741 : * @see release()
742 : * @see isValid(), isNull()
743 : *
744 : * @copydoc keyClear
745 : */
746 : inline void Key::clear ()
747 : {
748 9 : ckdb::keyClear (key);
749 : }
750 :
751 : /**
752 : * Passes out the raw key pointer.
753 : *
754 : * This pointer can be used to directly change the underlying key
755 : * object.
756 : *
757 : * \note that the ownership remains in the object
758 : */
759 : ckdb::Key * Key::getKey () const
760 : {
761 1472168 : return key;
762 : }
763 :
764 : /**
765 : * Is an abbreviation for getKey.
766 : *
767 : * @copydoc getKey
768 : *
769 : * @see getKey()
770 : */
771 : ckdb::Key * Key::operator* () const
772 : {
773 394513 : return key;
774 : }
775 :
776 : /**
777 : * @returns a pointer to this object
778 : *
779 : * Needed for KeySet iterators.
780 : * @see KeySetIterator
781 : */
782 : Key * Key::operator-> ()
783 : {
784 : return this;
785 : }
786 :
787 : /**
788 : * Passes out the raw key pointer and resets internal key handle.
789 : *
790 : * \note that the ownership is moved outside.
791 : *
792 : * @retval 0 if no key is held (null pointer), no action is done then.
793 : */
794 : ckdb::Key * Key::release ()
795 : {
796 2059 : ckdb::Key * ret = key;
797 2059 : if (key)
798 : {
799 2054 : operator-- ();
800 2054 : key = nullptr;
801 : }
802 : return ret;
803 : }
804 :
805 : /**
806 : * @copydoc keyDup
807 : */
808 : ckdb::Key * Key::dup () const
809 : {
810 19271 : return ckdb::keyDup (getKey ());
811 : }
812 :
813 : /**
814 : * Destructs the key.
815 : *
816 : * @copydoc del()
817 : *
818 : * @see del()
819 : */
820 254709 : inline Key::~Key ()
821 : {
822 1114110 : if (key)
823 : {
824 922072 : del ();
825 : }
826 : }
827 :
828 : /**
829 : * @copydoc keyName
830 : *
831 : * @throw KeyException if key is null
832 : *
833 : * @note unlike in the C version, it is safe to change the returned
834 : * string.
835 : */
836 63154 : inline std::string Key::getName () const
837 : {
838 63154 : if (!key) throw KeyException ();
839 189462 : return std::string (ckdb::keyName (key));
840 : }
841 :
842 : /**
843 : * @copydoc keyGetNameSize
844 : */
845 : inline ssize_t Key::getNameSize () const
846 : {
847 14 : return ckdb::keyGetNameSize (getKey ());
848 : }
849 :
850 :
851 : /**
852 : * @copydoc keyGetBaseNameSize
853 : */
854 : inline ssize_t Key::getBaseNameSize () const
855 : {
856 1098 : return ckdb::keyGetBaseNameSize (getKey ());
857 : }
858 :
859 : /**
860 : * @copydoc keyBaseName
861 : */
862 : inline std::string Key::getBaseName () const
863 : {
864 228008 : return std::string (ckdb::keyBaseName (key));
865 : }
866 :
867 : /**
868 : * @copydoc keySetName
869 : *
870 : * @throw KeyInvalidName if the name is not valid
871 : * */
872 36406 : inline void Key::setName (const std::string & newName)
873 : {
874 72812 : if (ckdb::keySetName (getKey (), newName.c_str ()) == -1)
875 : {
876 24 : throw KeyInvalidName ();
877 : }
878 36394 : }
879 :
880 4884 : inline void Key::addName (const std::string & addedName)
881 : {
882 9768 : if (ckdb::keyAddName (getKey (), addedName.c_str ()) == -1)
883 : {
884 2 : throw KeyInvalidName ();
885 : }
886 4883 : }
887 :
888 : /**Sets a base name for a key.
889 : *
890 : * @copydoc keySetBaseName
891 : *
892 : * @throw KeyInvalidName if the name is not valid
893 : */
894 8 : inline void Key::setBaseName (const std::string & baseName)
895 : {
896 16 : if (ckdb::keySetBaseName (getKey (), baseName.c_str ()) == -1)
897 : {
898 2 : throw KeyInvalidName ();
899 : }
900 7 : }
901 :
902 : /** Adds a base name for a key
903 : *
904 : * @copydoc keyAddBaseName
905 : *
906 : * @throw KeyInvalidName if the name is not valid
907 : */
908 348258 : inline void Key::addBaseName (const std::string & baseName)
909 : {
910 696516 : if (ckdb::keyAddBaseName (getKey (), baseName.c_str ()) == -1)
911 : {
912 2 : throw KeyInvalidName ();
913 : }
914 348257 : }
915 :
916 : /** Delete the baseName of a key.
917 : *
918 : * @throw KeyInvalidName if the name is not valid
919 : */
920 170 : inline void Key::delBaseName ()
921 : {
922 170 : if (ckdb::keySetBaseName (getKey (), 0) == -1)
923 : {
924 0 : throw KeyInvalidName ();
925 : }
926 170 : }
927 :
928 : /**
929 : * @copydoc keyGetFullNameSize
930 : */
931 : inline ssize_t Key::getFullNameSize () const
932 : {
933 4142 : return ckdb::keyGetFullNameSize (getKey ());
934 : }
935 :
936 : /**
937 : * @copydoc keyGetFullName
938 : *
939 : * @throw KeyException if key is null
940 : */
941 4128 : inline std::string Key::getFullName () const
942 : {
943 4128 : ssize_t csize = getFullNameSize ();
944 4128 : if (csize == -1)
945 : {
946 0 : throw KeyException ();
947 : }
948 :
949 4128 : if (csize == 0)
950 : {
951 0 : return "";
952 : }
953 :
954 15500 : std::string str (csize - 1, '\0');
955 12384 : ckdb::keyGetFullName (getKey (), &str[0], csize);
956 4128 : return str;
957 : }
958 :
959 : /**
960 : * @copydoc keyCmp
961 : *
962 : * @retval true == 0
963 : */
964 : inline bool Key::operator== (const Key & k) const
965 : {
966 6476 : return ckdb::keyCmp (key, k.key) == 0;
967 : }
968 :
969 : /**
970 : * @copydoc keyCmp
971 : *
972 : * @retval true != 0
973 : */
974 : inline bool Key::operator!= (const Key & k) const
975 : {
976 79 : return ckdb::keyCmp (key, k.key) != 0;
977 : }
978 :
979 : /**
980 : * @copydoc keyCmp
981 : *
982 : * @retval true < 0
983 : */
984 : inline bool Key::operator< (const Key & other) const
985 : {
986 132525 : return ckdb::keyCmp (key, other.key) < 0;
987 : }
988 :
989 : /**
990 : * @copydoc keyCmp
991 : *
992 : * @retval true <= 0
993 : */
994 : inline bool Key::operator<= (const Key & other) const
995 : {
996 19 : return ckdb::keyCmp (key, other.key) <= 0;
997 : }
998 :
999 : /**
1000 : * @copydoc keyCmp
1001 : *
1002 : * @retval true > 0
1003 : */
1004 : inline bool Key::operator> (const Key & other) const
1005 : {
1006 17 : return ckdb::keyCmp (key, other.key) > 0;
1007 : }
1008 :
1009 : /**
1010 : * @copydoc keyCmp
1011 : *
1012 : * @retval true >= 0
1013 : */
1014 : inline bool Key::operator>= (const Key & other) const
1015 : {
1016 17 : return ckdb::keyCmp (key, other.key) >= 0;
1017 : }
1018 :
1019 :
1020 : /**
1021 : * This is for loops and lookups only.
1022 : *
1023 : * Opposite of isNull()
1024 : *
1025 : * For loops it checks if there are still more keys.
1026 : * For lookups it checks if a key could be found.
1027 : *
1028 : * @warning you should not construct or use null keys
1029 : *
1030 : * @see isNull(), isValid()
1031 : * @return false on null keys
1032 : * @return true otherwise
1033 : */
1034 : inline Key::operator bool () const
1035 : {
1036 615188 : return !isNull ();
1037 : }
1038 :
1039 : /**
1040 : * @brief Checks if C++ wrapper has an underlying key
1041 : *
1042 : * @see operator bool(), isValid()
1043 : * @return true if no underlying key exists
1044 : */
1045 : inline bool Key::isNull () const
1046 : {
1047 615370 : return key == nullptr;
1048 : }
1049 :
1050 : /**
1051 : * @copydoc keyNeedSync
1052 : */
1053 : inline bool Key::needSync () const
1054 : {
1055 18 : return ckdb::keyNeedSync (key);
1056 : }
1057 :
1058 : /**
1059 : * Get a key value.
1060 : *
1061 : * You can write your own template specialication, e.g.:
1062 : * @code
1063 : template <>
1064 : inline QColor Key::get() const
1065 : {
1066 : if (getStringSize() < 1)
1067 : {
1068 : throw KeyTypeConversion();
1069 : }
1070 :
1071 : std::string str = getString();
1072 : QColor c(str.c_str());
1073 : return c;
1074 : }
1075 : * @endcode
1076 : *
1077 : * @copydoc getString
1078 : *
1079 : * This method tries to serialise the string to the given type.
1080 : */
1081 : template <class T>
1082 618 : inline T Key::get () const
1083 : {
1084 1236 : std::string str = getString ();
1085 1236 : std::istringstream ist (str);
1086 618 : ist.imbue (std::locale ("C"));
1087 : T x;
1088 618 : ist >> x; // convert string to type
1089 1212 : if (ist.fail () || !ist.eof ())
1090 : {
1091 56 : throw KeyTypeConversion ();
1092 : }
1093 1180 : return x;
1094 : }
1095 :
1096 : /*
1097 : // TODO: are locale dependent
1098 : // + throw wrong exception (easy to fix though)
1099 : template <>
1100 : inline int Key::get<int>() const
1101 : {
1102 : return stoi(getString());
1103 : }
1104 :
1105 : template <>
1106 : inline long Key::get<long>() const
1107 : {
1108 : return stol(getString());
1109 : }
1110 :
1111 : template <>
1112 : inline long long Key::get<long long>() const
1113 : {
1114 : return stoll(getString());
1115 : }
1116 :
1117 : template <>
1118 : inline unsigned long Key::get<unsigned long>() const
1119 : {
1120 : return stoul(getString());
1121 : }
1122 :
1123 : template <>
1124 : inline unsigned long long Key::get<unsigned long long>() const
1125 : {
1126 : return stoull(getString());
1127 : }
1128 :
1129 : template <>
1130 : inline float Key::get<float>() const
1131 : {
1132 : return stof(getString());
1133 : }
1134 :
1135 : template <>
1136 : inline double Key::get<double>() const
1137 : {
1138 : return stod(getString());
1139 : }
1140 :
1141 : template <>
1142 : inline long double Key::get<long double>() const
1143 : {
1144 : return stold(getString());
1145 : }
1146 : */
1147 :
1148 :
1149 : template <>
1150 : inline std::string Key::get () const
1151 : {
1152 3075 : return getString ();
1153 : }
1154 :
1155 : /**
1156 : * Set a key value.
1157 : *
1158 : * @copydoc setString
1159 : *
1160 : * This method tries to deserialise the string to the given type.
1161 : */
1162 : template <class T>
1163 9138 : inline void Key::set (T x)
1164 : {
1165 18276 : std::ostringstream ost;
1166 9138 : ost.imbue (std::locale ("C"));
1167 9150 : ost << x; // convert type to string
1168 9138 : if (ost.fail ())
1169 : {
1170 0 : throw KeyTypeConversion ();
1171 : }
1172 27414 : setString (ost.str ());
1173 9138 : }
1174 :
1175 : /*
1176 : // TODO: are locale dependent
1177 : template <>
1178 : inline void Key::set(int val)
1179 : {
1180 : setString(std::to_string(val));
1181 : }
1182 :
1183 : template <>
1184 : inline void Key::set(long val)
1185 : {
1186 : setString(std::to_string(val));
1187 : }
1188 :
1189 : template <>
1190 : inline void Key::set(long long val)
1191 : {
1192 : setString(std::to_string(val));
1193 : }
1194 :
1195 : template <>
1196 : inline void Key::set(unsigned val)
1197 : {
1198 : setString(std::to_string(val));
1199 : }
1200 :
1201 : template <>
1202 : inline void Key::set(unsigned long val)
1203 : {
1204 : setString(std::to_string(val));
1205 : }
1206 :
1207 : template <>
1208 : inline void Key::set(unsigned long long val)
1209 : {
1210 : setString(std::to_string(val));
1211 : }
1212 :
1213 : template <>
1214 : inline void Key::set(float val)
1215 : {
1216 : setString(std::to_string(val));
1217 : }
1218 :
1219 : template <>
1220 : inline void Key::set(double val)
1221 : {
1222 : setString(std::to_string(val));
1223 : }
1224 :
1225 : template <>
1226 : inline void Key::set(long double val)
1227 : {
1228 : setString(std::to_string(val));
1229 : }
1230 : */
1231 :
1232 :
1233 : /**
1234 : * @return the string directly from the key.
1235 : *
1236 : * It should be the same as get().
1237 : * @return empty string on null pointers
1238 : *
1239 : * @throw KeyException on null key or not a valid size
1240 : * @throw KeyTypeMismatch if key holds binary data and not a string
1241 : *
1242 : * @note unlike in the C version, it is safe to change the returned
1243 : * string.
1244 : *
1245 : * @see isString(), getBinary()
1246 : */
1247 239028 : inline std::string Key::getString () const
1248 : {
1249 239028 : ssize_t csize = getStringSize ();
1250 239028 : if (csize == -1)
1251 : {
1252 0 : throw KeyException ();
1253 : }
1254 :
1255 239028 : if (csize == 0)
1256 : {
1257 8 : return "";
1258 : }
1259 :
1260 954053 : std::string str (csize - 1, '\0');
1261 717072 : if (ckdb::keyGetString (getKey (), &str[0], csize) == -1)
1262 : {
1263 6 : throw KeyTypeMismatch ();
1264 : }
1265 239021 : return str;
1266 : }
1267 :
1268 : /**
1269 : * @copydoc keyGetValueSize()
1270 : */
1271 : inline ssize_t Key::getStringSize () const
1272 : {
1273 239235 : return ckdb::keyGetValueSize (key);
1274 : }
1275 :
1276 : /**
1277 : * Elektra can store function pointers as binary.
1278 : * This function returns such a function pointer.
1279 : *
1280 : * @throw KeyTypeMismatch if no binary data found, or binary data has not correct length
1281 : *
1282 : * @return a function pointer stored with setBinary()
1283 : */
1284 78700 : inline Key::func_t Key::getFunc () const
1285 : {
1286 : union
1287 : {
1288 : Key::func_t f;
1289 : void * v;
1290 : } conversation;
1291 : static_assert (sizeof (conversation) == sizeof (func_t), "union does not have size of function pointer");
1292 :
1293 78700 : if (ckdb::keyGetBinary (getKey (), &conversation.v, sizeof (conversation)) != sizeof (conversation)) throw KeyTypeMismatch ();
1294 :
1295 78700 : return conversation.f;
1296 : }
1297 :
1298 :
1299 299 : inline void Key::setCallback (callback_t fct)
1300 : {
1301 : union
1302 : {
1303 : callback_t f;
1304 : void * v;
1305 : } conversation;
1306 : static_assert (sizeof (conversation) == sizeof (callback_t), "union does not have size of function pointer");
1307 :
1308 299 : conversation.f = fct;
1309 299 : ckdb::keySetBinary (getKey (), &conversation.v, sizeof (conversation));
1310 299 : ckdb::keySetMeta (getKey (), "callback", "");
1311 299 : }
1312 :
1313 :
1314 : /**
1315 : * @copydoc keySetString
1316 : */
1317 : inline void Key::setString (std::string newString)
1318 : {
1319 24348 : ckdb::keySetString (getKey (), newString.c_str ());
1320 : }
1321 :
1322 : /**
1323 : * @copydoc keyValue
1324 : *
1325 : * @return the value of the key
1326 : * @see getBinary()
1327 : */
1328 : inline const void * Key::getValue () const
1329 : {
1330 846 : return ckdb::keyValue (getKey ());
1331 : }
1332 :
1333 : /**
1334 : * @returns the binary Value of the key.
1335 : *
1336 : * @retval "" on null pointers (size == 0) and on data only containing \\0
1337 : *
1338 : * @note if you need to distinguish between null pointers and data
1339 : * containing \\0 you can use getValue().
1340 : *
1341 : * @throw KeyException on invalid binary size
1342 : * @throw KeyTypeMismatch if key is string and not a binary
1343 : *
1344 : * @copydoc keyGetBinary
1345 : *
1346 : * @see isBinary(), getString(), getValue()
1347 : **/
1348 681 : inline std::string Key::getBinary () const
1349 : {
1350 681 : ssize_t csize = getBinarySize ();
1351 681 : if (csize == -1)
1352 : {
1353 0 : throw KeyException ();
1354 : }
1355 :
1356 681 : if (csize == 0)
1357 : {
1358 8 : return "";
1359 : }
1360 :
1361 2135 : std::string str (csize, '\0');
1362 2031 : if (ckdb::keyGetBinary (getKey (), &str[0], csize) == -1)
1363 : {
1364 6 : throw KeyTypeMismatch ();
1365 : }
1366 674 : return str;
1367 : }
1368 :
1369 : /**
1370 : * @copydoc keyGetValueSize()
1371 : */
1372 : inline ssize_t Key::getBinarySize () const
1373 : {
1374 3381 : return ckdb::keyGetValueSize (key);
1375 : }
1376 :
1377 : /**
1378 : * @copydoc keySetBinary
1379 : */
1380 : inline ssize_t Key::setBinary (const void * newBinary, size_t dataSize)
1381 : {
1382 143 : return ckdb::keySetBinary (getKey (), newBinary, dataSize);
1383 : }
1384 :
1385 :
1386 : /**
1387 : * @copydoc keyGetMeta
1388 : *
1389 : * You can specify your own template specialisation:
1390 : * @code
1391 : template<>
1392 : inline yourtype Key::getMeta(const std::string &name) const
1393 : {
1394 : yourtype x;
1395 : std::string str;
1396 : str = std::string(
1397 : static_cast<const char*>(
1398 : ckdb::keyValue(
1399 : ckdb::keyGetMeta(key, name.c_str())
1400 : )
1401 : )
1402 : );
1403 : return yourconversion(str);
1404 : }
1405 : * @endcode
1406 : *
1407 : * @throw KeyTypeConversion if metadata could not be parsed
1408 : *
1409 : * @note No exception will be thrown if a const Key or char* is requested,
1410 : * but don't forget the const: getMeta<const Key>,
1411 : * otherwise you will get an compiler error.
1412 : *
1413 : * If no meta is available:
1414 : * - char* is null (evaluates to 0)
1415 : * - const Key is null (evaluate to false)
1416 : * - otherwise the default constructed type will be returned
1417 : * @see hasMeta
1418 : *
1419 : * @see delMeta(), setMeta(), copyMeta(), copyAllMeta()
1420 : */
1421 : template <class T>
1422 43 : inline T Key::getMeta (const std::string & metaName) const
1423 : {
1424 129 : Key k (const_cast<ckdb::Key *> (ckdb::keyGetMeta (key, metaName.c_str ())));
1425 43 : if (!k)
1426 : {
1427 : return T ();
1428 : }
1429 34 : return k.get<T> ();
1430 : }
1431 :
1432 :
1433 : /**
1434 : * @retval true if there is a metadata with given name
1435 : * @retval false if no such metadata exists
1436 : *
1437 : *@see getMeta()
1438 : */
1439 3335 : inline bool Key::hasMeta (const std::string & metaName) const
1440 : {
1441 10005 : Key k (const_cast<ckdb::Key *> (ckdb::keyGetMeta (key, metaName.c_str ())));
1442 6670 : return k;
1443 : }
1444 :
1445 : template <>
1446 : inline const ckdb::Key * Key::getMeta (const std::string & name) const
1447 : {
1448 64 : return ckdb::keyGetMeta (key, name.c_str ());
1449 : }
1450 :
1451 : template <>
1452 : inline const Key Key::getMeta (const std::string & name) const
1453 : {
1454 5796 : const ckdb::Key * k = ckdb::keyGetMeta (key, name.c_str ());
1455 5796 : return Key (const_cast<ckdb::Key *> (k));
1456 : }
1457 :
1458 : template <>
1459 : inline const char * Key::getMeta (const std::string & name) const
1460 : {
1461 4 : return static_cast<const char *> (ckdb::keyValue (ckdb::keyGetMeta (key, name.c_str ())));
1462 : }
1463 :
1464 : template <>
1465 2554 : inline std::string Key::getMeta (const std::string & name) const
1466 : {
1467 2554 : const char * v = static_cast<const char *> (ckdb::keyValue (ckdb::keyGetMeta (key, name.c_str ())));
1468 2554 : if (!v)
1469 : {
1470 : return std::string ();
1471 : }
1472 2543 : std::string str;
1473 10172 : str = std::string (v);
1474 2543 : return str;
1475 : }
1476 :
1477 : /**
1478 : * Set metadata for key.
1479 : *
1480 : * @copydoc keySetMeta
1481 : *
1482 : * @warning unlike the C Interface, it is not possible to remove
1483 : * metadata with this method.
1484 : * k.setMeta("something", NULL) will lead to set the number 0 or to
1485 : * something different (may depend on compiler definition of NULL).
1486 : * See discussion in Issue
1487 : * https://github.com/ElektraInitiative/libelektra/issues/8
1488 : *
1489 : * Use delMeta() to avoid these issues.
1490 : *
1491 : * @see delMeta(), getMeta(), copyMeta(), copyAllMeta()
1492 : */
1493 : template <class T>
1494 4910 : inline void Key::setMeta (const std::string & metaName, T x)
1495 : {
1496 9820 : Key k;
1497 6910 : k.set<T> (x);
1498 19640 : ckdb::keySetMeta (key, metaName.c_str (), k.getString ().c_str ());
1499 4910 : }
1500 :
1501 : /**
1502 : * Delete metadata for key.
1503 : *
1504 : * @see setMeta(), getMeta(), copyMeta(), copyAllMeta()
1505 : */
1506 : inline void Key::delMeta (const std::string & metaName)
1507 : {
1508 1137 : ckdb::keySetMeta (key, metaName.c_str (), nullptr);
1509 : }
1510 :
1511 : /**
1512 : * @copydoc keyCopyMeta
1513 : *
1514 : * @see getMeta(), setMeta(), copyAllMeta()
1515 : */
1516 : inline void Key::copyMeta (const Key & other, const std::string & metaName)
1517 : {
1518 16 : ckdb::keyCopyMeta (key, other.key, metaName.c_str ());
1519 : }
1520 :
1521 : /**
1522 : * @copydoc keyCopyAllMeta
1523 : *
1524 : * @see getMeta(), setMeta(), copyMeta()
1525 : */
1526 : inline void Key::copyAllMeta (const Key & other)
1527 : {
1528 4 : ckdb::keyCopyAllMeta (key, other.key);
1529 : }
1530 :
1531 : /**
1532 : * @copydoc keyRewindMeta
1533 : *
1534 : * @see nextMeta(), currentMeta()
1535 : */
1536 : inline void Key::rewindMeta ()
1537 : {
1538 4043 : ckdb::keyRewindMeta (key);
1539 : }
1540 :
1541 : /**
1542 : * @copydoc keyNextMeta
1543 : *
1544 : * @see rewindMeta(), currentMeta()
1545 : */
1546 : inline const Key Key::nextMeta ()
1547 : {
1548 6746 : const ckdb::Key * k = ckdb::keyNextMeta (key);
1549 6746 : return Key (const_cast<ckdb::Key *> (k));
1550 : }
1551 :
1552 :
1553 : /**
1554 : * @copydoc keyCurrentMeta
1555 : *
1556 : * @note that the key will be null if last metadata is found.
1557 : *
1558 : * @code
1559 : * k.rewindMeta();
1560 : * while (meta = k.nextMeta())
1561 : * {
1562 : * cout << meta.getName() << " " << meta.getString() << endl;
1563 : * }
1564 : * @endcode
1565 : *
1566 : * @see rewindMeta(), nextMeta()
1567 : */
1568 : inline const Key Key::currentMeta () const
1569 : {
1570 782 : return Key (const_cast<ckdb::Key *> (ckdb::keyCurrentMeta (const_cast<const ckdb::Key *> (key))));
1571 : }
1572 :
1573 :
1574 : /** @return if the key is valid
1575 : *
1576 : * An invalid key has no name.
1577 : * The name of valid keys either start with user or system.
1578 : *
1579 : * @retval true if the key has a valid name
1580 : * @retval false if the key has an invalid name
1581 : *
1582 : * @see getName(), isUser(), isSystem(), getNamespace()
1583 : */
1584 : inline bool Key::isValid () const
1585 : {
1586 5473 : return ckdb::keyGetNameSize (getKey ()) > 1;
1587 : }
1588 :
1589 : /**
1590 : * @return namespace as string
1591 : *
1592 : * Will return slash for cascading names.
1593 : *
1594 : * @see getName(), isUser(), isSystem()
1595 : */
1596 14887 : inline std::string Key::getNamespace () const
1597 : {
1598 29774 : std::string name = getName ();
1599 14887 : size_t slash = name.find ('/');
1600 15414 : if (slash == 0) return "/";
1601 14360 : if (slash != std::string::npos) return name.substr (0, slash);
1602 : return name;
1603 : }
1604 :
1605 :
1606 : /**
1607 : * Determines if the key is in cascading namespace.
1608 : *
1609 : * @retval true if it is a cascading key
1610 : * @retval false otherwise
1611 : */
1612 : inline bool Key::isCascading () const
1613 : {
1614 341 : return ckdb::keyGetNamespace (getKey ()) == KEY_NS_CASCADING;
1615 : }
1616 :
1617 : /**
1618 : * Determines if the key is in spec namespace.
1619 : *
1620 : * @retval true if it is a spec key
1621 : * @retval false otherwise
1622 : */
1623 : inline bool Key::isSpec () const
1624 : {
1625 556 : return ckdb::keyGetNamespace (getKey ()) == KEY_NS_SPEC;
1626 : }
1627 :
1628 : /**
1629 : * Determines if the key is in proc namespace.
1630 : *
1631 : * @retval true if it is a proc key
1632 : * @retval false otherwise
1633 : */
1634 : inline bool Key::isProc () const
1635 : {
1636 14 : return ckdb::keyGetNamespace (getKey ()) == KEY_NS_PROC;
1637 : }
1638 :
1639 : /**
1640 : * Determines if the key is in dir namespace.
1641 : *
1642 : * @retval true if it is a dir key
1643 : * @retval false otherwise
1644 : */
1645 : inline bool Key::isDir () const
1646 : {
1647 14 : return ckdb::keyGetNamespace (getKey ()) == KEY_NS_DIR;
1648 : }
1649 :
1650 : /**
1651 : * Determines if the key is in user namespace.
1652 : *
1653 : * @retval true if it is a user key
1654 : * @retval false otherwise
1655 : */
1656 : inline bool Key::isUser () const
1657 : {
1658 17 : return ckdb::keyGetNamespace (getKey ()) == KEY_NS_USER;
1659 : }
1660 :
1661 : /**
1662 : * Determines if the key is in system namespace.
1663 : *
1664 : * @retval true if it is a system key
1665 : * @retval false otherwise
1666 : */
1667 : inline bool Key::isSystem () const
1668 : {
1669 82 : return ckdb::keyGetNamespace (getKey ()) == KEY_NS_SYSTEM;
1670 : }
1671 :
1672 : /**
1673 : * @copydoc keyIsString
1674 : */
1675 : inline bool Key::isString () const
1676 : {
1677 1561 : return ckdb::keyIsString (key);
1678 : }
1679 :
1680 : /**
1681 : * @copydoc keyIsBinary
1682 : */
1683 : inline bool Key::isBinary () const
1684 : {
1685 4454 : return ckdb::keyIsBinary (key);
1686 : }
1687 :
1688 : /**
1689 : * @copydoc keyIsInactive
1690 : */
1691 : inline bool Key::isInactive () const
1692 : {
1693 4 : return ckdb::keyIsInactive (key);
1694 : }
1695 :
1696 : /**
1697 : * @param k the other key
1698 : * @return true if our key is below k
1699 : *
1700 : * @copydoc keyIsBelow
1701 : */
1702 : inline bool Key::isBelow (const Key & k) const
1703 : {
1704 475876 : int ret = ckdb::keyIsBelow (k.getKey (), key);
1705 237938 : if (ret == -1) return false;
1706 237938 : return ret;
1707 : }
1708 :
1709 : /**
1710 : * @param k the other key
1711 : * @return true if our key is below k or the same as k
1712 : *
1713 : * @copydoc keyIsBelowOrSame
1714 : */
1715 : inline bool Key::isBelowOrSame (const Key & k) const
1716 : {
1717 13234 : int ret = ckdb::keyIsBelowOrSame (k.getKey (), key);
1718 6617 : if (ret == -1) return false;
1719 6617 : return ret;
1720 : }
1721 :
1722 : /**
1723 : * @param k the other key
1724 : * @return true if our key is direct below k
1725 : *
1726 : * @copydoc keyIsDirectBelow
1727 : */
1728 : inline bool Key::isDirectBelow (const Key & k) const
1729 : {
1730 22590 : int ret = ckdb::keyIsDirectBelow (k.getKey (), key);
1731 11295 : if (ret == -1) return false;
1732 11295 : return ret;
1733 : }
1734 :
1735 : /**
1736 : * Deallocate the key if the reference counter reached zero.
1737 : *
1738 : * If there are still references, the function will only
1739 : * decrement the reference counter.
1740 : *
1741 : * @retval -1 if no key is held (null pointer)
1742 : *
1743 : * @copydoc keyDel
1744 : */
1745 1410822 : inline int Key::del ()
1746 : {
1747 1410822 : if (key)
1748 : {
1749 1313331 : operator-- ();
1750 1313331 : return ckdb::keyDel (key);
1751 : }
1752 : return -1;
1753 : }
1754 :
1755 :
1756 : } // end of namespace kdb
1757 :
1758 :
1759 : namespace std
1760 : {
1761 : /**
1762 : * @brief Support for putting Key in a hash
1763 : */
1764 : template <>
1765 : struct hash<kdb::Key>
1766 : {
1767 62 : size_t operator() (kdb::Key const & k) const
1768 : {
1769 : // use key name as hash value
1770 186 : return std::hash<std::string> () (k.getName ());
1771 : }
1772 : };
1773 : } // end of namespace std
1774 :
1775 : #endif
|