YARP
Yet Another Robot Platform
NameServer.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-License-Identifier: BSD-3-Clause
5  */
6 
8 
9 #include <yarp/conf/string.h>
10 #include <yarp/conf/version.h>
11 
13 #include <yarp/os/ManagedBytes.h>
14 #include <yarp/os/NetType.h>
15 #include <yarp/os/Network.h>
16 #include <yarp/os/Port.h>
17 #include <yarp/os/Property.h>
18 #include <yarp/os/Time.h>
19 #include <yarp/os/Value.h>
20 #include <yarp/os/Vocab.h>
23 
24 #include <map>
25 #include <set>
26 
27 using namespace yarp::os::impl;
28 using namespace yarp::os;
29 
30 YARP_OS_LOG_COMPONENT(NAMESERVER, "yarp.os.impl.NameServer")
31 
32 // produce a correctly parsed string in presence of quoting
33 static std::string STR_HELP(const char* txt)
34 {
35  Value v;
36  v.fromString(txt);
37  return v.asString();
38 }
39 #define STR(x) STR_HELP(x).c_str()
40 
43 //
44 // Basic functionality
45 //
48 
49 
50 Contact NameServer::unregisterName(const std::string& name)
51 {
52  Contact prev = queryName(name);
53  if (prev.isValid()) {
54  if (prev.getPort() != -1) {
55  NameRecord& rec = getNameRecord(prev.getRegName());
56  if (rec.isReusablePort()) {
57  HostRecord& host = getHostRecord(prev.getHost());
58  host.release(prev.getPort());
59  }
60  if (rec.isReusableIp()) {
61  if (rec.getAddress().getCarrier() == "mcast") {
62  mcastRecord.releaseAddress(rec.getAddress().getHost().c_str());
63  }
64  }
65  rec.clear();
66  tmpNames.release(name);
67 
68  Bottle event;
69  event.addVocab32("del");
70  event.addString(name.c_str());
71  onEvent(event);
72  }
73  }
74 
75  return queryName(name);
76 }
77 
78 
79 Contact NameServer::registerName(const std::string& name,
80  const Contact& address,
81  const std::string& remote)
82 {
83  bool reusablePort = false;
84  bool reusableIp = false;
85 
86  yCTrace(NAMESERVER, "in registerName...");
87 
88  if (name != "...") {
89  unregisterName(name);
90  }
91 
92  Contact suggestion = address;
93 
94  if (!suggestion.isValid()) {
95  suggestion = Contact(name, "...", "...", 0);
96  }
97 
98  std::string portName = name;
99  if (portName == "...") {
100  portName = tmpNames.get();
101  }
102 
103  std::string carrier = suggestion.getCarrier();
104  if (carrier == "...") {
105  carrier = "tcp";
106  }
107 
108  std::string machine = suggestion.getHost();
109  int overridePort = 0;
110  if (machine == "...") {
111  if (carrier != "mcast") {
112  if (remote == "...") {
113  yCError(NAMESERVER, "remote machine name was not found! can only guess it is local...");
114  machine = "127.0.0.1";
115  } else {
116  machine = remote;
117  }
118  } else {
119  machine = mcastRecord.get();
120  overridePort = mcastRecord.lastPortNumber();
121  reusableIp = true;
122  }
123  }
124 
125  int port = suggestion.getPort();
126  if (port == 0) {
127  if (overridePort != 0) {
128  port = overridePort;
129  } else {
130  port = getHostRecord(machine).get();
131  reusablePort = true;
132  }
133  }
134 
135  suggestion = Contact(portName, carrier, machine, port);
136 
137  yCDebug(NAMESERVER, "Registering %s for %s", suggestion.toURI().c_str(), suggestion.getRegName().c_str());
138 
139  NameRecord& nameRecord = getNameRecord(suggestion.getRegName());
140  nameRecord.setAddress(suggestion, reusablePort, reusableIp);
141 
142  Bottle event;
143  event.addVocab32("add");
144  event.addString(suggestion.getRegName().c_str());
145  onEvent(event);
146 
147  return nameRecord.getAddress();
148 }
149 
150 
151 Contact NameServer::queryName(const std::string& name)
152 {
153  std::string base = name;
154  std::string pat;
155  if (name.find("/net=") == 0) {
156  constexpr size_t patStart = 5;
157  size_t patEnd = name.find('/', patStart);
158  if (patEnd >= patStart && patEnd != std::string::npos) {
159  pat = name.substr(patStart, patEnd - patStart);
160  base = name.substr(patEnd);
161  yCDebug(NAMESERVER, "Special query form %s (%s/%s)", name.c_str(), pat.c_str(), base.c_str());
162  }
163  }
164 
165  NameRecord* rec = getNameRecord(base, false);
166  if (rec != nullptr) {
167  if (!pat.empty()) {
168  std::string ip = rec->matchProp("ips", pat);
169  if (!ip.empty()) {
170  auto sip = yarp::conf::string::split(ip, ' ');
171  Contact c = rec->getAddress();
172  c.setHost(sip.at(0));
173  return c;
174  }
175  }
176  return rec->getAddress();
177  }
178  return Contact();
179 }
180 
181 
182 NameServer::NameRecord* NameServer::getNameRecord(const std::string& name,
183  bool create)
184 {
185  auto entry = nameMap.find(name);
186  if (entry == nameMap.end()) {
187  if (!create) {
188  return nullptr;
189  }
190  nameMap.emplace(name, NameRecord());
191  entry = nameMap.find(name);
192  }
193  yCAssert(NAMESERVER, entry != nameMap.end());
194  return &(entry->second);
195 }
196 
197 
198 NameServer::HostRecord* NameServer::getHostRecord(const std::string& name,
199  bool create)
200 {
201  auto entry = hostMap.find(name);
202  if (entry == hostMap.end()) {
203  if (!create) {
204  return nullptr;
205  }
206  hostMap[name] = HostRecord();
207  entry = hostMap.find(name);
208  entry->second.setBase(basePort);
209  }
210  yCAssert(NAMESERVER, entry != hostMap.end());
211  return &(entry->second);
212 }
213 
214 
217 //
218 // Remote interface
219 //
222 
223 
224 void NameServer::setup()
225 {
226 
227  basePort = NetworkBase::getDefaultPortRange() + 2;
228 
229  dispatcher.add("register", &NameServer::cmdRegister);
230  dispatcher.add("unregister", &NameServer::cmdUnregister);
231  dispatcher.add("query", &NameServer::cmdQuery);
232  dispatcher.add("help", &NameServer::cmdHelp);
233  dispatcher.add("set", &NameServer::cmdSet);
234  dispatcher.add("get", &NameServer::cmdGet);
235  dispatcher.add("check", &NameServer::cmdCheck);
236  dispatcher.add("match", &NameServer::cmdMatch);
237  dispatcher.add("list", &NameServer::cmdList);
238  dispatcher.add("route", &NameServer::cmdRoute);
239  dispatcher.add("gc", &NameServer::cmdGarbageCollect);
240  dispatcher.add("bot", &NameServer::cmdBot);
241  dispatcher.add("announce", &NameServer::cmdAnnounce);
242 
243  ndispatcher.add("list", &NameServer::ncmdList);
244  ndispatcher.add("query", &NameServer::ncmdQuery);
245  ndispatcher.add("version", &NameServer::ncmdVersion);
246  ndispatcher.add("set", &NameServer::ncmdSet);
247  ndispatcher.add("get", &NameServer::ncmdGet);
248 }
249 
250 std::string NameServer::cmdRegister(int argc, char* argv[])
251 {
252 
253  std::string remote = argv[0];
254  argc--;
255  argv++;
256 
257  if (argc < 1) {
258  return "need at least one argument";
259  }
260  std::string portName = STR(argv[0]);
261 
262  std::string machine = "...";
263  std::string carrier = "...";
264  int port = 0;
265  if (argc >= 2) {
266  carrier = argv[1];
267  }
268  if (argc >= 3) {
269  machine = argv[2];
270  }
271  if (argc >= 4) {
272  if (std::string("...") == argv[3]) {
273  port = 0;
274  } else {
275  port = yarp::conf::numeric::from_string<int>(argv[3]);
276  }
277  }
278 
279  Contact address = registerName(portName, Contact(portName, carrier, machine, port), remote);
280 
281  yCDebug(NAMESERVER, "name server register address -- %s", address.toString().c_str());
282 
283  return terminate(textify(address));
284 }
285 
286 
287 std::string NameServer::cmdQuery(int argc, char* argv[])
288 {
289  // ignore source
290  argc--;
291  argv++;
292 
293  if (argc < 1) {
294  return "need at least one argument";
295  }
296  std::string portName = STR(argv[0]);
297  Contact address = queryName(portName);
298  return terminate(textify(address));
299 }
300 
301 std::string NameServer::cmdUnregister(int argc, char* argv[])
302 {
303  // ignore source
304  argc--;
305  argv++;
306 
307  if (argc < 1) {
308  return "need at least one argument";
309  }
310  std::string portName = STR(argv[0]);
311  Contact address = unregisterName(portName);
312  return terminate(textify(address));
313 }
314 
315 
316 std::string NameServer::cmdAnnounce(int argc, char* argv[])
317 {
318  // ignore source
319  argc--;
320  argv++;
321 
322  return terminate("ok\n");
323 }
324 
325 std::string NameServer::cmdRoute(int argc, char* argv[])
326 {
327  // ignore source
328  argc--;
329  argv++;
330 
331  if (argc < 2) {
332  return terminate("need at least two arguments: the source port and the target port\n(followed by an optional list of carriers in decreasing order of desirability)");
333  }
334  std::string src = STR(argv[0]);
335  std::string dest = STR(argv[1]);
336 
337  argc -= 2;
338  argv += 2;
339 
340  const char* altArgv[] = {
341  "local",
342  "shmem",
343  "mcast",
344  "udp",
345  "tcp",
346  "text"};
347  int altArgc = 6;
348 
349  if (argc == 0) {
350  argc = altArgc;
351  argv = (char**)altArgv;
352  }
353 
354 
355  NameRecord& srcRec = getNameRecord(src);
356  NameRecord& destRec = getNameRecord(dest);
357  std::string pref;
358 
359  for (int i = 0; i < argc; i++) {
360  std::string carrier = argv[i];
361  if (srcRec.checkProp("offers", carrier) && destRec.checkProp("accepts", carrier)) {
362  bool ok = true;
363  if (carrier == "local" || carrier == "shmem") {
364  if (srcRec.getProp("ips") == destRec.getProp("ips")) {
365  if (carrier == "local") {
366  if (srcRec.getProp("process") != destRec.getProp("process")) {
367  ok = false;
368  }
369  }
370  } else {
371  ok = false;
372  }
373  }
374  if (ok) {
375  pref = carrier;
376  break;
377  }
378  }
379  }
380  if (!pref.empty()) {
381  pref = pref + ":/" + dest;
382  } else {
383  pref = dest;
384  }
385 
386  std::string result = "port ";
387  result += src + " route " + dest + " = " + pref + "\n";
388  return terminate(result);
389 }
390 
391 
392 std::string NameServer::cmdHelp(int argc, char* argv[])
393 {
394  // ignore source
395  argc--;
396  argv++;
397 
398  std::string result = "Here are some ways to use the name server:\n";
399  //ACE_Vector<std::string> names = dispatcher.getNames();
400  //for (unsigned i=0; i<names.size(); i++) {
401  //const std::string& name = names[i];
402  //result += std::string(" ") + name + " ...\n";
403  //}
404  result += std::string("+ help\n");
405  result += std::string("+ list\n");
406  result += std::string("+ register $portname\n");
407  result += std::string("+ register $portname $carrier $ipAddress $portNumber\n");
408  result += std::string(" (if you want a field set automatically, write '...')\n");
409  result += std::string("+ unregister $portname\n");
410  result += std::string("+ query $portname\n");
411  result += std::string("+ set $portname $property $value\n");
412  result += std::string("+ get $portname $property\n");
413  result += std::string("+ check $portname $property\n");
414  result += std::string("+ match $portname $property $prefix\n");
415  result += std::string("+ route $port1 $port2\n");
416  result += std::string("+ gc\n");
417  return terminate(result);
418 }
419 
420 
421 std::string NameServer::cmdSet(int argc, char* argv[])
422 {
423  // ignore source
424  argc--;
425  argv++;
426 
427  if (argc < 2) {
428  return "need at least two arguments: the port name, and a key";
429  }
430  std::string target = STR(argv[0]);
431  std::string key = argv[1];
432  NameRecord& nameRecord = getNameRecord(target);
433  nameRecord.clearProp(key);
434  for (int i = 2; i < argc; i++) {
435  nameRecord.addProp(key, argv[i]);
436  }
437  return terminate(std::string("port ") + target + " property " + key + " = " + nameRecord.getProp(key) + "\n");
438 }
439 
440 std::string NameServer::cmdGet(int argc, char* argv[])
441 {
442  // ignore source
443  argc--;
444  argv++;
445 
446  if (argc < 2) {
447  return "need exactly two arguments: the port name, and a key";
448  }
449  std::string target = STR(argv[0]);
450  std::string key = argv[1];
451  NameRecord& nameRecord = getNameRecord(target);
452  return terminate(std::string("port ") + target + " property " + key + " = " + nameRecord.getProp(key) + "\n");
453 }
454 
455 std::string NameServer::cmdMatch(int argc, char* argv[])
456 {
457  // ignore source
458  argc--;
459  argv++;
460 
461  if (argc < 3) {
462  return "need exactly three arguments: the port name, a key, and a prefix";
463  }
464  std::string target = STR(argv[0]);
465  std::string key = argv[1];
466  std::string prefix = argv[2];
467  NameRecord& nameRecord = getNameRecord(target);
468  return terminate(std::string("port ") + target + " property " + key + " = " + nameRecord.matchProp(key, prefix) + "\n");
469 }
470 
471 std::string NameServer::cmdCheck(int argc, char* argv[])
472 {
473  // ignore source
474  argc--;
475  argv++;
476 
477  if (argc < 2) {
478  return "need at least two arguments: the port name, and a key";
479  }
480  std::string response;
481  std::string target = STR(argv[0]);
482  std::string key = argv[1];
483  NameRecord& nameRecord = getNameRecord(target);
484  for (int i = 2; i < argc; i++) {
485  std::string val = "false";
486  if (nameRecord.checkProp(key, argv[i])) {
487  val = "true";
488  }
489  if (i > 2) {
490  response += "\n";
491  }
492  response.append("port ").append(target).append(" property ").append(key).append(" value ").append(argv[i]).append(" present ").append(val);
493  }
494  response += "\n";
495  return terminate(response);
496 }
497 
498 
499 std::string NameServer::cmdList(int argc, char* argv[])
500 {
501  YARP_UNUSED(argc);
502  YARP_UNUSED(argv);
503  std::string response;
504 
505  std::multiset<std::string> lines;
506  for (auto& it : nameMap) {
507  NameRecord& rec = it.second;
508  lines.insert(textify(rec.getAddress()));
509  }
510 
511  // return result in alphabetical order
512  for (const auto& line : lines) {
513  response += line;
514  }
515 
516  return terminate(response);
517 }
518 
519 
520 std::string NameServer::cmdBot(int argc, char* argv[])
521 {
522  std::string txt;
523  argc--;
524  argv++;
525  if (argc >= 1) {
526  std::string key = argv[0];
527  argc--;
528  argv++;
529  Bottle result = ndispatcher.dispatch(this, key.c_str(), argc, argv);
530  txt = result.toString();
531  }
532  return txt;
533 }
534 
535 
536 Bottle NameServer::ncmdList(int argc, char* argv[])
537 {
538  Bottle response;
539 
540  std::string prefix;
541 
542  if (argc == 1) {
543  prefix = STR(argv[0]);
544  }
545 
546  response.addString("ports");
547  for (auto& it : nameMap) {
548  NameRecord& rec = it.second;
549  std::string iname = rec.getAddress().getRegName();
550  if (iname.find(prefix) == 0) {
551  if (iname == prefix || iname[prefix.length()] == '/' || prefix[prefix.length() - 1] == '/') {
552  if (rec.getAddress().isValid()) {
553  response.addList() = botify(rec.getAddress());
554  }
555  }
556  }
557  }
558 
559  return response;
560 }
561 
562 
563 yarp::os::Bottle NameServer::ncmdQuery(int argc, char* argv[])
564 {
565  Bottle response;
566  if (argc == 1) {
567  std::string portName = STR(argv[0]);
568  Contact address = queryName(portName);
569  response = botify(address);
570  }
571  return response;
572 }
573 
574 
575 yarp::os::Bottle NameServer::ncmdVersion(int argc, char* argv[])
576 {
577  YARP_UNUSED(argc);
578  YARP_UNUSED(argv);
579  Bottle response;
580  response.addString("version");
581  response.addString(YARP_VERSION);
582  return response;
583 }
584 
585 
586 yarp::os::Bottle NameServer::ncmdSet(int argc, char* argv[])
587 {
588 
589  Bottle response;
590  if (argc >= 2) {
591  std::string target = STR(argv[0]);
592  std::string key = STR(argv[1]);
593  NameRecord& nameRecord = getNameRecord(target);
594  nameRecord.clearProp(key);
595  for (int i = 2; i < argc; i++) {
596  nameRecord.addProp(key, argv[i]);
597  }
598  response.addString("ok");
599  }
600  return response;
601 }
602 
603 yarp::os::Bottle NameServer::ncmdGet(int argc, char* argv[])
604 {
605  Bottle response;
606  if (argc == 2) {
607  std::string target = STR(argv[0]);
608  std::string key = argv[1];
609  NameRecord& nameRecord = getNameRecord(target);
610  return Bottle(nameRecord.getProp(key));
611  }
612  return response;
613 }
614 
615 
616 std::string NameServer::cmdGarbageCollect(int argc, char* argv[])
617 {
618  YARP_UNUSED(argc);
619  YARP_UNUSED(argv);
620  std::string response;
621 
622  response = "No cleaning done.\n";
623 
624  return terminate(response);
625 }
626 
627 
628 std::string NameServer::textify(const Contact& address)
629 {
630  std::string result;
631  if (address.isValid()) {
632  if (address.getPort() >= 0) {
633  result = "registration name ";
634  result = result + address.getRegName() + " ip " + address.getHost() + " port " + yarp::conf::numeric::to_string(address.getPort()) + " type " + address.getCarrier() + "\n";
635  } else {
636  result = "registration name ";
637  result = result + address.getRegName() + " ip " + "none" + " port " + "none" + " type " + address.getCarrier() + "\n";
638  }
639  }
640  return result;
641 }
642 
643 
645 {
646  Bottle result;
647  if (address.isValid()) {
648  Bottle bname;
649  bname.addString("name");
650  bname.addString(address.getRegName().c_str());
651  Bottle bip;
652  bip.addString("ip");
653  bip.addString(address.getHost().c_str());
654  Bottle bnum;
655  bnum.addString("port_number");
656  bnum.addInt32(address.getPort());
657  Bottle bcarrier;
658  bcarrier.addString("carrier");
659  bcarrier.addString(address.getCarrier().c_str());
660 
661  result.addString("port");
662  result.addList() = bname;
663  result.addList() = bip;
664  result.addList() = bnum;
665  result.addList() = bcarrier;
666  } else {
667  Bottle bstate;
668  bstate.addString("error");
669  bstate.addInt32(-2);
670  bstate.addString("port not known");
671  result.addString("port");
672  result.addList() = bstate;
673  }
674  return result;
675 }
676 
677 
678 static std::string ns_terminate(const std::string& str)
679 {
680  return str + "*** end of message";
681 }
682 
683 std::string NameServer::terminate(const std::string& str)
684 {
685  return ns_terminate(str);
686 }
687 
688 
689 std::string NameServer::apply(const std::string& txt, const Contact& remote)
690 {
691  std::string result = "no command given";
692  mutex.lock();
693  auto ss = yarp::conf::string::split(txt, std::regex{"[\" \t\n]+"});
694  if (ss.size() >= 2) {
695  std::string key = ss.at(1);
696  yCTrace(NAMESERVER, "dispatching to %s", key.c_str());
697  ss.at(1) = remote.getHost();
698 
699  // Create argc/argv containing all arguments but the first one
700  std::vector<char*> args;
701  args.reserve(ss.size());
702  std::transform(ss.begin() + 1, ss.end(), std::back_inserter(args), [](const std::string& str) { return const_cast<char*>(str.c_str()); });
703  args.push_back(nullptr);
704  int argc = static_cast<int>(args.size()) - 1;
705  char** argv = args.data();
706 
707  result = dispatcher.dispatch(this, key.c_str(), argc, argv);
708  if (result.empty()) {
709  Bottle b = ndispatcher.dispatch(this, key.c_str(), argc, argv);
710  result = b.toString();
711  if (!result.empty()) {
712  result = result + "\n";
713  result = terminate(result);
714  }
715  }
716  yCTrace(NAMESERVER, "name server request -- %s", txt.c_str());
717  yCTrace(NAMESERVER, "name server result -- %s", result.c_str());
718  }
719  mutex.unlock();
720  return result;
721 }
722 
723 
724 bool NameServer::apply(const Bottle& cmd, Bottle& result, const Contact& remote)
725 {
726  Bottle rcmd;
727  rcmd.addString("ignored_legacy");
728  rcmd.append(cmd);
729  std::string in = rcmd.toString();
730  std::string out = apply(in, remote);
731  result.fromString(out);
732  return true;
733 }
734 
735 
736 #ifndef DOXYGEN_SHOULD_SKIP_THIS
737 
738 class MainNameServerWorker :
739  public PortReader
740 {
741 private:
742  NameServer* server;
743 
744 public:
745  MainNameServerWorker(NameServer* server)
746  {
747  this->server = server;
748  }
749 
750  bool read(ConnectionReader& reader) override
751  {
752  yCTrace(NAMESERVER, "read start");
753  std::string ref = "NAME_SERVER ";
754  bool ok = true;
755  std::string msg = "?";
756  bool haveMessage = false;
757  if (ok) {
758  if (reader.isTextMode()) {
759  msg = reader.expectText();
760  } else {
761  // migrate to binary mode support, eventually optimize
762  Bottle b;
763  b.read(reader);
764  msg = b.toString();
765  }
766  haveMessage = (!msg.empty());
767  msg = ref + msg;
768  }
769  if (reader.isActive() && haveMessage) {
770  yCDebug(NAMESERVER, "name server got message %s", msg.c_str());
771  size_t index = msg.find("NAME_SERVER");
772  if (index == 0) {
773  Contact remote = reader.getRemoteContact();
774  yCDebug(NAMESERVER, "name server receiving from %s", remote.toURI().c_str());
775  yCDebug(NAMESERVER, "name server request is %s", msg.c_str());
776  std::string result = server->apply(msg, remote);
777  ConnectionWriter* os = reader.getWriter();
778  if (os != nullptr) {
779  if (result.empty()) {
780  result = ns_terminate(std::string("unknown command ") + msg + "\n");
781  }
782  // This change is just to make Microsoft Telnet happy
783  std::string tmp;
784  for (char i : result) {
785  if (i == '\n') {
786  tmp += '\r';
787  }
788  tmp += i;
789  }
790  tmp += '\r';
791  os->appendText(tmp);
792 
793  yCDebug(NAMESERVER, "name server reply is %s", result.c_str());
794  std::string resultSparse = result;
795  size_t end = resultSparse.find("\n*** end of message");
796  if (end != std::string::npos) {
797  resultSparse[end] = '\0';
798  }
799  yCInfo(NAMESERVER, "%s", resultSparse.c_str());
800  }
801  } else {
802  yCInfo(NAMESERVER, "Name server ignoring unknown command: %s", msg.c_str());
803  }
804  }
805  yCTrace(NAMESERVER, "read stop");
806  return true;
807  }
808 };
809 
810 
811 class MainNameServer :
812  public NameServer,
813  public PortReaderCreator
814 {
815 private:
816  Port* port;
817 
818 public:
819  MainNameServer(int basePort, Port* port = nullptr) :
820  port(port)
821  {
822  setBasePort(basePort);
823  }
824 
825  void setPort(Port& port)
826  {
827  this->port = &port;
828  }
829 
830  void onEvent(Bottle& event) override
831  {
832  if (port != nullptr) {
833  port->write(event);
834  }
835  }
836 
837  PortReader* create() const override
838  {
839  return new MainNameServerWorker(const_cast<MainNameServer*>(this));
840  }
841 };
842 
843 
844 #endif // DOXYGEN_SHOULD_SKIP_THIS
#define STR(x)
Definition: NameServer.cpp:39
const yarp::os::LogComponent & NAMESERVER()
Definition: NameServer.cpp:30
static std::string STR_HELP(const char *txt)
Definition: NameServer.cpp:33
static std::string ns_terminate(const std::string &str)
Definition: NameServer.cpp:678
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:74
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
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:182
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:240
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:140
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
An interface for reading from a network connection.
virtual bool isTextMode() const =0
Check if the connection is text mode.
virtual std::string expectText(const char terminatingChar='\n')=0
Read some text from the network connection.
virtual Contact getRemoteContact() const =0
Gets information about who is supplying the data being read, if that information is available.
virtual bool isActive() const =0
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
An interface for writing to a network connection.
virtual void appendText(const std::string &str, const char terminate='\n')=0
Send a terminated string to the network connection.
Represents how to reach a part of a YARP network.
Definition: Contact.h:36
void setHost(const std::string &hostname)
Set the host name to be the input parameter.
Definition: Contact.cpp:233
bool isValid() const
Checks if a Contact is tagged as valid.
Definition: Contact.cpp:298
std::string getRegName() const
Get the name associated with this Contact.
Definition: Contact.cpp:217
std::string toString() const
Get a textual representation of the Contact.
Definition: Contact.cpp:303
std::string toURI(bool includeCarrier=true) const
Get a representation of the Contact as a URI.
Definition: Contact.cpp:313
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition: Contact.cpp:239
std::string getCarrier() const
Get the carrier associated with this Contact for socket communication.
Definition: Contact.cpp:250
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition: Contact.cpp:228
static int getDefaultPortRange()
Under normal operation, YARP has a name server that manages a pool of (socket) ports starting at a po...
Definition: Network.cpp:2002
A creator for readers.
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Definition: PortReader.h:25
A mini-server for network communication.
Definition: Port.h:47
bool write(const PortWriter &writer, const PortWriter *callback=nullptr) const override
Write an object to the port.
Definition: Port.cpp:427
A single value (typically within a Bottle).
Definition: Value.h:45
void fromString(const char *str)
Set value to correspond to a textual representation.
Definition: Value.cpp:351
virtual std::string asString() const
Get string value.
Definition: Value.cpp:234
Implementation of a YARP2-conforming name server.
Definition: NameServer.h:45
static std::string textify(const Contact &address)
Definition: NameServer.cpp:628
std::string apply(const std::string &txt, const Contact &remote) override
Definition: NameServer.cpp:689
Contact queryName(const std::string &name)
Definition: NameServer.cpp:151
static yarp::os::Bottle botify(const Contact &address)
Definition: NameServer.cpp:644
Contact unregisterName(const std::string &name)
Definition: NameServer.cpp:50
std::string terminate(const std::string &str)
Definition: NameServer.cpp:683
Contact registerName(const std::string &name, const Contact &address)
Definition: NameServer.h:57
#define yCInfo(component,...)
Definition: LogComponent.h:132
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCAssert(component, x)
Definition: LogComponent.h:169
#define yCTrace(component,...)
Definition: LogComponent.h:85
#define yCDebug(component,...)
Definition: LogComponent.h:109
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:35
std::string to_string(IntegerType x)
Definition: numeric.h:115
ContainerT split(const typename ContainerT::value_type &s, std::basic_regex< typename ContainerT::value_type::value_type > regex)
Utility to split a string by a separator, into a vector of strings.
Definition: string.h:27
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
Definition: ImageFile.cpp:922
#define YARP_VERSION
Definition: version.h:14
#define YARP_UNUSED(var)
Definition: api.h:162