YARP
Yet Another Robot Platform
StreamConnectionReader.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  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <yarp/os/Bottle.h>
11 #include <yarp/os/Log.h>
12 #include <yarp/os/NetType.h>
14 #include <yarp/os/impl/Protocol.h>
16 
17 using namespace yarp::os::impl;
18 using namespace yarp::os;
19 
22  writer(nullptr),
23  in(nullptr),
24  str(nullptr),
25  protocol(nullptr),
26  messageLen(0),
27  textMode(false),
28  bareMode(false),
29  valid(false),
30  err(false),
31  shouldDrop(false),
32  writePending(false),
33  ref(nullptr),
34  convertedTextMode(false),
35  pushedIntFlag(false),
36  pushedInt(-1),
37  parentConnectionReader(nullptr)
38 {
39 }
40 
42 {
43  if (writer != nullptr) {
44  delete writer;
45  writer = nullptr;
46  }
47 }
48 
50  TwoWayStream* str,
51  const Route& route,
52  size_t len,
53  bool textMode,
54  bool bareMode)
55 {
56  this->in = &in;
57  this->str = str;
58  this->route = route;
59  this->messageLen = len;
60  this->textMode = textMode;
61  this->bareMode = bareMode;
62  this->valid = true;
63  ref = nullptr;
64  err = false;
65  convertedTextMode = false;
66  pushedIntFlag = false;
67 }
68 
70 {
71  this->protocol = protocol;
72 }
73 
75 {
76  str = nullptr;
77 }
78 
80 {
81  return shouldDrop;
82 }
83 
85 {
86  if (!isGood()) {
87  return false;
88  }
89  yAssert(in != nullptr);
90  size_t len = b.length();
91  if (len == 0) {
92  return true;
93  }
94  //if (len<0) len = messageLen;
95  if (len > 0) {
96  yarp::conf::ssize_t rlen = in->readFull(b);
97  if (rlen >= 0) {
98  messageLen -= len;
99  return true;
100  }
101  }
102  err = true;
103  return false;
104 }
105 
106 #ifndef YARP_NO_DEPRECATED // Since YARP 3.2
108 {
109  if (!isGood()) {
110  return {};
111  }
112  char* buf = new char[len];
113  yarp::os::Bytes b(buf, len);
114  yAssert(in != nullptr);
115  yarp::conf::ssize_t r = in->read(b);
116  if (r < 0 || static_cast<size_t>(r) < b.length()) {
117  err = true;
118  delete[] buf;
119  return {};
120  }
121  messageLen -= b.length();
122  std::string s = buf;
123  delete[] buf;
124  return s;
125 }
126 #endif // YARP_NO_DEPRECATED
127 
129 {
130  if (!isGood()) {
131  return {};
132  }
133  yAssert(in != nullptr);
134  bool success = false;
135  std::string result = in->readLine('\n', &success);
136  if (!success) {
137  err = true;
138  return {};
139  }
140  messageLen -= result.length() + 1;
141  return result;
142 }
143 
145 {
146  if (writer != nullptr) {
147  if (writePending) {
148  if (str != nullptr) {
149  if (protocol != nullptr) {
150  protocol->reply(*writer);
151  } else {
152  writer->write(str->getOutputStream());
153  }
154  writer->clear();
155  }
156  }
157  }
158  writePending = false;
159 }
160 
162 {
163  ref = obj;
164 }
165 
167 {
168  reset(*in, str, route, len, textMode, bareMode);
169  return true;
170 }
171 
173 {
174  return messageLen + (pushedIntFlag ? sizeof(yarp::os::NetInt32) : 0);
175 }
176 
178 {
179  if (pushedIntFlag) {
180  return false;
181  }
182  pushedIntFlag = true;
183  pushedInt = x;
184  return true;
185 }
186 
187 template <typename T, typename NetT>
188 inline T StreamConnectionReader::expectType()
189 {
190  yAssert(in != nullptr);
191 
192  NetT x = 0;
193  yarp::os::Bytes b(reinterpret_cast<char*>(&x), sizeof(T));
194  yarp::conf::ssize_t r = in->read(b);
195  if (r < 0 || static_cast<size_t>(r) < b.length()) {
196  err = true;
197  return 0;
198  }
199  messageLen -= b.length();
200 
201  return static_cast<T>(x);
202 }
203 
205 {
206  if (!isGood()) {
207  return 0;
208  }
209  return expectType<std::int8_t, NetInt8>();
210 }
211 
213 {
214  if (!isGood()) {
215  return 0;
216  }
217  return expectType<std::int16_t, NetInt16>();
218 }
219 
221 {
222  if (pushedIntFlag) {
223  pushedIntFlag = false;
224  return pushedInt;
225  }
226  if (!isGood()) {
227  return 0;
228  }
229  return expectType<std::int32_t, NetInt32>();
230 }
231 
233 {
234  if (!isGood()) {
235  return 0;
236  }
237  return expectType<std::int64_t, NetInt64>();
238 }
239 
241 {
242  if (!isGood()) {
243  return 0;
244  }
245  return expectType<yarp::conf::float32_t, NetFloat32>();
246 }
247 
249 {
250  if (!isGood()) {
251  return 0;
252  }
253  return expectType<yarp::conf::float64_t, NetFloat64>();
254 }
255 
256 bool StreamConnectionReader::expectBlock(char* data, size_t len)
257 {
258  yarp::os::Bytes bytes(data, len);
259  return expectBlock(bytes);
260 }
261 
262 std::string StreamConnectionReader::expectText(const char terminatingChar)
263 {
264  if (!isGood()) {
265  return {};
266  }
267  yAssert(in != nullptr);
268  bool lsuccess = false;
269  std::string result = in->readLine(terminatingChar, &lsuccess);
270  if (lsuccess) {
271  messageLen -= result.length() + 1;
272  }
273  return result;
274 }
275 
277 {
278  return textMode;
279 }
280 
282 {
283  return bareMode;
284 }
285 
287 {
288  if (isTextMode()) {
289  if (!convertedTextMode) {
290  Bottle bot;
291  bot.read(*this);
293  bot.write(writer);
294  std::string s = writer.toString();
295  altStream.reset(s);
296  in = &altStream;
297  convertedTextMode = true;
298  }
299  }
300 
301  return true;
302 }
303 
305 {
306  if (str == nullptr) {
307  return nullptr;
308  }
309  if (writer == nullptr) {
311  yAssert(writer != nullptr);
312  }
313  writer->clear();
314  writePending = true;
315  if (protocol != nullptr) {
316  protocol->willReply();
317  }
318  return writer;
319 }
320 
322 {
323  if (str != nullptr) {
324  Contact remote = str->getRemoteAddress();
325  remote.setName(route.getFromName());
326  return remote;
327  }
328  Contact remote = yarp::os::Contact(route.getFromName(), route.getCarrierName());
329  return remote;
330 }
331 
333 {
334  if (str != nullptr) {
335  Contact local = str->getLocalAddress();
336  local.setName(route.getToName());
337  return local;
338  }
339  return yarp::os::Contact();
340 }
341 
343 {
344  return valid;
345 }
346 
348 {
349  if (err) {
350  return true;
351  }
352  return !isActive();
353 }
354 
356 {
357  if (shouldDrop) {
358  return false;
359  }
360  if (!isValid()) {
361  return false;
362  }
363  if (in != nullptr) {
364  if (in->isOk()) {
365  return true;
366  }
367  }
368  return false;
369 }
370 
372 {
373  return ref;
374 }
375 
377 {
378  if (protocol != nullptr) {
379  const std::string& env = protocol->getEnvelope();
380  return {const_cast<char*>(env.c_str()), env.length()};
381  }
382  if (parentConnectionReader != nullptr) {
383  return parentConnectionReader->readEnvelope();
384  }
385  return {nullptr, 0};
386 }
387 
389 {
390  shouldDrop = true;
391 }
392 
394 {
395  if (config.size() == 0) {
396  if (protocol != nullptr) {
397  const_cast<Bottle&>(config).fromString(protocol->getSenderSpecifier());
398  }
399  }
400  return config;
401 }
402 
404 {
405  this->parentConnectionReader = parentConnectionReader;
406 }
407 
408 bool StreamConnectionReader::isGood()
409 {
410  return isActive() && isValid() && !isError();
411 }
#define yAssert(x)
Definition: Log.h:297
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:243
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
Definition: Bottle.cpp:233
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
size_t length() const
Definition: Bytes.cpp:25
An interface for reading from a network connection.
virtual Bytes readEnvelope()
Read a message envelope, if available.
An interface for writing to a network connection.
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
void setName(const std::string &name)
Set the name associated with this Contact.
Definition: Contact.cpp:225
Simple specification of the minimum functions needed from input streams.
Definition: InputStream.h:29
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:23
yarp::conf::ssize_t readFull(Bytes &b)
Keep reading until buffer is full.
Definition: InputStream.cpp:99
std::string readLine(const char terminal='\n', bool *success=nullptr)
Read a block of text terminated with a specific marker (or EOF).
Definition: InputStream.cpp:57
This is a base class for objects that can be both read from and be written to the YARP network.
Definition: Portable.h:29
Information about a connection between two ports.
Definition: Route.h:32
const std::string & getToName() const
Get the destination of the route.
Definition: Route.cpp:106
const std::string & getCarrierName() const
Get the carrier type of the route.
Definition: Route.cpp:126
const std::string & getFromName() const
Get the source of the route.
Definition: Route.cpp:96
A base class for nested structures that can be searched.
Definition: Searchable.h:69
A stream which can be asked to perform bidirectional communication.
Definition: TwoWayStream.h:29
virtual OutputStream & getOutputStream()=0
Get an OutputStream to write to.
virtual const Contact & getLocalAddress() const =0
Get the address of the local side of the stream.
virtual const Contact & getRemoteAddress() const =0
Get the address of the remote side of the stream.
A helper for creating cached object descriptions.
bool write(ConnectionWriter &connection) const override
Write this object to a network connection.
void clear() override
Clear all cached data.
Connection choreographer.
Definition: Protocol.h:34
std::string getSenderSpecifier() const override
Extract a name for the sender, if the connection type supports that.
Definition: Protocol.cpp:152
const std::string & getEnvelope() const override
Read the envelope associated with the current message.
Definition: Protocol.cpp:181
void reply(SizedWriter &writer) override
Reply to a message we have just read.
Definition: Protocol.cpp:323
void willReply()
Promise that we'll be making a reply.
Definition: Protocol.h:93
virtual std::string expectString()
Read a string from the network connection.
std::int64_t expectInt64() override
Read a 64-bit integer from the network connection.
yarp::os::Contact getRemoteContact() const override
Gets information about who is supplying the data being read, if that information is available.
bool convertTextMode() override
Reads in a standard description in text mode, and converts it to a standard description in binary.
void setParentConnectionReader(ConnectionReader *parentConnectionReader) override
Set ConnectionReader to be used for reading the envelope.
yarp::os::ConnectionWriter * getWriter() override
Gets a way to reply to the message, if possible.
bool pushInt(int x) override
Store an integer to return on the next call to expectInt()
bool isBareMode() const override
Check if the connection is bare mode.
std::int16_t expectInt16() override
Read a 16-bit integer from the network connection.
yarp::conf::float64_t expectFloat64() override
Read a 64-bit floating point number from the network connection.
yarp::os::Contact getLocalContact() const override
Gets information about who is receiving the data, if that information is available.
const yarp::os::Searchable & getConnectionModifiers() const override
Access modifiers associated with the connection, if any.
size_t getSize() const override
Checks how much data is available.
std::string expectText(const char terminatingChar) override
Read some text from the network connection.
std::int8_t expectInt8() override
Read a 8-bit integer from the network connection.
yarp::conf::float32_t expectFloat32() override
Read a 32-bit floating point number from the network connection.
yarp::os::Bytes readEnvelope() override
Read a message envelope, if available.
void reset(yarp::os::InputStream &in, TwoWayStream *str, const Route &route, size_t len, bool textMode, bool bareMode=false)
virtual bool expectBlock(yarp::os::Bytes &b)
bool isTextMode() const override
Check if the connection is text mode.
yarp::os::Portable * getReference() const override
Get a direct pointer to the object being sent, if possible.
virtual void setReference(yarp::os::Portable *obj)
std::int32_t expectInt32() override
Read a 32-bit integer from the network connection.
void requestDrop() override
Tag the connection to be dropped after the current message.
::ssize_t ssize_t
Definition: numeric.h:60
double float64_t
Definition: numeric.h:51
float float32_t
Definition: numeric.h:50
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
std::int32_t NetInt32
Definition of the NetInt32 type.
Definition: NetInt32.h:33