YARP
Yet Another Robot Platform
XmlRpcStream.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include "XmlRpcStream.h"
10 #include "XmlRpcValue.h"
11 #include "XmlRpcLogComponent.h"
12 
13 #include <yarp/os/Bottle.h>
14 #include <yarp/os/Value.h>
15 
16 using namespace yarp::os;
17 using namespace std;
18 using YarpXmlRpc::XmlRpcValue;
19 
20 Value toValue(XmlRpcValue& v, bool outer)
21 {
22  int t = v.getType();
23  switch (t) {
24  case XmlRpcValue::TypeInt:
25  return Value((int)v);
26  break;
27  case XmlRpcValue::TypeDouble:
28  return Value((double)v);
29  break;
30  case XmlRpcValue::TypeString:
31  {
32  string s = (string)v;
33  if (s.length()==0 || s[0]!='[') {
34  return Value(s);
35  } else {
36  Value v;
37  v.fromString(s.c_str());
38  return v;
39  }
40  }
41  break;
42  case XmlRpcValue::TypeArray:
43  {
44  Value vbot;
45  Bottle *bot = vbot.asList();
46  for (int i=0; i<v.size(); i++) {
47  XmlRpcValue& v2 = v[i];
48  if (v2.getType()!=XmlRpcValue::TypeInvalid) {
49  Value v = toValue(v2,false);
50  if (i==0) {
51  std::string tag = v.asString();
52  if (tag=="list"||tag=="dict") {
53  if (!outer) {
54  bot->addString("list");
55  }
56  }
57  }
58  bot->add(v);
59  }
60  }
61  return vbot;
62  }
63  break;
64  case XmlRpcValue::TypeStruct:
65  {
66  Value vbot;
67  Bottle *bot = vbot.asList();
68  XmlRpcValue::ValueStruct& vals = v;
69  bot->addString("dict");
70  for (auto& val : vals) {
71  XmlRpcValue& v2 = val.second;
72  Bottle& sub = bot->addList();
73  sub.addString(val.first.c_str());
74  if (v2.getType()!=XmlRpcValue::TypeInvalid) {
75  sub.add(toValue(v2,false));
76  }
77  }
78  return vbot;
79  }
80  break;
81  case XmlRpcValue::TypeInvalid:
82  return Value::getNullValue();
83  break;
84  }
85  yCTrace(XMLRPCCARRIER, "Skipping %d", t);
86  return Value("(type not supported yet out of laziness)");
87 }
88 
90 {
91  yCTrace(XMLRPCCARRIER, "XMLRPC READ");
92  yarp::conf::ssize_t result = sis.read(b);
93  if (result>0) {
94  yCTrace(XMLRPCCARRIER, "RETURNING %zd bytes", result);
95  return result;
96  }
97  yCTrace(XMLRPCCARRIER, "No string");
98  if (result==0) {
99  yCTrace(XMLRPCCARRIER, "Reading...");
100  bool ok = false;
101  if (sender) {
102  client.reset();
103  } else {
104  server.reset();
105  }
106  if (firstRound) {
107  if (sender) {
108  client.read("POST /RP");
109  } else {
110  server.read("POST /RP");
111  }
112  firstRound = false;
113  }
114  char buf[1000];
115  Bytes bytes(buf,sizeof(buf));
116  while (!ok) {
117  int result2 = delegate->getInputStream().partialRead(bytes);
118  if (result2<=0) {
119  return result2;
120  }
121  string s(buf,result2);
122  yCTrace(XMLRPCCARRIER, "Giving %s to parser", s.c_str());
123  if (sender) {
124  ok = client.read(s);
125  } else {
126  ok = server.read(s);
127  }
128  if (ok) {
129  yCTrace(XMLRPCCARRIER, "got a block!");
130  XmlRpcValue xresult;
131  std::string prefix;
132  std::string cprefix;
133  if (sender) {
134  client.parseResponse(xresult);
135  } else {
136  cprefix = server.parseRequest(xresult);
137  bool isAdmin = false;
138  if (interpretRos) {
139  if (cprefix=="publisherUpdate") {
140  isAdmin = true;
141  }
142  if (cprefix=="requestTopic") {
143  isAdmin = true;
144  }
145  if (cprefix=="getPid") {
146  isAdmin = true;
147  }
148  if (cprefix=="getBusInfo") {
149  isAdmin = true;
150  }
151  }
152  prefix = isAdmin?"a\n":"d\n";
153  prefix += cprefix;
154  prefix += " ";
155  }
156  yCTrace(XMLRPCCARRIER, "xmlrpc block is %s", xresult.toXml().c_str());
157  Value v = toValue(xresult,true);
158  if (!v.isNull()) {
159  sis.reset(prefix + v.toString() + "\n");
160  } else {
161  sis.reset(prefix + "\n");
162  }
163  yCTrace(XMLRPCCARRIER, "String version is %s", sis.toString().c_str());
164  result = sis.read(b);
165  break;
166  }
167  }
168  }
169  yCTrace(XMLRPCCARRIER, "RETURNING %zd bytes", result);
170  return (result>0)?result:-1;
171 }
172 
173 
175 {
176  delegate->getOutputStream().write(b);
177 }
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::os::Value::getNullValue
static Value & getNullValue()
Return an invalid, "null" Value.
Definition: Value.cpp:475
toValue
Value toValue(XmlRpcValue &v, bool outer)
Definition: XmlRpcStream.cpp:20
t
float t
Definition: FfmpegWriter.cpp:74
XmlRpcStream::write
void write(const yarp::os::Bytes &b) override
Write a block of bytes to the stream.
Definition: XmlRpcStream.cpp:174
XmlRpcStream.h
yarp::os::Bottle::addList
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:185
XMLRPCCARRIER
const yarp::os::LogComponent & XMLRPCCARRIER()
Definition: XmlRpcLogComponent.cpp:16
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
yarp::conf::ssize_t
::ssize_t ssize_t
Definition: numeric.h:60
yarp::os::Value::isNull
bool isNull() const override
Checks if the object is invalid.
Definition: Value.cpp:383
yarp::os::Bottle::addString
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
yarp::os::Bytes
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
XmlRpcLogComponent.h
yarp::os::InputStream::read
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:23
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::os::Value::fromString
void fromString(const char *str)
Set value to correspond to a textual representation.
Definition: Value.cpp:354
yarp::os::Value::asList
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
yarp::os::Bottle::add
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition: Bottle.cpp:339
yCTrace
#define yCTrace(component,...)
Definition: LogComponent.h:88
yarp::os::Value::toString
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:47
Bottle.h
Value.h