Support std::move for parameters; fix result name issue.

This commit is contained in:
Adam Gu
2018-01-16 16:38:07 +08:00
parent f43b1d0c36
commit 2793357da3
16 changed files with 188 additions and 113 deletions
+17
View File
@@ -63,6 +63,10 @@ const Namespace kSoapEnvNamespace{
////////////////////////////////////////////////////////////////////////////////
Parameter::Parameter(const std::string& key, const char* value)
: key_(key), value_(value) {
}
Parameter::Parameter(const std::string& key, const std::string& value)
: key_(key), value_(value) {
}
@@ -84,4 +88,17 @@ Parameter::Parameter(const std::string& key, bool value)
value_ = value ? "true" : "false";
}
Parameter::Parameter(Parameter&& rhs)
: key_(std::move(rhs.key_))
, value_(std::move(rhs.value_)) {
}
Parameter& Parameter::operator=(Parameter&& rhs) {
if (this != &rhs) {
key_ = std::move(rhs.key_);
value_ = std::move(rhs.value_);
}
return *this;
}
} // namespace csoap
+14
View File
@@ -84,11 +84,17 @@ extern const Namespace kSoapEnvNamespace;
// Parameter in the SOAP request envelope.
class Parameter {
public:
Parameter(const std::string& key, const char* value);
Parameter(const std::string& key, const std::string& value);
Parameter(const std::string& key, int value);
Parameter(const std::string& key, double value);
Parameter(const std::string& key, bool value);
// Move constructor.
Parameter(Parameter&& rhs);
Parameter& operator=(Parameter&& rhs);
const std::string& key() const {
return key_;
}
@@ -97,6 +103,14 @@ public:
return value_;
}
const char* c_key() const {
return key_.c_str();
}
const char* c_value() const {
return value_.c_str();
}
private:
std::string key_;
std::string value_;
-4
View File
@@ -17,10 +17,6 @@
#include "csoap/http_request.h"
#include "csoap/http_response.h"
#if CSOAP_ENABLE_OUTPUT
#include "csoap/xml.h" // For pretty print response XML.
#endif
namespace csoap {
////////////////////////////////////////////////////////////////////////////////
-4
View File
@@ -5,8 +5,6 @@
namespace csoap {
////////////////////////////////////////////////////////////////////////////////
std::ostream& operator<<(std::ostream& os, const HttpResponse& response) {
os << response.start_line();
@@ -24,8 +22,6 @@ std::ostream& operator<<(std::ostream& os, const HttpResponse& response) {
return os;
}
////////////////////////////////////////////////////////////////////////////////
namespace status_strings {
const std::string OK = "HTTP/1.1 200 OK\r\n";
-4
View File
@@ -7,14 +7,10 @@
namespace csoap {
////////////////////////////////////////////////////////////////////////////////
class HttpResponse;
std::ostream& operator<<(std::ostream& os, const HttpResponse& response);
////////////////////////////////////////////////////////////////////////////////
class HttpResponse : public HttpMessage {
friend std::ostream& operator<<(std::ostream& os,
const HttpResponse& response);
+12 -10
View File
@@ -11,23 +11,25 @@
namespace csoap {
Error SoapClient::Call(const std::string& operation,
const Parameter* parameters,
std::size_t count,
std::vector<Parameter>&& parameters,
std::string* result) {
assert(!url_.empty() &&
!host_.empty() &&
!result_name_.empty() &&
service_ns_.IsValid());
assert(service_ns_.IsValid());
assert(!url_.empty() && !host_.empty());
assert(!result_name_.empty());
if (!soapenv_ns_.IsValid()) {
soapenv_ns_ = kSoapEnvNamespace;
}
SoapRequest soap_request;
soap_request.set_soapenv_ns(kSoapEnvNamespace); // TODO: Configurable
soap_request.set_soapenv_ns(soapenv_ns_);
soap_request.set_service_ns(service_ns_);
soap_request.set_operation(operation);
for (std::size_t i = 0; i < count; ++i) {
soap_request.AddParameter(parameters[i]);
for (Parameter& p : parameters) {
soap_request.AddParameter(std::move(p));
}
std::string http_content;
@@ -55,7 +57,7 @@ Error SoapClient::Call(const std::string& operation,
soap_response.set_result_name(result_name_);
if (!soap_response.FromXml(http_response.content())) {
return kXmlError; // TODO: Some SOAP error?
return kXmlError;
}
*result = soap_response.result();
+6 -5
View File
@@ -2,6 +2,7 @@
#define CSOAP_SOAP_CLIENT_H_
#include <string>
#include <vector>
#include "csoap/common.h"
namespace csoap {
@@ -19,12 +20,15 @@ protected:
}
// A generic wrapper to make a call.
// NOTE: The parameters should be movable.
Error Call(const std::string& operation,
const Parameter* parameters,
std::size_t count,
std::vector<Parameter>&& parameters,
std::string* result);
protected:
Namespace soapenv_ns_; // SOAP envelope namespace.
Namespace service_ns_; // Namespace for your web service.
// Request URL.
// Could be a complete URL (http://ws1.parasoft.com/glue/calculator)
// or just the path component of it (/glue/calculator).
@@ -33,9 +37,6 @@ protected:
std::string host_;
std::string port_; // Leave this empty to use default 80.
// The namespace of your service.
csoap::Namespace service_ns_;
// Response result XML node name.
// E.g., "Result".
std::string result_name_;
+4 -44
View File
@@ -3,15 +3,14 @@
namespace csoap {
void SoapRequest::AddParameter(const std::string& key,
const std::string& value) {
parameters_.push_back(Parameter(key, value));
}
void SoapRequest::AddParameter(const Parameter& parameter) {
parameters_.push_back(parameter);
}
void SoapRequest::AddParameter(Parameter&& parameter) {
parameters_.push_back(std::move(parameter));
}
std::string SoapRequest::GetParameter(const std::string& key) const {
for (const Parameter& p : parameters_) {
if (p.key() == key) {
@@ -21,45 +20,6 @@ std::string SoapRequest::GetParameter(const std::string& key) const {
return "";
}
//bool SoapRequest::FromXml(const std::string& xml_string) {
// pugi::xml_document xdoc;
// pugi::xml_parse_result result = xdoc.load_string(xml_string.c_str());
//
// if (!result) {
// return false;
// }
//
// pugi::xml_node xroot = xdoc.document_element();
//
// soapenv_ns_.name = xml::GetPrefix(xroot);
// soapenv_ns_.url = xml::GetNSAttr(xroot, soapenv_ns_.name);
//
// pugi::xml_node xbody = xml::GetChild(xroot, soapenv_ns_.name, "Body");
// if (!xbody) {
// return false;
// }
//
// // Operation
//
// pugi::xml_node xoperation = xbody.first_child();
// xml::SplitName(xoperation, &service_ns_.name, &operation_);
// service_ns_.url = xml::GetNSAttr(xoperation, service_ns_.name);
//
// // Parameters
//
// pugi::xml_node xparameter = xoperation.first_child();
// while (xparameter) {
// parameters_.push_back({
// xml::GetNameNoPrefix(xparameter),
// std::string(xparameter.text().as_string())
// });
//
// xparameter = xparameter.next_sibling();
// }
//
// return true;
//}
void SoapRequest::ToXmlBody(pugi::xml_node xbody) {
pugi::xml_node xop = xml::AddChild(xbody, service_ns_.name, operation_);
xml::AddNSAttr(xop, service_ns_.name, service_ns_.url);
+2 -1
View File
@@ -11,9 +11,10 @@ namespace csoap {
// request body.
class SoapRequest : public SoapMessage {
public:
void AddParameter(const std::string& key, const std::string& value);
void AddParameter(const Parameter& parameter);
void AddParameter(Parameter&& parameter);
// Get parameter value by key.
std::string GetParameter(const std::string& key) const;
+1 -2
View File
@@ -10,8 +10,7 @@ void SoapResponse::ToXmlBody(pugi::xml_node xbody) {
pugi::xml_node xop = xml::AddChild(xbody, service_ns_.name, rsp_operation);
xml::AddNSAttr(xop, service_ns_.name, service_ns_.url);
// TODO: Leave the user to decide the result name.
pugi::xml_node xresult = xml::AddChild(xop, service_ns_.name, "Result");
pugi::xml_node xresult = xml::AddChild(xop, service_ns_.name, result_name_);
xresult.text().set(result_.c_str());
}
@@ -30,8 +30,8 @@ void CalculatorClient::Init() {
#if ACCESS_PARASOFT
url_ = "/glue/calculator";
host_ = "ws1.parasoft.com";
port_ = "80"; // Or leave it empty because 80 is the default HTTP port.
service_ns_ = { "ser", "http://www.parasoft.com/wsdl/calculator/" };
port_ = ""; // Default to "80".
service_ns_ = { "cal", "http://www.parasoft.com/wsdl/calculator/" };
result_name_ = "Result";
#else
url_ = "/";
@@ -48,20 +48,24 @@ bool CalculatorClient::Calc(const std::string& operation,
double x,
double y,
double* result) {
csoap::Parameter parameters[] = {
// Prepare parameters.
std::vector<csoap::Parameter> parameters{
{ x_name, x },
{ y_name, y }
};
// Make the call.
std::string result_str;
csoap::Error error = Call(operation, parameters, 2, &result_str);
csoap::Error error = Call(operation, std::move(parameters), &result_str);
// Error handling if any.
if (error != csoap::kNoError) {
std::cerr << "Error: " << error;
std::cerr << ", " << csoap::GetErrorMessage(error) << std::endl;
return false;
}
// Convert the result from string to double.
try {
*result = boost::lexical_cast<double>(result_str);
} catch (boost::bad_lexical_cast&) {
@@ -8,20 +8,20 @@
CalculatorService::CalculatorService() {
}
bool CalculatorService::Handle(const csoap::SoapRequest& request,
csoap::SoapResponse* response) {
bool CalculatorService::Handle(const csoap::SoapRequest& soap_request,
csoap::SoapResponse* soap_response) {
try {
if (request.operation() == "add") {
double x = boost::lexical_cast<double>(request.GetParameter("x"));
double y = boost::lexical_cast<double>(request.GetParameter("y"));
if (soap_request.operation() == "add") {
double x = boost::lexical_cast<double>(soap_request.GetParameter("x"));
double y = boost::lexical_cast<double>(soap_request.GetParameter("y"));
double result = x + y;
response->set_soapenv_ns(csoap::kSoapEnvNamespace);
response->set_service_ns({ "ser", "http://mycalculator/" });
response->set_operation(request.operation());
response->set_result_name("Result");
response->set_result(boost::lexical_cast<std::string>(result));
soap_response->set_soapenv_ns(csoap::kSoapEnvNamespace);
soap_response->set_service_ns({ "cal", "http://mycalculator/" });
soap_response->set_operation(soap_request.operation());
soap_response->set_result_name("Result");
soap_response->set_result(boost::lexical_cast<std::string>(result));
return true;
@@ -7,10 +7,8 @@ class CalculatorService : public csoap::SoapService {
public:
CalculatorService();
bool Handle(const csoap::SoapRequest& request,
csoap::SoapResponse* response) override;
protected:
bool Handle(const csoap::SoapRequest& soap_request,
csoap::SoapResponse* soap_response) override;
};
#endif // CALCULATOR_SERVICE_H_
+8 -10
View File
@@ -22,18 +22,18 @@ void CsdmClient::Init() {
bool CsdmClient::Call0(const std::string& operation,
std::string* result_xml) {
return CallEx(operation, NULL, 0, result_xml);
std::vector<csoap::Parameter> parameters;
return CallEx(operation, std::move(parameters), result_xml);
}
bool CsdmClient::Call1(const std::string& operation,
const std::string& name,
const std::string& value,
std::string* result_xml) {
csoap::Parameter parameters[] = {
std::vector<csoap::Parameter> parameters{
{ name, value },
};
return CallEx(operation, parameters, 1, result_xml);
return CallEx(operation, std::move(parameters), result_xml);
}
bool CsdmClient::Call2(const std::string& operation,
@@ -42,18 +42,16 @@ bool CsdmClient::Call2(const std::string& operation,
const std::string& name2,
const std::string& value2,
std::string* result_xml) {
csoap::Parameter parameters[] = {
std::vector<csoap::Parameter> parameters{
{ name1, value1 },
{ name2, value2 },
};
return CallEx(operation, parameters, 2, result_xml);
return CallEx(operation, std::move(parameters), result_xml);
}
bool CsdmClient::CallEx(const std::string& operation,
const csoap::Parameter* parameters,
std::size_t count,
std::vector<csoap::Parameter>&& parameters,
std::string* result) {
csoap::Error error = Call(operation, parameters, count, result);
csoap::Error error = Call(operation, std::move(parameters), result);
return error == csoap::kNoError;
}
+1 -2
View File
@@ -35,8 +35,7 @@ protected:
// A wrapper of CSoapClient::Call().
bool CallEx(const std::string& operation,
const csoap::Parameter* parameters,
std::size_t count,
std::vector<csoap::Parameter>&& parameters,
std::string* result);
};