LCOV - code coverage report
Current view: top level - src/bindings/cpp/include - key.hpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 259 266 97.4 %
Date: 2019-09-12 12:28:41 Functions: 55 244 22.5 %

          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

Generated by: LCOV version 1.13