Dict.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
5 * Karlsruhe Institute of Technology (KIT), all rights reserved.
6 *
7 * ArmarX is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * ArmarX is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
24// Header
25#include "Dict.h"
26
27// ArmarX
28#include <SimoxUtility/algorithm/string/string_conversion.h>
29
32
34
35namespace armarx::aron::data
36{
37
38 // constructors
40 detail::ContainerVariant<data::dto::Dict, Dict>::ContainerVariant(data::Descriptor::DICT,
41 path)
42 {
43 }
44
46 detail::ContainerVariant<data::dto::Dict, Dict>::ContainerVariant(o,
48 path)
49 {
50 for (const auto& [key, dataPtr] : this->aron->elements)
51 {
52 childrenNavigators[key] = Variant::FromAronDTO(dataPtr, path.withElement(key));
53 }
54 }
55
56 Dict::Dict(const std::map<std::string, VariantPtr>& m, const Path& path) : Dict(path)
57 {
58 for (const auto& [key, dataPtr] : m)
59 {
60 addElement(key, dataPtr);
61 }
62 }
63
64 // operators
65 bool
66 Dict::operator==(const Dict& other) const
67 {
68 for (const auto& [key, nav] : childrenNavigators)
69 {
70 if (not(other.hasElement(key)))
71 {
72 return false;
73 }
74 if (!nav)
75 {
76 return !((bool)other.getElement(key));
77 }
78 if (not(*nav == *other.getElement(key)))
79 {
80 return false;
81 }
82 }
83 return true;
84 }
85
86 bool
87 Dict::operator==(const DictPtr& other) const
88 {
89 if (!other)
90 {
91 return false;
92 }
93 return *this == *other;
94 }
95
97 Dict::operator[](const std::string& s) const
98 {
99 return getElement(s);
100 }
101
102 Dict&
103 Dict::operator=(const Dict& other)
104 {
105 this->aron = other.aron;
106 this->childrenNavigators = other.childrenNavigators;
107 return *this;
108 }
109
110 DictPtr
111 Dict::clone(const Path& p) const
112 {
113 DictPtr ret(new Dict(p));
114 ret->setImportance(getImportance());
115 for (const auto& [key, val] : getElements())
116 {
117 if (val)
118 {
119 ret->addElement(key, val->cloneAsVariant());
120 }
121 else
122 {
123 ret->addElement(key, nullptr);
124 }
125 }
126 return ret;
127 }
128
129 // static methods
130 DictPtr
132 {
133 if (!aron)
134 {
135 return nullptr;
136 }
137 return std::make_shared<Dict>(aron);
138 }
139
141 Dict::ToAronDictDTO(const DictPtr& navigator)
142 {
143 return navigator ? navigator->toAronDictDTO() : nullptr;
144 }
145
148 {
149 return aron;
150 }
151
152 // public member functions
153 std::vector<std::string>
155 {
156 std::vector<std::string> ret;
157 for (const auto& [key, _] : childrenNavigators)
158 {
159 ret.push_back(key);
160 }
161 return ret;
162 }
163
164 std::string
166 {
167 return simox::alg::to_string(getAllKeys(), ", ");
168 }
169
170 void
171 Dict::addElement(const std::string& key, const VariantPtr& data)
172 {
173 // Please note that the data may be null (indicating that a non existing maybetype has been added)
174
175 if (hasElement(key))
176 {
178 throw error::AronException(__PRETTY_FUNCTION__,
179 "The key '" + key + "' already exists in a aron dict.");
180 }
181 setElement(key, data);
182 }
183
184 void
185 Dict::addElementCopy(const std::string& key, const VariantPtr& data)
186 {
187 // Please note that the data may be null (indicating that a non existing maybetype has been added)
188
189 if (hasElement(key))
190 {
192 throw error::AronException(__PRETTY_FUNCTION__,
193 "The key '" + key + "' already exists in a aron dict.");
194 }
195 setElementCopy(key, data);
196 }
197
198 void
200 {
201 if (d == nullptr)
202 {
203 return;
204 }
205
206 // merge and overwrite
207 for (const auto& [k, v] : d->getElements())
208 {
209 this->setElement(k, v);
210 }
211 }
212
213 void
215 {
216 if (d == nullptr)
217 {
218 return;
219 }
220
221 // merge and overwrite
222 for (const auto& [k, v] : d->getElements())
223 {
224 this->setElementCopy(k, v);
225 }
226 }
227
228 bool
229 Dict::hasElement(const std::string& key) const
230 {
231 return childrenNavigators.count(key) > 0;
232 }
233
235 Dict::getElement(const std::string& key) const
236 {
237 auto it = childrenNavigators.find(key);
238 if (it == childrenNavigators.end())
239 {
241 throw error::AronException(__PRETTY_FUNCTION__,
242 "Could not find key '" + key +
243 "'. But I found the following keys: [" +
244 simox::alg::join(this->getAllKeys(), ", ") + "]",
245 getPath());
246 }
247 return it->second;
248 }
249
250 std::map<std::string, VariantPtr>
252 {
253 return childrenNavigators;
254 }
255
256 void
257 Dict::setElement(const std::string& key, const VariantPtr& data)
258 {
259 // Please note that the data may be null (indicating that a non existing maybetype has been added)
260
261 if (data)
262 {
263 const auto& p = data->getPath();
264 if (not p.hasDirectPrefix(this->getPath()))
265 {
267 << "An element added to a dict does not have a correct path set. This "
268 "may cause errors. Please use setElemetCopy() instead.";
269 }
270 }
271
272 this->childrenNavigators[key] = data;
273 if (data)
274 {
275 this->aron->elements[key] = data->toAronDTO();
276 }
277 else
278 {
279 this->aron->elements[key] = nullptr;
280 }
281 }
282
283 void
284 Dict::setElementCopy(const std::string& key, const VariantPtr& data)
285 {
286 // Please note that the data may be null (indicating that a non existing maybetype has been added)
287
288 VariantPtr copy = nullptr;
289 if (data)
290 {
291 Path newPath = getPath().withElement(key);
292 copy = data->cloneAsVariant(newPath);
293 }
294 setElement(key, copy);
295 }
296
297 void
298 Dict::removeElement(const std::string& key)
299 {
300 childrenNavigators.erase(key);
301 aron->elements.erase(key);
302 }
303
304 void
306 {
307 childrenNavigators.clear();
308 aron->elements.clear();
309 }
310
312 Dict::at(const std::string& s) const
313 {
314 return getElement(s);
315 }
316
317 // virtual implementations
318 std::string
320 {
321 return "Dict";
322 }
323
324 std::string
326 {
327 return "armarx::aron::data::Dict";
328 }
329
330 // TODO
333 {
335 throw error::NotImplementedYetException(__PRETTY_FUNCTION__);
336 }
337
338 bool
340 {
341 if (!type)
342 return true;
343
344 type::Descriptor typeDesc = type->getDescriptor();
345
346 switch (typeDesc)
347 {
349 {
351 auto objectTypeNav = type::Object::DynamicCastAndCheck(type);
352
353 // here we need to iterate over the elements of the type. That must be fulfilled.
354 // If this dict has more members that its fine.
355 for (const auto& [key, childTypeNav] : objectTypeNav->getMemberTypes())
356 {
357 if (!this->hasElement(key))
358 {
359 return false; // key must exist
360 }
361
362 if (!childTypeNav)
363 {
364 continue; // no information whih is fine --> continue
365 }
366
367 auto childNav = this->getElement(key);
368 if (childNav)
369 {
370 if (not childNav->fullfillsType(childTypeNav))
371 {
372 return false;
373 }
374 // else childnav fulfills type which is fine --> continue
375 continue;
376 }
377 else
378 {
379 if (childTypeNav->getMaybe() == type::Maybe::NONE)
380 {
381 return false;
382 }
383 // else: childTypeNav == maybe && nav == null which is fine --> continue
384 continue;
385 }
386 }
387 return true;
388 }
390 {
392 auto dictTypeNav = type::Dict::DynamicCastAndCheck(type);
393 for (const auto& [key, childNav] : childrenNavigators)
394 {
395 (void)key;
396 auto childTypeNav = dictTypeNav->getAcceptedType();
397 if (!childNav)
398 {
399 if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
400 {
401 return false;
402 }
403 // else childTypeNav is null or maybe and childNav is null which is fine.
404 continue;
405 }
406 if (!childNav->fullfillsType(childTypeNav))
407 {
408 return false;
409 }
410 }
411 return true;
412 }
413 default:
414 return false;
415 }
416 }
417
418 std::vector<VariantPtr>
420 {
421 std::vector<VariantPtr> ret(childrenNavigators.size());
422 for (const auto& [key, nav] : childrenNavigators)
423 {
424 ret.push_back(nav);
425 }
426 return ret;
427 }
428
429 size_t
431 {
432 return childrenNavigators.size();
433 }
434
437 {
438 if (!path.hasElement())
439 {
442 __PRETTY_FUNCTION__, "Could not navigate without a valid path", path);
443 }
444 std::string el = path.getFirstElement();
445 if (!hasElement(el))
446 {
449 __PRETTY_FUNCTION__, "Could not find an element of a path.", el, path);
450 }
451
452 if (path.size() == 1)
453 {
454 return childrenNavigators.at(el);
455 }
456 else
457 {
458 Path next = path.withDetachedFirstElement();
459 if (!childrenNavigators.at(el))
460 {
462 throw error::AronException(__PRETTY_FUNCTION__,
463 "Could not navigate into a NULL member. Seems like the "
464 "member is optional and not set.",
465 next);
466 }
467 return childrenNavigators.at(el)->navigateAbsolute(next);
468 }
469 }
470} // namespace armarx::aron::data
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
The Path class.
Definition Path.h:36
Path withElement(const std::string &, bool escape=false) const
Definition Path.cpp:163
size_t childrenSize() const override
get the children size of a data variant
Definition Dict.cpp:430
void addElement(const std::string &key, const VariantPtr &=nullptr)
Definition Dict.cpp:171
void removeElement(const std::string &key)
Definition Dict.cpp:298
VariantPtr at(const std::string &) const
Definition Dict.cpp:312
std::string getShortName() const override
get a short str representation of this variant
Definition Dict.cpp:319
void setElement(const std::string &, const VariantPtr &=nullptr)
Definition Dict.cpp:257
data::dto::DictPtr toAronDictDTO() const
Definition Dict.cpp:147
VariantPtr operator[](const std::string &) const
Definition Dict.cpp:97
type::VariantPtr recalculateType() const override
recalculate the type of a data variant. Please not tha the mapping ist NOT bijective,...
Definition Dict.cpp:332
std::string getAllKeysAsString() const
Definition Dict.cpp:165
std::string getFullName() const override
get the full str representation of this variant
Definition Dict.cpp:325
void mergeAndReplace(const DictPtr &d)
Definition Dict.cpp:199
void mergeAndReplaceCopy(const DictPtr &d)
Definition Dict.cpp:214
static data::dto::DictPtr ToAronDictDTO(const PointerType &navigator)
Definition Dict.cpp:141
Dict & operator=(const Dict &)
Definition Dict.cpp:103
bool operator==(const Dict &) const override
Definition Dict.cpp:66
Dict(const Path &path=Path())
Definition Dict.cpp:39
void addElementCopy(const std::string &key, const VariantPtr &=nullptr)
Definition Dict.cpp:185
std::map< std::string, VariantPtr > getElements() const
Definition Dict.cpp:251
std::vector< std::string > getAllKeys() const
Definition Dict.cpp:154
void setElementCopy(const std::string &, const VariantPtr &=nullptr)
Definition Dict.cpp:284
VariantPtr navigateAbsolute(const Path &path) const override
naviate absolute
Definition Dict.cpp:436
static PointerType FromAronDictDTO(const data::dto::DictPtr &aron)
Definition Dict.cpp:131
bool fullfillsType(const type::VariantPtr &) const override
checks, if the current data variant fullfills the given type
Definition Dict.cpp:339
std::vector< VariantPtr > getChildren() const override
get the children of a data variant
Definition Dict.cpp:419
bool hasElement(const std::string &) const
Definition Dict.cpp:229
VariantPtr getElement(const std::string &) const
Definition Dict.cpp:235
Path getPath() const
get the path
Definition Variant.h:111
A base class for aron exceptions.
Definition Exception.h:37
The NotImplementedYetException class.
Definition Exception.h:61
The ValueNotValidException class.
Definition Exception.h:99
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:182
::IceInternal::Handle< Dict > DictPtr
A convenience header to include all aron files (full include, not forward declared)
std::shared_ptr< Dict > DictPtr
Definition Dict.h:42
std::shared_ptr< Variant > VariantPtr
A convenience header to include all aron files (full include, not forward declared)
std::shared_ptr< Variant > VariantPtr
#define ARMARX_TRACE
Definition trace.h:75