YARP
Yet Another Robot Platform
NameserCarrier.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 
11 
13 #include <yarp/os/Route.h>
14 #include <yarp/os/SizedWriter.h>
15 
16 #include <string>
17 
18 using namespace yarp::os;
19 using namespace yarp::os::impl;
20 
22  delegate(delegate),
23  pendingRead(""),
24  swallowRead("VER ")
25 {
26 }
27 
29 {
30  if (delegate != nullptr) {
31  delete delegate;
32  delegate = nullptr;
33  }
34 }
35 
37 {
38  return *this;
39 }
40 
42 {
43  return delegate->getOutputStream();
44 }
45 
47 {
48  return delegate->getLocalAddress();
49 }
50 
52 {
53  return delegate->getRemoteAddress();
54 }
55 
57 {
58  return delegate->isOk();
59 }
60 
62 {
63  delegate->reset();
64 }
65 
67 {
68  delegate->close();
69 }
70 
72 {
73  delegate->beginPacket();
74 }
75 
77 {
78  delegate->endPacket();
79 }
80 
82 {
83  // assume it is ok for name_ser to go byte-by-byte
84  // since this protocol will be phased out
85  if (b.length() <= 0) {
86  return 0;
87  }
88  Bytes tmp(b.get(), 1);
89  while (swallowRead.length() > 0) {
90  yarp::conf::ssize_t r = delegate->getInputStream().read(tmp);
91  if (r <= 0) {
92  return r;
93  }
94  swallowRead = swallowRead.substr(1, swallowRead.length() - 1);
95  }
96  if (pendingRead.length() > 0) {
97  b.get()[0] = pendingRead[0];
98  pendingRead = pendingRead.substr(1, pendingRead.length() - 1);
99  return 1;
100  }
101  yarp::conf::ssize_t r = delegate->getInputStream().read(tmp);
102  if (r <= 0) {
103  return r;
104  }
105  if (tmp.get()[0] == '\n') {
106  pendingRead = "";
107  swallowRead = "NAME_SERVER ";
108  }
109  return r;
110 }
111 
112 
114 {
115  firstSend = true;
116 }
117 
119 {
120  return "name_ser";
121 }
122 
124 {
125  return "NAME_SER";
126 }
127 
129 {
130  return new NameserCarrier();
131 }
132 
134 {
135  if (header.length() == 8) {
136  std::string target = getSpecifierName();
137  for (int i = 0; i < 8; i++) {
138  if (!(target[i] == header.get()[i])) {
139  return false;
140  }
141  }
142  return true;
143  }
144  return false;
145 }
146 
148 {
149  if (header.length() == 8) {
150  std::string target = getSpecifierName();
151  for (int i = 0; i < 8; i++) {
152  header.get()[i] = target[i];
153  }
154  }
155 }
156 
157 
159 {
160  return false;
161 }
162 
164 {
165  return true;
166 }
167 
169 {
170  return true;
171 }
172 
174 {
175  return false;
176 }
177 
179 {
180  std::string target = getSpecifierName();
181  yarp::os::Bytes b((char*)target.c_str(), 8);
182  proto.os().write(b);
183  proto.os().flush();
184  return proto.os().isOk();
185 }
186 
188 {
189  Route route = proto.getRoute();
190  route.setFromName("anon");
191  proto.setRoute(route);
192  return true;
193 }
194 
196 {
197  YARP_UNUSED(proto);
198  return true;
199 }
200 
202 {
203  YARP_UNUSED(proto);
204  return true;
205 }
206 
208 {
209  YARP_UNUSED(proto);
210  return true;
211 }
212 
214 {
215  // I am the receiver
216  auto* stream = new NameserTwoWayStream(proto.giveStreams());
217  proto.takeStreams(stream);
218  return true;
219 }
220 
222 {
223  YARP_UNUSED(proto);
224  // I am the sender
225  return true;
226 }
227 
229 {
230  std::string target = firstSend ? "VER " : "NAME_SERVER ";
231  Bytes b((char*)target.c_str(), target.length());
232  proto.os().write(b);
233  proto.os().flush();
234  std::string txt;
235  // ancient nameserver can't deal with quotes
236  for (size_t i = 0; i < writer.length(); i++) {
237  for (size_t j = 0; j < writer.length(i); j++) {
238  char ch = writer.data(i)[j];
239  if (ch != '\"') {
240  txt += ch;
241  }
242  }
243  }
244  Bytes b2((char*)txt.c_str(), txt.length());
245  proto.os().write(b2);
246  proto.os().flush();
247  firstSend = false;
248  return proto.os().isOk();
249 }
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
size_t length() const
Definition: Bytes.cpp:25
const char * get() const
Definition: Bytes.cpp:30
A base class for connection types (tcp, mcast, shmem, ...) which are called carriers in YARP.
Definition: Carrier.h:48
The basic state of a connection - route, streams in use, etc.
virtual const Route & getRoute() const =0
Get the route associated with this connection.
virtual TwoWayStream * giveStreams()=0
Take ownership of the streams associated with the connection.
virtual void takeStreams(TwoWayStream *streams)=0
Provide streams to be used with the connection.
OutputStream & os()
Shorthand for getOutputStream()
virtual void setRoute(const Route &route)=0
Set the route associated with this connection.
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
Simple specification of the minimum functions needed from input streams.
Definition: InputStream.h:29
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:23
Simple specification of the minimum functions needed from output streams.
Definition: OutputStream.h:25
virtual void flush()
Make sure all pending write operations are finished.
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
virtual void write(char ch)
Write a single byte to the stream.
Information about a connection between two ports.
Definition: Route.h:32
void setFromName(const std::string &fromName)
Set the source of the route.
Definition: Route.cpp:101
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:36
virtual size_t length() const =0
virtual const char * data(size_t index) const =0
A stream which can be asked to perform bidirectional communication.
Definition: TwoWayStream.h:29
Communicating between two ports via a variant plain-text protocol originally designed for the yarp na...
bool write(ConnectionState &proto, SizedWriter &writer) override
Write a message.
bool canEscape() const override
Check if carrier can encode administrative messages, as opposed to just user data.
bool respondToHeader(ConnectionState &proto) override
Respond to the header.
bool requireAck() const override
Check if carrier has flow control, requiring sent messages to be acknowledged by recipient.
std::string getName() const override
Get the name of this connection type ("tcp", "mcast", "shmem", ...)
bool sendHeader(ConnectionState &proto) override
Write a header appropriate to the carrier to the connection, followed by any carrier-specific data.
void getHeader(Bytes &header) const override
Provide 8 bytes describing this connection sufficiently to allow the other side of a connection to se...
Carrier * create() const override
Factory method.
bool expectReplyToHeader(ConnectionState &proto) override
Process reply to header, if one is expected for this carrier.
bool expectIndex(ConnectionState &proto) override
Expect a message header, if there is one for this carrier.
bool expectSenderSpecifier(ConnectionState &proto) override
Expect the name of the sending port.
bool checkHeader(const Bytes &header) override
Given the first 8 bytes received on a connection, decide if this is the right carrier type to use for...
bool sendAck(ConnectionState &proto) override
Send an acknowledgement, if needed for this carrier.
bool supportReply() const override
This flag is used by YARP to determine whether the connection can carry RPC traffic,...
std::string getSpecifierName() const
bool expectAck(ConnectionState &proto) override
Receive an acknowledgement, if expected for this carrier.
bool isTextMode() const override
Check if carrier is textual in nature.
Communicating between two ports via a variant plain-text protocol originally designed for the yarp na...
void reset() override
Reset the stream.
const Contact & getLocalAddress() const override
Get the address of the local side of the stream.
OutputStream & getOutputStream() override
Get an OutputStream to write to.
InputStream & getInputStream() override
Get an InputStream to read from.
NameserTwoWayStream(TwoWayStream *delegate)
void endPacket() override
Mark the end of a logical packet (see beginPacket).
bool isOk() const override
Check if the stream is ok or in an error state.
void close() override
Terminate the stream.
void beginPacket() override
Mark the beginning of a logical packet.
const Contact & getRemoteAddress() const override
Get the address of the remote side of the stream.
::ssize_t ssize_t
Definition: numeric.h:60
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
#define YARP_UNUSED(var)
Definition: api.h:159