YARP
Yet Another Robot Platform
Bottle.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * Copyright (C) 2006, 2008 Arjan Gijsberts
5  * All rights reserved.
6  *
7  * This software may be modified and distributed under the terms of the
8  * BSD-3-Clause license. See the accompanying LICENSE file for details.
9  */
10 
11 #include <yarp/os/Bottle.h>
12 #include <yarp/os/DummyConnector.h>
13 #include <yarp/os/NetType.h>
16 
17 
18 using yarp::os::Bottle;
21 using yarp::os::Property;
22 using yarp::os::Value;
25 
26 namespace {
27 YARP_OS_LOG_COMPONENT(BOTTLE, "yarp.os.Bottle")
28 }
29 
30 // FIXME this can be constexpr, but swig 3.0.8 is not happy
31 const Bottle::size_type Bottle::npos = static_cast<Bottle::size_type>(-1);
32 
33 class NullBottle : public Bottle
34 {
35 public:
37  Bottle()
38  {
39  setReadOnly(true);
40  }
41  bool isNull() const override
42  {
43  return true;
44  }
45 };
46 
47 Bottle::Bottle() :
48  Portable(),
49  Searchable(),
50  implementation(new BottleImpl(this))
51 {
52  yCAssert(BOTTLE, implementation != nullptr);
53  implementation->invalid = false;
54  implementation->ro = false;
55 }
56 
57 Bottle::Bottle(const std::string& text) :
58  Portable(),
59  Searchable(),
60  implementation(new BottleImpl(this))
61 {
62  yCAssert(BOTTLE, implementation != nullptr);
63  implementation->invalid = false;
64  implementation->ro = false;
65  fromString(text);
66 }
67 
68 Bottle::Bottle(const Bottle& rhs) :
69  Portable(),
70  Searchable(rhs),
71  implementation(new BottleImpl(this))
72 {
73  yCAssert(BOTTLE, implementation != nullptr);
74  implementation->invalid = false;
75  implementation->ro = false;
76  copy(rhs);
77 }
78 
79 Bottle::Bottle(Bottle&& rhs) noexcept :
80  Portable(std::move(static_cast<Portable&>(rhs))),
81  Searchable(std::move(static_cast<Searchable&>(rhs))),
82  implementation(rhs.implementation)
83 {
84  implementation->parent = this;
85  rhs.implementation = new BottleImpl(&rhs);
86 }
87 
88 Bottle::Bottle(std::initializer_list<Value> values) :
89  Portable(),
90  Searchable(),
91  implementation(new BottleImpl(this))
92 {
93  yCAssert(BOTTLE, implementation != nullptr);
94  implementation->invalid = false;
95  implementation->ro = false;
96 
97  for (const auto& val : values) {
98  add(val);
99  }
100 }
101 
103 {
104  if (&rhs != this) {
105  implementation->edit();
106  copy(rhs);
107  }
108  return *this;
109 }
110 
112 {
113  std::swap(implementation, rhs.implementation);
114  implementation->parent = this;
115  rhs.implementation->parent = &rhs;
116  return *this;
117 }
118 
120 {
121  delete implementation;
122 }
123 
125 {
126  implementation->edit();
127  implementation->invalid = false;
128  implementation->clear();
129 }
130 
131 void Bottle::addInt8(std::int8_t x)
132 {
133  implementation->edit();
134  implementation->addInt8(x);
135 }
136 
137 void Bottle::addInt16(std::int16_t x)
138 {
139  implementation->edit();
140  implementation->addInt16(x);
141 }
142 
143 void Bottle::addInt32(std::int32_t x)
144 {
145  implementation->edit();
146  implementation->addInt32(x);
147 }
148 
149 void Bottle::addInt64(std::int64_t x)
150 {
151  implementation->edit();
152  implementation->addInt64(x);
153 }
154 
156 {
157  implementation->edit();
158  implementation->addFloat32(x);
159 }
160 
162 {
163  implementation->edit();
164  implementation->addFloat64(x);
165 }
166 
167 void Bottle::addVocab(int x)
168 {
169  implementation->edit();
170  implementation->addVocab(x);
171 }
172 
173 void Bottle::addString(const char* str)
174 {
175  implementation->edit();
176  implementation->addString(str);
177 }
178 
179 void Bottle::addString(const std::string& str)
180 {
181  implementation->edit();
182  implementation->addString(str);
183 }
184 
186 {
187  implementation->edit();
188  return implementation->addList();
189 }
190 
192 {
193  implementation->edit();
194  return implementation->addDict();
195 }
196 
198 {
199  implementation->edit();
200  Storable* stb = implementation->pop();
201  Value val(*stb);
202  // here we take responsibility for deallocation of the Storable instance
203  delete stb;
204  return val;
205 }
206 
207 void Bottle::fromString(const std::string& text)
208 {
209  implementation->edit();
210  implementation->invalid = false;
211  implementation->fromString(text);
212 }
213 
214 std::string Bottle::toString() const
215 {
216  return implementation->toString();
217 }
218 
219 void Bottle::fromBinary(const char* buf, size_t len)
220 {
221  implementation->edit();
222  implementation->fromBinary(buf, len);
223 }
224 
225 const char* Bottle::toBinary(size_t* size)
226 {
227  if (size != nullptr) {
228  *size = implementation->byteCount();
229  }
230  return implementation->getBytes();
231 }
232 
233 bool Bottle::write(ConnectionWriter& writer) const
234 {
235  return implementation->write(writer);
236 }
237 
239 {
240  implementation->onCommencement();
241 }
242 
244 {
245  implementation->edit();
246  return implementation->read(reader);
247 }
248 
249 Value& Bottle::get(size_t index) const
250 {
251  return implementation->get(index);
252 }
253 
254 size_t Bottle::size() const
255 {
256  return static_cast<int>(implementation->size());
257 }
258 
260 {
261  implementation->hasChanged();
262 }
263 
265 {
266  return implementation->getSpecialization();
267 }
268 
269 void Bottle::copy(const Bottle& alt, size_t first, size_t len)
270 {
271  implementation->edit();
272  if (alt.isNull()) {
273  clear();
274  implementation->invalid = true;
275  return;
276  }
277  implementation->copyRange(alt.implementation, first, len);
278 }
279 
280 bool Bottle::check(const std::string& key) const
281 {
282  Bottle& val = findGroup(key);
283  if (!val.isNull()) {
284  return true;
285  }
286  Value& val2 = find(key);
287  return !val2.isNull();
288 }
289 
290 Value& Bottle::find(const std::string& key) const
291 {
292  Value& val = implementation->findBit(key);
293 
294  if (getMonitor() != nullptr) {
295  SearchReport report;
296  report.key = key;
297  report.isFound = !val.isNull();
298  report.value = val.toString();
299  reportToMonitor(report);
300  }
301 
302  return val;
303 }
304 
305 Bottle& Bottle::findGroup(const std::string& key) const
306 {
307  Value& bb = implementation->findGroupBit(key);
308 
309  if (getMonitor() != nullptr) {
310  SearchReport report;
311  report.key = key;
312  report.isGroup = true;
313  if (bb.isList()) {
314  report.isFound = true;
315  report.value = bb.toString();
316  }
317  reportToMonitor(report);
318  if (bb.isList()) {
319  std::string context = getMonitorContext();
320  context += ".";
321  context += key;
322  bb.asList()->setMonitor(getMonitor(),
323  context.c_str()); // pass on any monitoring
324  }
325  }
326 
327  if (bb.isList()) {
328  return *(bb.asList());
329  }
330  return getNullBottle();
331 }
332 
333 void Bottle::add(Value* value)
334 {
335  implementation->edit();
336  implementation->addBit(value);
337 }
338 
339 void Bottle::add(const Value& value)
340 {
341  implementation->edit();
342  implementation->addBit(value);
343 }
344 
346 {
347  static NullBottle bottleNull;
348  return bottleNull;
349 }
350 
351 bool Bottle::operator==(const Bottle& alt) const
352 {
353  return toString() == alt.toString();
354 }
355 
356 bool Bottle::write(PortReader& reader, bool textMode)
357 {
358  DummyConnector con;
359  con.setTextMode(textMode);
360  write(con.getWriter());
361  return reader.read(con.getReader());
362 }
363 
364 bool Bottle::read(const PortWriter& writer, bool textMode)
365 {
366  implementation->edit();
367  DummyConnector con;
368  con.setTextMode(textMode);
369  writer.write(con.getWriter());
370  return read(con.getReader());
371 }
372 
373 bool Bottle::isNull() const
374 {
375  return implementation->invalid;
376 }
377 
378 bool Bottle::operator!=(const Bottle& alt) const
379 {
380  return !((*this) == alt);
381 }
382 
383 void Bottle::append(const Bottle& alt)
384 {
385  implementation->edit();
386  for (size_t i = 0; i < alt.size(); i++) {
387  add(alt.get(i));
388  }
389 }
390 
392 {
393  Bottle b;
394  if (isNull()) {
395  return *this;
396  }
397  b.copy(*this, 1, size() - 1);
398  return b;
399 }
400 
401 std::string Bottle::toString(int x)
402 {
403  return NetType::toString(x);
404 }
405 
406 std::string Bottle::describeBottleCode(int code)
407 {
408  int unit = code & ~(BOTTLE_TAG_LIST | BOTTLE_TAG_DICT);
409  std::string unitName = "mixed";
410  switch (unit) {
411  case 0:
412  unitName = "mixed";
413  break;
414  case BOTTLE_TAG_INT32:
415  unitName = "int";
416  break;
417  case BOTTLE_TAG_VOCAB:
418  unitName = "vocab";
419  break;
420  case BOTTLE_TAG_FLOAT64:
421  unitName = "float";
422  break;
423  case BOTTLE_TAG_STRING:
424  unitName = "string";
425  break;
426  case BOTTLE_TAG_BLOB:
427  unitName = "blob";
428  break;
429  default:
430  unitName = "unknown";
431  break;
432  }
433  std::string result = unitName;
434  if ((code & BOTTLE_TAG_LIST) != 0) {
435  result = "list of " + unitName;
436  } else if ((code & BOTTLE_TAG_DICT) != 0) {
437  result = "dict of " + unitName;
438  }
439  return result;
440 }
441 
442 void Bottle::setReadOnly(bool readOnly)
443 {
444  implementation->ro = readOnly;
445 }
yarp::os::DummyConnector
A dummy connection to test yarp::os::Portable implementations.
Definition: DummyConnector.h:38
NullBottle::isNull
bool isNull() const override
Checks if the object is invalid.
Definition: Bottle.cpp:41
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:72
BottleImpl.h
yarp::os::Bottle::toString
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
yarp::os::Bottle::Bottle
Bottle()
Constructor.
Definition: Bottle.cpp:47
yarp::os::Portable
Definition: Portable.h:28
yarp::os::Bottle::clear
void clear()
Empties the bottle of any objects it contains.
Definition: Bottle.cpp:124
yarp::os::Bottle::fromBinary
void fromBinary(const char *buf, size_t len)
Initializes bottle from a binary representation.
Definition: Bottle.cpp:219
yarp::os::PortReader::read
virtual bool read(ConnectionReader &reader)=0
Read this object from a network connection.
yarp::os::Searchable
A base class for nested structures that can be searched.
Definition: Searchable.h:68
yarp::os::Bottle::size
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
BOTTLE_TAG_LIST
#define BOTTLE_TAG_LIST
Definition: Bottle.h:30
yarp::os::Bottle::pop
Value pop()
Removes a Value v from the end of the list and returns this value.
Definition: Bottle.cpp:197
yarp::os::Bottle::operator=
Bottle & operator=(const Bottle &rhs)
Copy assignment operator.
Definition: Bottle.cpp:102
yarp::os::impl::BottleImpl
A flexible data format for holding a bunch of numbers and strings.
Definition: BottleImpl.h:35
yarp::os::DummyConnector::getReader
ConnectionReader & getReader()
Get the dummy ConnectionReader loaded with whatever was written the ConnectionWriter since it was las...
Definition: DummyConnector.cpp:113
BOTTLE_TAG_STRING
#define BOTTLE_TAG_STRING
Definition: Bottle.h:28
yarp::os::Bottle::fromString
void fromString(const std::string &text)
Initializes bottle from a string.
Definition: Bottle.cpp:207
yarp::os::Bottle::describeBottleCode
static std::string describeBottleCode(int code)
Convert a numeric bottle code to a string.
Definition: Bottle.cpp:406
yarp::os::Bottle::operator!=
bool operator!=(const Bottle &alt) const
Inequality test.
Definition: Bottle.cpp:378
yarp::os::impl::Storable
A single item in a Bottle.
Definition: Storable.h:46
LogComponent.h
yarp::os::PortWriter
Interface implemented by all objects that can write themselves to the network, such as Bottle objects...
Definition: PortWriter.h:26
yarp::os::Bottle::addFloat64
void addFloat64(yarp::conf::float64_t x)
Places a 64-bit floating point number in the bottle, at the end of the list.
Definition: Bottle.cpp:161
yarp::os::Bottle::find
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Bottle.cpp:290
BOTTLE_TAG_INT32
#define BOTTLE_TAG_INT32
Definition: Bottle.h:23
yarp::os::Bottle::addInt8
void addInt8(std::int8_t x)
Places a 8-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:131
NetType.h
yarp::os::Bottle::addInt64
void addInt64(std::int64_t x)
Places a 64-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:149
yarp::os::Bottle::addDict
Property & addDict()
Places an empty key/value object in the bottle, at the end of the list.
Definition: Bottle.cpp:191
yarp::os::Bottle::check
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Bottle.cpp:280
yarp::os::Bottle::findGroup
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
Definition: Bottle.cpp:305
BOTTLE_TAG_VOCAB
#define BOTTLE_TAG_VOCAB
Definition: Bottle.h:25
yarp::os::Bottle::setReadOnly
void setReadOnly(bool readOnly)
Definition: Bottle.cpp:442
yarp::os::Bottle::addFloat32
void addFloat32(yarp::conf::float32_t x)
Places a 32-bit floating point number in the bottle, at the end of the list.
Definition: Bottle.cpp:155
yarp::os::PortReader
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Definition: PortReader.h:27
yarp::os::Bottle::get
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
yarp::os::Bottle::addInt16
void addInt16(std::int16_t x)
Places a 16-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:137
yarp::os::Bottle::addList
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:185
yarp::os::Bottle::write
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition: Bottle.cpp:233
yarp::os::ConnectionWriter
An interface for writing to a network connection.
Definition: ConnectionWriter.h:39
DummyConnector.h
yarp::os::DummyConnector::getWriter
ConnectionWriter & getWriter()
Get the dummy ConnectionWriter loaded with whatever was written the ConnectionWriter since it was las...
Definition: DummyConnector.cpp:108
yarp::os::Value::isNull
bool isNull() const override
Checks if the object is invalid.
Definition: Value.cpp:383
yarp::os::Bottle::addInt32
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:143
yarp::os::Bottle::hasChanged
void hasChanged()
Declare that the content of the Bottle has been changed.
Definition: Bottle.cpp:259
yarp::os::PortWriter::write
virtual bool write(ConnectionWriter &writer) const =0
Write this object to a network connection.
yarp::os::Bottle::addString
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
yarp::os::Bottle::addVocab
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
yarp::os::Bottle::getNullBottle
static Bottle & getNullBottle()
A special Bottle with no content.
Definition: Bottle.cpp:345
yarp::os::Value::isList
virtual bool isList() const
Checks if value is a list.
Definition: Value.cpp:165
yCAssert
#define yCAssert(component, x)
Definition: LogComponent.h:172
yarp::os::Bottle::isNull
bool isNull() const override
Checks if the object is invalid.
Definition: Bottle.cpp:373
yarp::conf::float32_t
float float32_t
Definition: numeric.h:50
yarp::os::ConnectionReader
An interface for reading from a network connection.
Definition: ConnectionReader.h:39
yarp::os::Bottle::tail
Bottle tail() const
Get all but the first element of a bottle.
Definition: Bottle.cpp:391
BOTTLE_TAG_BLOB
#define BOTTLE_TAG_BLOB
Definition: Bottle.h:29
yarp::os::Bottle::operator==
bool operator==(const Bottle &alt) const
Equality test.
Definition: Bottle.cpp:351
yarp::os::NetType::toString
static std::string toString(int x)
Definition: NetType.cpp:138
BOTTLE_TAG_FLOAT64
#define BOTTLE_TAG_FLOAT64
Definition: Bottle.h:27
yarp::os::DummyConnector::setTextMode
void setTextMode(bool textmode)
Set the textMode of the dummy connection.
Definition: DummyConnector.cpp:98
yarp::os::Bottle::copy
void copy(const Bottle &alt, size_type first=0, size_type len=npos)
Copy all or part of another Bottle.
Definition: Bottle.cpp:269
yarp::os::Bottle::read
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:243
yarp::os::Value::asList
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
BOTTLE_TAG_DICT
#define BOTTLE_TAG_DICT
Definition: Bottle.h:31
yarp::conf::float64_t
double float64_t
Definition: numeric.h:51
implementation
RandScalar * implementation(void *t)
Definition: RandnScalar.cpp:20
yarp::os::Bottle::onCommencement
void onCommencement() const override
This is called when the port is about to begin writing operations.
Definition: Bottle.cpp:238
yarp::os::Bottle::~Bottle
virtual ~Bottle()
Destructor.
Definition: Bottle.cpp:119
yarp::os::Bottle::add
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition: Bottle.cpp:339
yarp::os::Value::toString
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:46
NullBottle
Definition: Bottle.cpp:33
YARP_OS_LOG_COMPONENT
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:37
yarp::os::Bottle::getSpecialization
int getSpecialization()
Get numeric bottle code for this bottle.
Definition: Bottle.cpp:264
NullBottle::NullBottle
NullBottle()
Definition: Bottle.cpp:36
Bottle.h
yarp::os::Property
A class for storing options and configuration information.
Definition: Property.h:34
yarp::os::Bottle::append
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
Definition: Bottle.cpp:383
yarp::os::Bottle::toBinary
const char * toBinary(size_t *size=nullptr)
Returns binary representation of bottle.
Definition: Bottle.cpp:225