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