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