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