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