Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Key helper functions
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include <helper/keyhelper.hpp>
11 :
12 : using namespace std;
13 :
14 : namespace kdb
15 : {
16 :
17 : namespace tools
18 : {
19 :
20 : namespace helper
21 : {
22 :
23 5611 : string rebasePath (const Key & key, const Key & oldParent, const Key & newParent)
24 : {
25 11222 : string oldKeyPath = key.getName ();
26 :
27 16833 : Key actualOldParent = oldParent.dup ();
28 16833 : if (oldParent.getNamespace () == "/")
29 : {
30 352 : actualOldParent.setName (key.getNamespace () + oldParent.getName ());
31 : }
32 :
33 16833 : Key actualNewParent = newParent.dup ();
34 16833 : if (newParent.getNamespace () == "/")
35 : {
36 336 : actualNewParent.setName (key.getNamespace () + newParent.getName ());
37 : }
38 :
39 5611 : if (!key.isBelowOrSame (actualOldParent))
40 20 : throw InvalidRebaseException ("the supplied key " + key.getName () + " is not below the old parent " +
41 12 : actualOldParent.getName ());
42 :
43 11214 : string relativePath;
44 5607 : if (oldKeyPath[0] == '/')
45 : {
46 4 : string actualOldParentName = actualOldParent.getName ();
47 4 : string withoutNamespaceParent = actualOldParentName.substr (actualOldParentName.find ('/'));
48 4 : relativePath = oldKeyPath.substr (withoutNamespaceParent.length (), oldKeyPath.length ());
49 : }
50 : else
51 : {
52 16815 : relativePath = oldKeyPath.substr (actualOldParent.getName ().length (), oldKeyPath.length ());
53 : }
54 11214 : string newPath = actualNewParent.getName () + relativePath;
55 :
56 5607 : return newPath;
57 : }
58 :
59 2585 : Key rebaseKey (const Key & key, const Key & oldParent, const Key & newParent)
60 : {
61 5170 : string newPath = rebasePath (key, oldParent, newParent);
62 5170 : Key result = key.dup ();
63 2585 : result.setName (newPath);
64 2585 : return result;
65 : }
66 :
67 1018 : void removeNamespace (Key & key)
68 : {
69 2036 : std::string name = key.getName ();
70 1018 : size_t pos = name.find_first_of ('/');
71 1018 : if (pos == string::npos)
72 : {
73 : // we directly had a namespace
74 96 : key.setName ("/");
75 : }
76 : else
77 : {
78 1988 : name = name.substr (pos);
79 994 : key.setName (name);
80 : }
81 1018 : }
82 :
83 19 : Key commonKeyName (Key key1, Key key2)
84 : {
85 : // do not let removed namespaces escape
86 38 : key1 = key1.dup ();
87 38 : key2 = key2.dup ();
88 :
89 19 : if (key1.isBelowOrSame (key2)) return key2;
90 19 : if (key2.isBelowOrSame (key1)) return key1;
91 :
92 76 : if (key1.getNamespace () != key2.getNamespace ())
93 : {
94 10 : removeNamespace (key1);
95 10 : removeNamespace (key2);
96 : }
97 :
98 38 : Key ret (key1.getNamespace (), KEY_END);
99 365 : for (auto it1 = ++key1.begin (), it2 = ++key2.begin (); it1 != key1.end () && it2 != key2.end (); ++it1, ++it2)
100 : {
101 305 : if (*it1 != *it2) break;
102 86 : ret.addBaseName (*it1);
103 : }
104 19 : return ret;
105 : }
106 : } // namespace helper
107 : } // namespace tools
108 : } // namespace kdb
|