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 for (const auto& [key, val] : getElements())
115 {
116 if (val)
117 {
118 ret->addElement(key, val->cloneAsVariant());
119 }
120 else
121 {
122 ret->addElement(key, nullptr);
123 }
124 }
125 return ret;
126 }
127
128 // static methods
129 DictPtr
131 {
132 if (!aron)
133 {
134 return nullptr;
135 }
136 return std::make_shared<Dict>(aron);
137 }
138
140 Dict::ToAronDictDTO(const DictPtr& navigator)
141 {
142 return navigator ? navigator->toAronDictDTO() : nullptr;
143 }
144
147 {
148 return aron;
149 }
150
151 // public member functions
152 std::vector<std::string>
154 {
155 std::vector<std::string> ret;
156 for (const auto& [key, _] : childrenNavigators)
157 {
158 ret.push_back(key);
159 }
160 return ret;
161 }
162
163 std::string
165 {
166 return simox::alg::to_string(getAllKeys(), ", ");
167 }
168
169 void
170 Dict::addElement(const std::string& key, const VariantPtr& data)
171 {
172 // Please note that the data may be null (indicating that a non existing maybetype has been added)
173
174 if (hasElement(key))
175 {
177 throw error::AronException(__PRETTY_FUNCTION__,
178 "The key '" + key + "' already exists in a aron dict.");
179 }
180 setElement(key, data);
181 }
182
183 void
184 Dict::addElementCopy(const std::string& key, const VariantPtr& data)
185 {
186 // Please note that the data may be null (indicating that a non existing maybetype has been added)
187
188 if (hasElement(key))
189 {
191 throw error::AronException(__PRETTY_FUNCTION__,
192 "The key '" + key + "' already exists in a aron dict.");
193 }
194 setElementCopy(key, data);
195 }
196
197 void
199 {
200 if (d == nullptr)
201 {
202 return;
203 }
204
205 // merge and overwrite
206 for (const auto& [k, v] : d->getElements())
207 {
208 this->setElement(k, v);
209 }
210 }
211
212 void
214 {
215 if (d == nullptr)
216 {
217 return;
218 }
219
220 // merge and overwrite
221 for (const auto& [k, v] : d->getElements())
222 {
223 this->setElementCopy(k, v);
224 }
225 }
226
227 bool
228 Dict::hasElement(const std::string& key) const
229 {
230 return childrenNavigators.count(key) > 0;
231 }
232
234 Dict::getElement(const std::string& key) const
235 {
236 auto it = childrenNavigators.find(key);
237 if (it == childrenNavigators.end())
238 {
240 throw error::AronException(__PRETTY_FUNCTION__,
241 "Could not find key '" + key +
242 "'. But I found the following keys: [" +
243 simox::alg::join(this->getAllKeys(), ", ") + "]",
244 getPath());
245 }
246 return it->second;
247 }
248
249 std::map<std::string, VariantPtr>
251 {
252 return childrenNavigators;
253 }
254
255 void
256 Dict::setElement(const std::string& key, const VariantPtr& data)
257 {
258 // Please note that the data may be null (indicating that a non existing maybetype has been added)
259
260 if (data)
261 {
262 const auto& p = data->getPath();
263 if (not p.hasDirectPrefix(this->getPath()))
264 {
266 << "An element added to a dict does not have a correct path set. This "
267 "may cause errors. Please use setElemetCopy() instead.";
268 }
269 }
270
271 this->childrenNavigators[key] = data;
272 if (data)
273 {
274 this->aron->elements[key] = data->toAronDTO();
275 }
276 else
277 {
278 this->aron->elements[key] = nullptr;
279 }
280 }
281
282 void
283 Dict::setElementCopy(const std::string& key, const VariantPtr& data)
284 {
285 // Please note that the data may be null (indicating that a non existing maybetype has been added)
286
287 VariantPtr copy = nullptr;
288 if (data)
289 {
290 Path newPath = getPath().withElement(key);
291 copy = data->cloneAsVariant(newPath);
292 }
293 setElement(key, copy);
294 }
295
296 void
297 Dict::removeElement(const std::string& key)
298 {
299 childrenNavigators.erase(key);
300 aron->elements.erase(key);
301 }
302
303 void
305 {
306 childrenNavigators.clear();
307 aron->elements.clear();
308 }
309
311 Dict::at(const std::string& s) const
312 {
313 return getElement(s);
314 }
315
316 // virtual implementations
317 std::string
319 {
320 return "Dict";
321 }
322
323 std::string
325 {
326 return "armarx::aron::data::Dict";
327 }
328
329 // TODO
332 {
334 throw error::NotImplementedYetException(__PRETTY_FUNCTION__);
335 }
336
337 bool
339 {
340 if (!type)
341 return true;
342
343 type::Descriptor typeDesc = type->getDescriptor();
344
345 switch (typeDesc)
346 {
348 {
350 auto objectTypeNav = type::Object::DynamicCastAndCheck(type);
351
352 // here we need to iterate over the elements of the type. That must be fulfilled.
353 // If this dict has more members that its fine.
354 for (const auto& [key, childTypeNav] : objectTypeNav->getMemberTypes())
355 {
356 if (!this->hasElement(key))
357 {
358 return false; // key must exist
359 }
360
361 if (!childTypeNav)
362 {
363 continue; // no information whih is fine --> continue
364 }
365
366 auto childNav = this->getElement(key);
367 if (childNav)
368 {
369 if (not childNav->fullfillsType(childTypeNav))
370 {
371 return false;
372 }
373 // else childnav fulfills type which is fine --> continue
374 continue;
375 }
376 else
377 {
378 if (childTypeNav->getMaybe() == type::Maybe::NONE)
379 {
380 return false;
381 }
382 // else: childTypeNav == maybe && nav == null which is fine --> continue
383 continue;
384 }
385 }
386 return true;
387 }
389 {
391 auto dictTypeNav = type::Dict::DynamicCastAndCheck(type);
392 for (const auto& [key, childNav] : childrenNavigators)
393 {
394 (void)key;
395 auto childTypeNav = dictTypeNav->getAcceptedType();
396 if (!childNav)
397 {
398 if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
399 {
400 return false;
401 }
402 // else childTypeNav is null or maybe and childNav is null which is fine.
403 continue;
404 }
405 if (!childNav->fullfillsType(childTypeNav))
406 {
407 return false;
408 }
409 }
410 return true;
411 }
412 default:
413 return false;
414 }
415 }
416
417 std::vector<VariantPtr>
419 {
420 std::vector<VariantPtr> ret(childrenNavigators.size());
421 for (const auto& [key, nav] : childrenNavigators)
422 {
423 ret.push_back(nav);
424 }
425 return ret;
426 }
427
428 size_t
430 {
431 return childrenNavigators.size();
432 }
433
436 {
437 if (!path.hasElement())
438 {
441 __PRETTY_FUNCTION__, "Could not navigate without a valid path", path);
442 }
443 std::string el = path.getFirstElement();
444 if (!hasElement(el))
445 {
448 __PRETTY_FUNCTION__, "Could not find an element of a path.", el, path);
449 }
450
451 if (path.size() == 1)
452 {
453 return childrenNavigators.at(el);
454 }
455 else
456 {
457 Path next = path.withDetachedFirstElement();
458 if (!childrenNavigators.at(el))
459 {
461 throw error::AronException(__PRETTY_FUNCTION__,
462 "Could not navigate into a NULL member. Seems like the "
463 "member is optional and not set.",
464 next);
465 }
466 return childrenNavigators.at(el)->navigateAbsolute(next);
467 }
468 }
469} // 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:429
void addElement(const std::string &key, const VariantPtr &=nullptr)
Definition Dict.cpp:170
void removeElement(const std::string &key)
Definition Dict.cpp:297
VariantPtr at(const std::string &) const
Definition Dict.cpp:311
std::string getShortName() const override
get a short str representation of this variant
Definition Dict.cpp:318
void setElement(const std::string &, const VariantPtr &=nullptr)
Definition Dict.cpp:256
data::dto::DictPtr toAronDictDTO() const
Definition Dict.cpp:146
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:331
std::string getAllKeysAsString() const
Definition Dict.cpp:164
std::string getFullName() const override
get the full str representation of this variant
Definition Dict.cpp:324
void mergeAndReplace(const DictPtr &d)
Definition Dict.cpp:198
void mergeAndReplaceCopy(const DictPtr &d)
Definition Dict.cpp:213
static data::dto::DictPtr ToAronDictDTO(const PointerType &navigator)
Definition Dict.cpp:140
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:184
std::map< std::string, VariantPtr > getElements() const
Definition Dict.cpp:250
std::vector< std::string > getAllKeys() const
Definition Dict.cpp:153
void setElementCopy(const std::string &, const VariantPtr &=nullptr)
Definition Dict.cpp:283
VariantPtr navigateAbsolute(const Path &path) const override
naviate absolute
Definition Dict.cpp:435
static PointerType FromAronDictDTO(const data::dto::DictPtr &aron)
Definition Dict.cpp:130
bool fullfillsType(const type::VariantPtr &) const override
checks, if the current data variant fullfills the given type
Definition Dict.cpp:338
std::vector< VariantPtr > getChildren() const override
get the children of a data variant
Definition Dict.cpp:418
bool hasElement(const std::string &) const
Definition Dict.cpp:228
VariantPtr getElement(const std::string &) const
Definition Dict.cpp:234
Path getPath() const
get the path
Definition Variant.h:110
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:184
::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:77