1 /*
2  * Copyright (C) 2018 Red Hat, Inc.
3  *
4  * Licensed under the GNU Lesser General Public License Version 2.1
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 // libsolv
22 extern "C" {
23 #include <solv/dataiterator.h>
24 }
25 
26 #include "DependencyContainer.hpp"
27 #include "Dependency.hpp"
28 #include "../DependencySplitter.hpp"
29 
30 namespace libdnf {
31 
DependencyContainer(const DependencyContainer & src)32 DependencyContainer::DependencyContainer(const DependencyContainer &src)
33         : sack(src.sack)
34 {
35     queue_init_clone(&queue, &src.queue);
36 }
37 
DependencyContainer(DependencyContainer && src)38 DependencyContainer::DependencyContainer(DependencyContainer &&src)
39         : sack(src.sack)
40 {
41     queue_init(&queue);
42     std::swap(queue, src.queue);
43 }
44 
DependencyContainer(DnfSack * sack)45 DependencyContainer::DependencyContainer(DnfSack *sack)
46         : sack(sack)
47 {
48     queue_init(&queue);
49 }
50 
DependencyContainer(DnfSack * sack,const Queue & queue)51 DependencyContainer::DependencyContainer(DnfSack *sack, const Queue &queue)
52         : sack(sack)
53 {
54     queue_init_clone(&this->queue, &queue);
55 }
56 
DependencyContainer(DnfSack * sack,Queue && queue)57 DependencyContainer::DependencyContainer(DnfSack *sack, Queue &&queue)
58         : sack(sack), queue(queue)
59 {}
60 
~DependencyContainer()61 DependencyContainer::~DependencyContainer()
62 {
63     queue_free(&queue);
64 }
65 
operator =(const DependencyContainer & src)66 DependencyContainer &DependencyContainer::operator=(const DependencyContainer &src)
67 {
68     if (this != &src) {
69         sack = src.sack;
70         queue_free(&queue);
71         queue_init_clone(&queue, &src.queue);
72     }
73     return *this;
74 }
75 
operator =(DependencyContainer && src)76 DependencyContainer &DependencyContainer::operator=(DependencyContainer &&src) noexcept
77 {
78     if (this != &src) {
79         sack = src.sack;
80         std::swap(queue, src.queue);
81     }
82     return *this;
83 }
84 
operator !=(const DependencyContainer & r) const85 bool DependencyContainer::operator!=(const DependencyContainer &r) const { return !(*this == r); }
operator ==(const DependencyContainer & r) const86 bool DependencyContainer::operator==(const DependencyContainer &r) const
87 {
88     if (queue.count != r.queue.count)
89         return false;
90 
91     for (int i = 0; i < queue.count; i++) {
92         if (queue.elements[i] != r.queue.elements[i]) {
93             return false;
94         }
95     }
96 
97     return dnf_sack_get_pool(sack) == dnf_sack_get_pool(r.sack);
98 }
99 
add(Dependency * dependency)100 void DependencyContainer::add(Dependency *dependency)
101 {
102     queue_push(&queue, dependency->getId());
103 }
104 
add(Id id)105 void DependencyContainer::add(Id id)
106 {
107     queue_push(&queue, id);
108 }
109 
addReldepWithGlob(const char * reldepStr)110 bool DependencyContainer::addReldepWithGlob(const char *reldepStr)
111 {
112     DependencySplitter depSplitter;
113     if(!depSplitter.parse(reldepStr))
114         return false;
115     Dataiterator di;
116     Pool *pool = dnf_sack_get_pool(sack);
117 
118     dataiterator_init(&di, pool, 0, 0, 0, depSplitter.getNameCStr(),
119                       SEARCH_STRING | SEARCH_GLOB);
120     while (dataiterator_step(&di)) {
121         Id id = Dependency::getReldepId(sack, di.kv.str, depSplitter.getEVRCStr(),
122                                         depSplitter.getCmpType());
123         add(id);
124     }
125     dataiterator_free(&di);
126     return true;
127 }
128 
addReldep(const char * reldepStr)129 bool DependencyContainer::addReldep(const char *reldepStr)
130 {
131     try {
132         Id id = Dependency::getReldepId(sack, reldepStr);
133         add(id);
134         return true;
135     }
136     catch (...) {
137         return false;
138     }
139 }
140 
extend(DependencyContainer * container)141 void DependencyContainer::extend(DependencyContainer *container)
142 {
143     queue_insertn(&queue, 0, container->queue.count, container->queue.elements);
144 }
145 
get(int index) const146 std::unique_ptr<Dependency> DependencyContainer::get(int index) const noexcept
147 {
148     Id id = queue.elements[index];
149     return std::unique_ptr<Dependency> (new Dependency(sack, id));
150 }
151 
getPtr(int index) const152 Dependency *DependencyContainer::getPtr(int index) const noexcept
153 {
154     Id id = queue.elements[index];
155     return new Dependency(sack, id);
156 }
157 
count() const158 int DependencyContainer::count() const noexcept { return queue.count; }
getQueue() const159 const Queue &DependencyContainer::getQueue() const noexcept { return queue; }
160 
161 }
162