hiep sua file

This commit is contained in:
HiepLM 2025-12-29 17:43:35 +07:00
parent d8b17df593
commit 5bdd606fff
30 changed files with 1981 additions and 987 deletions

View File

@ -32,6 +32,7 @@
#include "XmlRpcValue.h" #include "XmlRpcValue.h"
#include "XmlRpcUtil.h" #include "XmlRpcUtil.h"
namespace robot {
namespace XmlRpc { namespace XmlRpc {
@ -90,5 +91,6 @@ namespace XmlRpc {
extern const char XMLRPC_VERSION[]; extern const char XMLRPC_VERSION[];
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPC_H_ #endif // _XMLRPC_H_

View File

@ -16,6 +16,7 @@
#include "xmlrpcpp/XmlRpcDispatch.h" #include "xmlrpcpp/XmlRpcDispatch.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "xmlrpcpp/XmlRpcSource.h"
namespace robot {
namespace XmlRpc { namespace XmlRpc {
// Arguments and results are represented by XmlRpcValues // Arguments and results are represented by XmlRpcValues
@ -124,5 +125,6 @@ namespace XmlRpc {
}; // class XmlRpcClient }; // class XmlRpcClient
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPCCLIENT_H_ #endif // _XMLRPCCLIENT_H_

View File

@ -12,6 +12,7 @@
# include <list> # include <list>
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
// An RPC source represents a file descriptor to monitor // An RPC source represents a file descriptor to monitor
@ -84,5 +85,6 @@ namespace XmlRpc {
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPCDISPATCH_H_ #endif // _XMLRPCDISPATCH_H_

View File

@ -13,6 +13,7 @@
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
//! A class representing an error. //! A class representing an error.
@ -37,6 +38,7 @@ namespace XmlRpc {
int _code; int _code;
}; };
} } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPCEXCEPTION_H_ #endif // _XMLRPCEXCEPTION_H_

View File

@ -16,6 +16,7 @@
#include "xmlrpcpp/XmlRpcDispatch.h" #include "xmlrpcpp/XmlRpcDispatch.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "xmlrpcpp/XmlRpcSource.h"
namespace robot {
namespace XmlRpc { namespace XmlRpc {
@ -100,5 +101,6 @@ namespace XmlRpc {
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif //_XMLRPCSERVER_H_ #endif //_XMLRPCSERVER_H_

View File

@ -14,6 +14,7 @@
#include "xmlrpcpp/XmlRpcValue.h" #include "xmlrpcpp/XmlRpcValue.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "xmlrpcpp/XmlRpcSource.h"
namespace robot {
namespace XmlRpc { namespace XmlRpc {
@ -98,5 +99,6 @@ namespace XmlRpc {
bool _keepAlive; bool _keepAlive;
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPCSERVERCONNECTION_H_ #endif // _XMLRPCSERVERCONNECTION_H_

View File

@ -12,6 +12,7 @@
# include <string> # include <string>
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
// Representation of a parameter or result value // Representation of a parameter or result value
@ -43,5 +44,6 @@ namespace XmlRpc {
XmlRpcServer* _server; XmlRpcServer* _server;
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPCSERVERMETHOD_H_ #endif // _XMLRPCSERVERMETHOD_H_

View File

@ -11,6 +11,7 @@
# include <string> # include <string>
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
//! A platform-independent socket API. //! A platform-independent socket API.
@ -65,5 +66,6 @@ namespace XmlRpc {
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif #endif

View File

@ -8,6 +8,7 @@
# pragma warning(disable:4786) // identifier was truncated in debug info # pragma warning(disable:4786) // identifier was truncated in debug info
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
//! An RPC source represents a file descriptor to monitor //! An RPC source represents a file descriptor to monitor
@ -51,5 +52,6 @@ namespace XmlRpc {
bool _keepOpen; bool _keepOpen;
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif //_XMLRPCSOURCE_H_ #endif //_XMLRPCSOURCE_H_

View File

@ -21,6 +21,7 @@
# define strncasecmp strnicmp # define strncasecmp strnicmp
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
//! Utilities for XML parsing, encoding, and decoding and message handlers. //! Utilities for XML parsing, encoding, and decoding and message handlers.
@ -57,5 +58,6 @@ namespace XmlRpc {
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
#endif // _XMLRPCUTIL_H_ #endif // _XMLRPCUTIL_H_

View File

@ -15,6 +15,7 @@
# include <time.h> # include <time.h>
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
//! RPC method arguments and results are represented by Values //! RPC method arguments and results are represented by Values
@ -181,9 +182,10 @@ namespace XmlRpc {
}; };
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
std::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v); std::ostream& operator<<(std::ostream& os, robot::XmlRpc::XmlRpcValue& v);
#endif // _XMLRPCVALUE_H_ #endif // _XMLRPCVALUE_H_

View File

@ -50,8 +50,7 @@ public:
// base64 requires max line length <= 72 characters // base64 requires max line length <= 72 characters
// you can fill end of line // you can fill end of line
// it may be crlf, crlfsp, noline or other class like it // it may be crlf, crlfsp, noline or other class like it
struct crlf struct crlf
{ {
template<class _OI> template<class _OI>
@ -161,7 +160,7 @@ public:
{ {
_3to4.zero(); _3to4.zero();
// берём по 3 символа // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> 3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_3to4.set_0(*_First); _3to4.set_0(*_First);
_First++; _First++;
@ -194,7 +193,7 @@ public:
*_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To; *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To;
*_To = _Tr::to_char_type(_base64Chars[_3to4.b64_3()]); ++_To; *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_3()]); ++_To;
if(line_octets == 17) // base64 позволяет длину строки не более 72 символов if(line_octets == 17) // base64 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> 72 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{ {
//_To = _Endl(_To); //_To = _Endl(_To);
*_To = '\n'; ++_To; *_To = '\n'; ++_To;

View File

@ -11,7 +11,7 @@
using namespace XmlRpc; using namespace robot::XmlRpc;
// Static data // Static data
const char XmlRpcClient::REQUEST_BEGIN[] = const char XmlRpcClient::REQUEST_BEGIN[] =

View File

@ -19,7 +19,7 @@
#endif // _WINDOWS #endif // _WINDOWS
using namespace XmlRpc; using namespace robot::XmlRpc;
XmlRpcDispatch::XmlRpcDispatch() XmlRpcDispatch::XmlRpcDispatch()

View File

@ -7,7 +7,7 @@
#include "xmlrpcpp/XmlRpcException.h" #include "xmlrpcpp/XmlRpcException.h"
using namespace XmlRpc; using namespace robot::XmlRpc;
XmlRpcServer::XmlRpcServer() XmlRpcServer::XmlRpcServer()

View File

@ -11,7 +11,7 @@
#endif #endif
using namespace XmlRpc; using namespace robot::XmlRpc;
// Static data // Static data
const char XmlRpcServerConnection::METHODNAME_TAG[] = "<methodName>"; const char XmlRpcServerConnection::METHODNAME_TAG[] = "<methodName>";

View File

@ -2,6 +2,7 @@
#include "xmlrpcpp/XmlRpcServerMethod.h" #include "xmlrpcpp/XmlRpcServerMethod.h"
#include "xmlrpcpp/XmlRpcServer.h" #include "xmlrpcpp/XmlRpcServer.h"
namespace robot {
namespace XmlRpc { namespace XmlRpc {
@ -19,3 +20,4 @@ namespace XmlRpc {
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot

View File

@ -30,7 +30,7 @@ extern "C" {
#endif // MAKEDEPEND #endif // MAKEDEPEND
using namespace XmlRpc; using namespace robot::XmlRpc;

View File

@ -3,6 +3,7 @@
#include "xmlrpcpp/XmlRpcSocket.h" #include "xmlrpcpp/XmlRpcSocket.h"
#include "xmlrpcpp/XmlRpcUtil.h" #include "xmlrpcpp/XmlRpcUtil.h"
namespace robot {
namespace XmlRpc { namespace XmlRpc {
@ -33,3 +34,4 @@ namespace XmlRpc {
} }
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot

View File

@ -11,7 +11,7 @@
#include "xmlrpcpp/XmlRpc.h" #include "xmlrpcpp/XmlRpc.h"
using namespace XmlRpc; using namespace robot::XmlRpc;
//#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output //#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output
@ -21,7 +21,7 @@ using namespace XmlRpc;
#endif #endif
// Version id // Version id
const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7"; const char robot::XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7";
// Default log verbosity: 0 for no messages through 5 (writes everything) // Default log verbosity: 0 for no messages through 5 (writes everything)
int XmlRpcLogHandler::_verbosity = 0; int XmlRpcLogHandler::_verbosity = 0;
@ -63,8 +63,8 @@ XmlRpcErrorHandler* XmlRpcErrorHandler::_errorHandler = &defaultErrorHandler;
// Easy API for log verbosity // Easy API for log verbosity
int XmlRpc::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); } int robot::XmlRpc::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); }
void XmlRpc::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); } void robot::XmlRpc::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); }

View File

@ -11,6 +11,7 @@
# include <stdio.h> # include <stdio.h>
#endif #endif
namespace robot {
namespace XmlRpc { namespace XmlRpc {
@ -598,10 +599,11 @@ namespace XmlRpc {
} }
} // namespace XmlRpc } // namespace XmlRpc
} // namespace robot
// ostream // ostream
std::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v) std::ostream& operator<<(std::ostream& os, robot::XmlRpc::XmlRpcValue& v)
{ {
// If you want to output in xml format: // If you want to output in xml format:
//return os << v.toXml(); //return os << v.toXml();

View File

@ -1,108 +1,216 @@
// FileClient.cpp : A simple xmlrpc client. Usage: FileClient serverHost serverPort xmlfile // FileClient.cpp : A simple xmlrpc client. Usage: FileClient serverHost serverPort xmlfile
// Reads an xmlrpc request from the specified xmlfile and calls the method on the server.
// // Reads an xmlrpc request from the specified xmlfile and calls the method on the server.
// Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows)
//
#include "XmlRpc.h"
#include <iostream> // Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows)
#include <fstream>
#include <stdlib.h>
using namespace XmlRpc; #include "XmlRpc.h"
std::string parseRequest(std::string const& xml, XmlRpcValue& params); #include <iostream>
#include <fstream>
int main(int argc, char* argv[])
{ #include <stdlib.h>
if (argc != 4) {
std::cerr << "Usage: FileClient serverHost serverPort requestXmlFile\n";
return -1;
} using namespace robot::XmlRpc;
int port = atoi(argv[2]);
XmlRpc::setVerbosity(5);
XmlRpcClient c(argv[1], port); std::string parseRequest(std::string const& xml, XmlRpcValue& params);
//
std::ifstream infile(argv[3]);
if (infile.fail()) {
std::cerr << "Could not open file '" << argv[3] << "'.\n";
return -1; int main(int argc, char* argv[])
}
{
// Suck in the file. This is a one-liner in good compilers (which vc++ 6 is not)...
infile.seekg(0L, std::ios::end); if (argc != 4) {
long nb = infile.tellg();
infile.clear(); std::cerr << "Usage: FileClient serverHost serverPort requestXmlFile\n";
infile.seekg(0L);
char* b = new char[nb+1]; return -1;
infile.read(b, nb);
b[nb] = 0; }
std::cout << "Read file.\n"; int port = atoi(argv[2]);
// Find the methodName and parse the params
std::string s(b);
XmlRpcValue params; robot::XmlRpc::setVerbosity(5);
std::string name = parseRequest(s, params);
XmlRpcClient c(argv[1], port);
if (name.empty()) {
std::cerr << "Could not parse file\n";
return -1;
} //
for (;;) { std::ifstream infile(argv[3]);
XmlRpcValue result;
std::cout << "Calling " << name << std::endl; if (infile.fail()) {
if (c.execute(name.c_str(), params, result))
std::cout << result << "\n\n"; std::cerr << "Could not open file '" << argv[3] << "'.\n";
else
std::cout << "Error calling '" << name << "'\n\n"; return -1;
std::cout << "Again? [y]: ";
std::string ans; }
std::cin >> ans;
if (ans != "" && ans != "y") break;
}
// Suck in the file. This is a one-liner in good compilers (which vc++ 6 is not)...
return 0;
} infile.seekg(0L, std::ios::end);
long nb = infile.tellg();
//
std::string infile.clear();
parseRequest(std::string const& xml, XmlRpcValue& params)
{ infile.seekg(0L);
const char METHODNAME_TAG[] = "<methodName>";
const char PARAMS_TAG[] = "<params>"; char* b = new char[nb+1];
const char PARAMS_ETAG[] = "</params>";
const char PARAM_TAG[] = "<param>"; infile.read(b, nb);
const char PARAM_ETAG[] = "</param>";
b[nb] = 0;
int offset = 0; // Number of chars parsed from the request
std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, xml, &offset);
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed methodName %s.", methodName.c_str()); std::cout << "Read file.\n";
if (! methodName.empty() && XmlRpcUtil::findTag(PARAMS_TAG, xml, &offset))
{
int nArgs = 0; // Find the methodName and parse the params
while (XmlRpcUtil::nextTagIs(PARAM_TAG, xml, &offset)) {
std::cout << "Parsing arg " << nArgs+1 << std::endl; std::string s(b);
XmlRpcValue arg(xml, &offset);
if ( ! arg.valid()) { XmlRpcValue params;
std::cerr << "Invalid argument\n";
return std::string(); std::string name = parseRequest(s, params);
}
std::cout << "Adding arg " << nArgs+1 << " to params array." << std::endl;
params[nArgs++] = arg;
(void) XmlRpcUtil::nextTagIs(PARAM_ETAG, xml, &offset); if (name.empty()) {
}
std::cerr << "Could not parse file\n";
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed %d params.", nArgs);
return -1;
(void) XmlRpcUtil::nextTagIs(PARAMS_ETAG, xml, &offset);
} }
return methodName;
}
for (;;) {
XmlRpcValue result;
std::cout << "Calling " << name << std::endl;
if (c.execute(name.c_str(), params, result))
std::cout << result << "\n\n";
else
std::cout << "Error calling '" << name << "'\n\n";
std::cout << "Again? [y]: ";
std::string ans;
std::cin >> ans;
if (ans != "" && ans != "y") break;
}
return 0;
}
//
std::string
parseRequest(std::string const& xml, XmlRpcValue& params)
{
const char METHODNAME_TAG[] = "<methodName>";
const char PARAMS_TAG[] = "<params>";
const char PARAMS_ETAG[] = "</params>";
const char PARAM_TAG[] = "<param>";
const char PARAM_ETAG[] = "</param>";
int offset = 0; // Number of chars parsed from the request
std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, xml, &offset);
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed methodName %s.", methodName.c_str());
if (! methodName.empty() && XmlRpcUtil::findTag(PARAMS_TAG, xml, &offset))
{
int nArgs = 0;
while (XmlRpcUtil::nextTagIs(PARAM_TAG, xml, &offset)) {
std::cout << "Parsing arg " << nArgs+1 << std::endl;
XmlRpcValue arg(xml, &offset);
if ( ! arg.valid()) {
std::cerr << "Invalid argument\n";
return std::string();
}
std::cout << "Adding arg " << nArgs+1 << " to params array." << std::endl;
params[nArgs++] = arg;
(void) XmlRpcUtil::nextTagIs(PARAM_ETAG, xml, &offset);
}
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed %d params.", nArgs);
(void) XmlRpcUtil::nextTagIs(PARAMS_ETAG, xml, &offset);
}
return methodName;
}

View File

@ -3,7 +3,7 @@
// on windows) // on windows)
#include "XmlRpc.h" #include "XmlRpc.h"
#include <iostream> #include <iostream>
using namespace XmlRpc; using namespace robot::XmlRpc;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@ -12,7 +12,7 @@ int main(int argc, char* argv[])
return -1; return -1;
} }
int port = atoi(argv[2]); int port = atoi(argv[2]);
//XmlRpc::setVerbosity(5); //robot::XmlRpc::setVerbosity(5);
// Use introspection API to look up the supported methods // Use introspection API to look up the supported methods
XmlRpcClient c(argv[1], port); XmlRpcClient c(argv[1], port);

View File

@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
#include <stdlib.h> #include <stdlib.h>
using namespace XmlRpc; using namespace robot::XmlRpc;
// The server // The server
XmlRpcServer s; XmlRpcServer s;
@ -66,7 +66,7 @@ int main(int argc, char* argv[])
} }
int port = atoi(argv[1]); int port = atoi(argv[1]);
XmlRpc::setVerbosity(5); robot::XmlRpc::setVerbosity(5);
// Create the server socket on the specified port // Create the server socket on the specified port
s.bindAndListen(port); s.bindAndListen(port);

View File

@ -1,45 +1,90 @@
// TestBase64Client.cpp : A simple xmlrpc client that returns a png file // TestBase64Client.cpp : A simple xmlrpc client that returns a png file
// encoded as base64 data to the client.
// // encoded as base64 data to the client.
// Usage: TestBase64Client serverHost serverPort outputfile
// Requests a png file from the specified server and saves it in outputfile. //
// Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows)
// Usage: TestBase64Client serverHost serverPort outputfile
#include "XmlRpc.h"
#include <iostream> // Requests a png file from the specified server and saves it in outputfile.
#include <fstream>
#include <stdlib.h> // Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows)
using namespace XmlRpc;
int main(int argc, char* argv[]) #include "XmlRpc.h"
{
if (argc != 4) { #include <iostream>
std::cerr << "Usage: TestBase64Client serverHost serverPort outputFile\n";
return -1; #include <fstream>
}
int port = atoi(argv[2]); #include <stdlib.h>
//XmlRpc::setVerbosity(5);
XmlRpcClient c(argv[1], port);
using namespace robot::XmlRpc;
XmlRpcValue noArgs, result;
if (c.execute("TestBase64", noArgs, result))
{
const XmlRpcValue::BinaryData& data = result; int main(int argc, char* argv[])
std::ofstream outfile(argv[3], std::ios::binary | std::ios::trunc);
if (outfile.fail()) {
std::cerr << "Error opening " << argv[3] << " for output.\n";
else if (argc != 4) {
{
int n = int(data.size()); std::cerr << "Usage: TestBase64Client serverHost serverPort outputFile\n";
for (int i=0; i<n; ++i)
outfile << data[i]; return -1;
}
} }
else
std::cout << "Error calling 'TestBase64'\n\n"; int port = atoi(argv[2]);
return 0;
}
//robot::XmlRpc::setVerbosity(5);
XmlRpcClient c(argv[1], port);
XmlRpcValue noArgs, result;
if (c.execute("TestBase64", noArgs, result))
{
const XmlRpcValue::BinaryData& data = result;
std::ofstream outfile(argv[3], std::ios::binary | std::ios::trunc);
if (outfile.fail())
std::cerr << "Error opening " << argv[3] << " for output.\n";
else
{
int n = int(data.size());
for (int i=0; i<n; ++i)
outfile << data[i];
}
}
else
std::cout << "Error calling 'TestBase64'\n\n";
return 0;
}

View File

@ -1,68 +1,136 @@
// TestBase64Server.cpp : Simple XMLRPC server example. Usage: TestBase64Server serverPort // TestBase64Server.cpp : Simple XMLRPC server example. Usage: TestBase64Server serverPort
//
#if defined(_MSC_VER) //
# pragma warning(disable:4786) // identifier was truncated in debug info
#endif #if defined(_MSC_VER)
# pragma warning(disable:4786) // identifier was truncated in debug info
#include <iostream>
#include <fstream> #endif
#include <algorithm>
#include <stdlib.h>
#include "XmlRpc.h"
using namespace XmlRpc; #include <iostream>
#include <fstream>
// The server
XmlRpcServer s; #include <algorithm>
// No arguments, result is Base64-encoded pngnow.png data. #include <stdlib.h>
class TestBase64 : public XmlRpcServerMethod
{
public:
TestBase64(XmlRpcServer* s) : XmlRpcServerMethod("TestBase64", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) #include "XmlRpc.h"
{
std::ifstream infile("pngnow.png", std::ios::binary); using namespace robot::XmlRpc;
if (infile.fail())
infile.open("../pngnow.png", std::ios::binary);
if (infile.fail())
result = "Could not open file pngnow.png";
else {
// The server
XmlRpcValue::BinaryData& data = result;
int n = 0; XmlRpcServer s;
for (;; ++n) {
char c = infile.get();
if (infile.eof()) break;
data.push_back(c); // No arguments, result is Base64-encoded pngnow.png data.
}
std::cerr << "Read " << n << " bytes from pngnow.png\n"; class TestBase64 : public XmlRpcServerMethod
}
} {
} TestBase64(&s); // This constructor registers the method with the server
public:
TestBase64(XmlRpcServer* s) : XmlRpcServerMethod("TestBase64", s) {}
int main(int argc, char* argv[])
{
if (argc != 2) {
std::cerr << "Usage: TestBase64Server serverPort\n"; void execute(XmlRpcValue& params, XmlRpcValue& result)
return -1;
} {
int port = atoi(argv[1]);
std::ifstream infile("pngnow.png", std::ios::binary);
//XmlRpc::setVerbosity(5);
if (infile.fail())
// Create the server socket on the specified port
s.bindAndListen(port); infile.open("../pngnow.png", std::ios::binary);
// Wait for requests indefinitely if (infile.fail())
s.work(-1.0);
result = "Could not open file pngnow.png";
return 0;
} else {
XmlRpcValue::BinaryData& data = result;
int n = 0;
for (;; ++n) {
char c = infile.get();
if (infile.eof()) break;
data.push_back(c);
}
std::cerr << "Read " << n << " bytes from pngnow.png\n";
}
}
} TestBase64(&s); // This constructor registers the method with the server
int main(int argc, char* argv[])
{
if (argc != 2) {
std::cerr << "Usage: TestBase64Server serverPort\n";
return -1;
}
int port = atoi(argv[1]);
//robot::XmlRpc::setVerbosity(5);
// Create the server socket on the specified port
s.bindAndListen(port);
// Wait for requests indefinitely
s.work(-1.0);
return 0;
}

View File

@ -1,233 +1,466 @@
// TestValues.cpp : Test XML encoding and decoding of XmlRpcValues. // TestValues.cpp : Test XML encoding and decoding of XmlRpcValues.
#include <stdlib.h>
#include "XmlRpcValue.h" #include <stdlib.h>
#include <assert.h>
#include <iostream> #include "XmlRpcValue.h"
using namespace XmlRpc;
void testBoolean() #include <assert.h>
{
XmlRpcValue booleanFalse(false); #include <iostream>
XmlRpcValue booleanTrue(true);
int offset = 0;
XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset);
offset = 0;
XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset);
assert(booleanFalse != booleanTrue); using namespace robot::XmlRpc;
assert(booleanFalse == booleanFalseXml);
assert(booleanFalse != booleanTrueXml);
if (bool(booleanFalse))
assert(false);
void testBoolean()
if ( ! bool(booleanTrue))
assert(false); {
}
XmlRpcValue booleanFalse(false);
// Int
void testInt() XmlRpcValue booleanTrue(true);
{
XmlRpcValue int0(0); int offset = 0;
XmlRpcValue int1(1);
XmlRpcValue int10(10); XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset);
XmlRpcValue int_1(-1);
int offset = 0; offset = 0;
XmlRpcValue int0Xml("<value><int>0</int></value>", &offset);
offset = 0; XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset);
XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset);
assert(int0 == int0Xml); assert(booleanFalse != booleanTrue);
assert(int(int10) - int(int1) == int(int9Xml));
assert(9 == int(int9Xml)); assert(booleanFalse == booleanFalseXml);
assert(int(int10) + int(int_1) == int(int9Xml));
} assert(booleanFalse != booleanTrueXml);
void testDouble()
{
// Double if (bool(booleanFalse))
XmlRpcValue d(43.7);
int offset = 0; assert(false);
XmlRpcValue dXml("<value><double>56.3</double></value>", &offset);
assert(double(d) + double(dXml) == 100.0); // questionable practice...
}
if ( ! bool(booleanTrue))
void testString()
{ assert(false);
// String
XmlRpcValue s("Now is the time <&"); }
char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>";
std::string ssxml = csxml;
int offset = 0;
XmlRpcValue vscXml(csxml, &offset); // Int
offset = 0;
XmlRpcValue vssXml(ssxml, &offset); void testInt()
assert(s == vscXml);
assert(s == vssXml); {
offset = 0;
XmlRpcValue fromXml(vssXml.toXml(), &offset); XmlRpcValue int0(0);
assert(s == fromXml);
XmlRpcValue int1(1);
// Empty or blank strings with no <string> tags
std::string emptyStringXml("<value></value>"); XmlRpcValue int10(10);
offset = 0;
XmlRpcValue emptyStringVal1(emptyStringXml, &offset); XmlRpcValue int_1(-1);
XmlRpcValue emptyStringVal2("");
assert(emptyStringVal1 == emptyStringVal2); int offset = 0;
emptyStringXml = "<value> </value>"; XmlRpcValue int0Xml("<value><int>0</int></value>", &offset);
offset = 0;
XmlRpcValue blankStringVal(emptyStringXml, &offset); offset = 0;
assert(std::string(blankStringVal) == " ");
} XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset);
assert(int0 == int0Xml);
void testDateTime()
{ assert(int(int10) - int(int1) == int(int9Xml));
// DateTime
int offset = 0; assert(9 == int(int9Xml));
XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
struct tm &t = dateTime; assert(int(int10) + int(int_1) == int(int9Xml));
assert(t.tm_year == 1904 && t.tm_min == 12);
} }
void testArray(XmlRpcValue const& d)
{ void testDouble()
// Array
XmlRpcValue a; {
a.setSize(4);
a[0] = 1; // Double
a[1] = std::string("two");
a[2] = 43.7; XmlRpcValue d(43.7);
a[3] = "four";
assert(int(a[0]) == 1); int offset = 0;
assert(a[2] == d);
XmlRpcValue dXml("<value><double>56.3</double></value>", &offset);
char csaXml[] =
"<value><array>\n" assert(double(d) + double(dXml) == 100.0); // questionable practice...
" <data>\n"
" <value><i4>1</i4></value> \n" }
" <value> <string>two</string></value>\n"
" <value><double>43.7</double></value>\n"
" <value>four</value>\n"
" </data>\n" void testString()
"</array></value>";
{
int offset = 0;
XmlRpcValue aXml(csaXml, &offset); // String
assert(a == aXml);
} XmlRpcValue s("Now is the time <&");
void testStruct() char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>";
{
// Struct std::string ssxml = csxml;
XmlRpcValue struct1;
struct1["i4"] = 1; int offset = 0;
struct1["str"] = "two";
struct1["d"] = 43.7; XmlRpcValue vscXml(csxml, &offset);
XmlRpcValue a; offset = 0;
a.setSize(4);
a[0] = 1; XmlRpcValue vssXml(ssxml, &offset);
a[1] = std::string("two");
a[2] = 43.7; assert(s == vscXml);
a[3] = "four";
assert(s == vssXml);
assert(struct1["d"] == a[2]);
offset = 0;
char csStructXml[] =
"<value><struct>\n" XmlRpcValue fromXml(vssXml.toXml(), &offset);
" <member>\n"
" <name>i4</name> \n" assert(s == fromXml);
" <value><i4>1</i4></value> \n"
" </member>\n"
" <member>\n"
" <name>d</name> \n" // Empty or blank strings with no <string> tags
" <value><double>43.7</double></value>\n"
" </member>\n" std::string emptyStringXml("<value></value>");
" <member>\n"
" <name>str</name> \n" offset = 0;
" <value> <string>two</string></value>\n"
" </member>\n" XmlRpcValue emptyStringVal1(emptyStringXml, &offset);
"</struct></value>";
XmlRpcValue emptyStringVal2("");
int offset = 0;
XmlRpcValue structXml(csStructXml, &offset); assert(emptyStringVal1 == emptyStringVal2);
assert(struct1 == structXml);
XmlRpcValue astruct;
astruct["array"] = a; emptyStringXml = "<value> </value>";
assert(astruct["array"][2] == struct1["d"]);
offset = 0;
for (int i=0; i<10; i++) {
XmlRpcValue Event; XmlRpcValue blankStringVal(emptyStringXml, &offset);
Event["Name"] = "string";
assert(std::string(blankStringVal) == " ");
Event.clear();
}
const int NELMTS = 100;
int ii;
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii); void testDateTime()
Event[std::string(buf)] = buf;
} {
Event.clear(); // DateTime
for (ii=0; ii< NELMTS; ++ii) { int offset = 0;
char buf[40];
sprintf(buf,"%d", ii); XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
if (ii != NELMTS/2)
Event[std::string(buf)] = ii; struct tm &t = dateTime;
else
for (int jj=0; jj< NELMTS; ++jj) { assert(t.tm_year == 1904 && t.tm_min == 12);
char bufj[40];
sprintf(bufj,"%d", jj); }
Event[std::string(buf)][std::string(bufj)] = bufj;
}
}
for (ii=0; ii< NELMTS; ++ii) {
char buf[40]; void testArray(XmlRpcValue const& d)
sprintf(buf,"%d", ii);
if (ii != NELMTS/2) {
assert(Event[std::string(buf)] == XmlRpcValue(ii));
else // Array
assert(Event[std::string(buf)].size() == NELMTS);
} XmlRpcValue a;
}
} a.setSize(4);
a[0] = 1;
int main(int argc, char* argv[]) a[1] = std::string("two");
{
testBoolean(); a[2] = 43.7;
testInt(); a[3] = "four";
assert(int(a[0]) == 1);
testDouble();
assert(a[2] == d);
testString();
char csaXml[] =
testDateTime();
"<value><array>\n"
testArray(43.7); " <data>\n"
" <value><i4>1</i4></value> \n"
testStruct();
" <value> <string>two</string></value>\n"
return 0;
} " <value><double>43.7</double></value>\n"
" <value>four</value>\n"
" </data>\n"
"</array></value>";
int offset = 0;
XmlRpcValue aXml(csaXml, &offset);
assert(a == aXml);
}
void testStruct()
{
// Struct
XmlRpcValue struct1;
struct1["i4"] = 1;
struct1["str"] = "two";
struct1["d"] = 43.7;
XmlRpcValue a;
a.setSize(4);
a[0] = 1;
a[1] = std::string("two");
a[2] = 43.7;
a[3] = "four";
assert(struct1["d"] == a[2]);
char csStructXml[] =
"<value><struct>\n"
" <member>\n"
" <name>i4</name> \n"
" <value><i4>1</i4></value> \n"
" </member>\n"
" <member>\n"
" <name>d</name> \n"
" <value><double>43.7</double></value>\n"
" </member>\n"
" <member>\n"
" <name>str</name> \n"
" <value> <string>two</string></value>\n"
" </member>\n"
"</struct></value>";
int offset = 0;
XmlRpcValue structXml(csStructXml, &offset);
assert(struct1 == structXml);
XmlRpcValue astruct;
astruct["array"] = a;
assert(astruct["array"][2] == struct1["d"]);
for (int i=0; i<10; i++) {
XmlRpcValue Event;
Event["Name"] = "string";
Event.clear();
const int NELMTS = 100;
int ii;
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
Event[std::string(buf)] = buf;
}
Event.clear();
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
Event[std::string(buf)] = ii;
else
for (int jj=0; jj< NELMTS; ++jj) {
char bufj[40];
sprintf(bufj,"%d", jj);
Event[std::string(buf)][std::string(bufj)] = bufj;
}
}
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
assert(Event[std::string(buf)] == XmlRpcValue(ii));
else
assert(Event[std::string(buf)].size() == NELMTS);
}
}
}
int main(int argc, char* argv[])
{
testBoolean();
testInt();
testDouble();
testString();
testDateTime();
testArray(43.7);
testStruct();
return 0;
}

View File

@ -1,253 +1,506 @@
// TestValues.cpp : Test XML encoding and decoding of XmlRpcValues. // TestValues.cpp : Test XML encoding and decoding of XmlRpcValues.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h> #define _CRTDBG_MAP_ALLOC
#include "XmlRpcValue.h" #include <stdlib.h>
#include <crtdbg.h>
#include <assert.h>
#include <iostream>
#include "XmlRpcValue.h"
using namespace XmlRpc;
void testBoolean()
{
XmlRpcValue booleanFalse(false); #include <assert.h>
XmlRpcValue booleanTrue(true);
int offset = 0; #include <iostream>
XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset);
offset = 0;
XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset);
assert(booleanFalse != booleanTrue);
assert(booleanFalse == booleanFalseXml);
assert(booleanFalse == booleanFalseXml); using namespace robot::XmlRpc;
if (booleanFalse)
assert(false);
if (booleanTrue)
assert( ! false);
else void testBoolean()
assert(false);
} {
// Int XmlRpcValue booleanFalse(false);
void testInt()
{ XmlRpcValue booleanTrue(true);
XmlRpcValue int0(0);
XmlRpcValue int1(1); int offset = 0;
XmlRpcValue int10(10);
XmlRpcValue int_1(-1); XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset);
int offset = 0;
XmlRpcValue int0Xml("<value><int>0</int></value>", &offset); offset = 0;
offset = 0;
XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset); XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset);
assert(int0 == int0Xml);
assert(int(int10) - int(int1) == int(int9Xml)); assert(booleanFalse != booleanTrue);
assert(9 == int(int9Xml));
assert(int(int10) + int(int_1) == int(int9Xml)); assert(booleanFalse == booleanFalseXml);
}
assert(booleanFalse == booleanFalseXml);
void testDouble()
{ if (booleanFalse)
// Double
XmlRpcValue d(43.7); assert(false);
int offset = 0;
XmlRpcValue dXml("<value><double>56.3</double></value>", &offset);
assert(double(d) + double(dXml) == 100.0); // questionable practice...
} if (booleanTrue)
void testString() assert( ! false);
{
// String else
XmlRpcValue s("Now is the time <&");
char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>"; assert(false);
std::string ssxml = csxml;
int offset = 0; }
XmlRpcValue vscXml(csxml, &offset);
offset = 0;
XmlRpcValue vssXml(ssxml, &offset);
assert(s == vscXml); // Int
assert(s == vssXml);
offset = 0; void testInt()
XmlRpcValue fromXml(vssXml.toXml(), &offset);
assert(s == fromXml); {
// Empty or blank strings with no <string> tags XmlRpcValue int0(0);
std::string emptyStringXml("<value></value>");
offset = 0; XmlRpcValue int1(1);
XmlRpcValue emptyStringVal1(emptyStringXml, &offset);
XmlRpcValue emptyStringVal2(""); XmlRpcValue int10(10);
assert(emptyStringVal1 == emptyStringVal2);
XmlRpcValue int_1(-1);
emptyStringXml = "<value> </value>";
offset = 0; int offset = 0;
XmlRpcValue blankStringVal(emptyStringXml, &offset);
assert(std::string(blankStringVal) == " "); XmlRpcValue int0Xml("<value><int>0</int></value>", &offset);
}
offset = 0;
void testDateTime() XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset);
{
// DateTime assert(int0 == int0Xml);
int offset = 0;
XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset); assert(int(int10) - int(int1) == int(int9Xml));
struct tm &t = dateTime;
assert(t.tm_year == 1904 && t.tm_min == 12); assert(9 == int(int9Xml));
}
assert(int(int10) + int(int_1) == int(int9Xml));
void testArray(XmlRpcValue const& d) }
{
// Array
XmlRpcValue a;
a.setSize(4); void testDouble()
a[0] = 1;
a[1] = std::string("two"); {
a[2] = 43.7;
a[3] = "four"; // Double
assert(int(a[0]) == 1);
assert(a[2] == d); XmlRpcValue d(43.7);
char csaXml[] = int offset = 0;
"<value><array>\n"
" <data>\n" XmlRpcValue dXml("<value><double>56.3</double></value>", &offset);
" <value><i4>1</i4></value> \n"
" <value> <string>two</string></value>\n" assert(double(d) + double(dXml) == 100.0); // questionable practice...
" <value><double>43.7</double></value>\n"
" <value>four</value>\n" }
" </data>\n"
"</array></value>";
int offset = 0; void testString()
XmlRpcValue aXml(csaXml, &offset);
assert(a == aXml); {
}
// String
void testStruct()
{ XmlRpcValue s("Now is the time <&");
// Struct
XmlRpcValue struct1; char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>";
struct1["i4"] = 1;
struct1["str"] = "two"; std::string ssxml = csxml;
struct1["d"] = 43.7;
int offset = 0;
XmlRpcValue a;
a.setSize(4); XmlRpcValue vscXml(csxml, &offset);
a[0] = 1;
a[1] = std::string("two"); offset = 0;
a[2] = 43.7;
a[3] = "four"; XmlRpcValue vssXml(ssxml, &offset);
assert(struct1["d"] == a[2]); assert(s == vscXml);
char csStructXml[] = assert(s == vssXml);
"<value><struct>\n"
" <member>\n" offset = 0;
" <name>i4</name> \n"
" <value><i4>1</i4></value> \n" XmlRpcValue fromXml(vssXml.toXml(), &offset);
" </member>\n"
" <member>\n" assert(s == fromXml);
" <name>d</name> \n"
" <value><double>43.7</double></value>\n"
" </member>\n"
" <member>\n" // Empty or blank strings with no <string> tags
" <name>str</name> \n"
" <value> <string>two</string></value>\n" std::string emptyStringXml("<value></value>");
" </member>\n"
"</struct></value>"; offset = 0;
int offset = 0; XmlRpcValue emptyStringVal1(emptyStringXml, &offset);
XmlRpcValue structXml(csStructXml, &offset);
assert(struct1 == structXml); XmlRpcValue emptyStringVal2("");
XmlRpcValue astruct; assert(emptyStringVal1 == emptyStringVal2);
astruct["array"] = a;
assert(astruct["array"][2] == struct1["d"]);
for (int i=0; i<10; i++) { emptyStringXml = "<value> </value>";
XmlRpcValue Event;
Event["Name"] = "string"; offset = 0;
Event.clear(); XmlRpcValue blankStringVal(emptyStringXml, &offset);
const int NELMTS = 100; assert(std::string(blankStringVal) == " ");
int ii;
}
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
Event[buf] = buf;
}
void testDateTime()
Event.clear();
{
for (ii=0; ii< NELMTS; ++ii) {
char buf[40]; // DateTime
sprintf(buf,"%d", ii);
if (ii != NELMTS/2) int offset = 0;
Event[buf] = ii;
else XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
for (int jj=0; jj< NELMTS; ++jj) {
char bufj[40]; struct tm &t = dateTime;
sprintf(bufj,"%d", jj);
Event[buf][bufj] = bufj; assert(t.tm_year == 1904 && t.tm_min == 12);
}
} }
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
assert(Event[buf] == XmlRpcValue(ii)); void testArray(XmlRpcValue const& d)
else
assert(Event[buf].size() == NELMTS); {
}
} // Array
}
XmlRpcValue a;
a.setSize(4);
int main(int argc, char* argv[])
{ a[0] = 1;
_CrtDumpMemoryLeaks();
_CrtCheckMemory( ); a[1] = std::string("two");
testBoolean(); a[2] = 43.7;
_CrtDumpMemoryLeaks();
_CrtCheckMemory( ); a[3] = "four";
testInt(); assert(int(a[0]) == 1);
_CrtDumpMemoryLeaks();
_CrtCheckMemory( ); assert(a[2] == d);
testDouble();
_CrtDumpMemoryLeaks(); char csaXml[] =
_CrtCheckMemory( );
"<value><array>\n"
testString(); " <data>\n"
_CrtDumpMemoryLeaks();
_CrtCheckMemory( ); " <value><i4>1</i4></value> \n"
" <value> <string>two</string></value>\n"
testDateTime();
_CrtDumpMemoryLeaks(); " <value><double>43.7</double></value>\n"
_CrtCheckMemory( );
" <value>four</value>\n"
testArray(43.7); " </data>\n"
_CrtDumpMemoryLeaks();
_CrtCheckMemory( ); "</array></value>";
testStruct();
_CrtDumpMemoryLeaks(); int offset = 0;
_CrtCheckMemory( );
XmlRpcValue aXml(csaXml, &offset);
return 0;
} assert(a == aXml);
}
void testStruct()
{
// Struct
XmlRpcValue struct1;
struct1["i4"] = 1;
struct1["str"] = "two";
struct1["d"] = 43.7;
XmlRpcValue a;
a.setSize(4);
a[0] = 1;
a[1] = std::string("two");
a[2] = 43.7;
a[3] = "four";
assert(struct1["d"] == a[2]);
char csStructXml[] =
"<value><struct>\n"
" <member>\n"
" <name>i4</name> \n"
" <value><i4>1</i4></value> \n"
" </member>\n"
" <member>\n"
" <name>d</name> \n"
" <value><double>43.7</double></value>\n"
" </member>\n"
" <member>\n"
" <name>str</name> \n"
" <value> <string>two</string></value>\n"
" </member>\n"
"</struct></value>";
int offset = 0;
XmlRpcValue structXml(csStructXml, &offset);
assert(struct1 == structXml);
XmlRpcValue astruct;
astruct["array"] = a;
assert(astruct["array"][2] == struct1["d"]);
for (int i=0; i<10; i++) {
XmlRpcValue Event;
Event["Name"] = "string";
Event.clear();
const int NELMTS = 100;
int ii;
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
Event[buf] = buf;
}
Event.clear();
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
Event[buf] = ii;
else
for (int jj=0; jj< NELMTS; ++jj) {
char bufj[40];
sprintf(bufj,"%d", jj);
Event[buf][bufj] = bufj;
}
}
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
assert(Event[buf] == XmlRpcValue(ii));
else
assert(Event[buf].size() == NELMTS);
}
}
}
int main(int argc, char* argv[])
{
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testBoolean();
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testInt();
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testDouble();
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testString();
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testDateTime();
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testArray(43.7);
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
testStruct();
_CrtDumpMemoryLeaks();
_CrtCheckMemory( );
return 0;
}

View File

@ -1,53 +1,106 @@
// TestXml.cpp : Test XML encoding and decoding. // TestXml.cpp : Test XML encoding and decoding.
// The characters <>&'" are illegal in xml and must be encoded.
// The characters <>&'" are illegal in xml and must be encoded.
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <iostream>
// If you are using MSVC++6, you should update <string> to fix
// BUG: getline Template Function Reads Extra Character #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <string>
#include <assert.h>
#include <stdlib.h>
#include <iostream>
#include "XmlRpcUtil.h"
// If you are using MSVC++6, you should update <string> to fix
using namespace XmlRpc;
// BUG: getline Template Function Reads Extra Character
int main(int argc, char* argv[]) #include <string>
{
// Basic tests #include <assert.h>
std::string empty;
assert(empty == XmlRpcUtil::xmlEncode(empty)); #include <stdlib.h>
assert(empty == XmlRpcUtil::xmlDecode(empty));
assert(empty == XmlRpcUtil::xmlEncode(""));
assert(empty == XmlRpcUtil::xmlDecode(""));
#include "XmlRpcUtil.h"
std::string raw("<>&'\"");
assert(XmlRpcUtil::xmlDecode(XmlRpcUtil::xmlEncode(raw)) == raw);
std::cout << "Basic tests passed.\n"; using namespace robot::XmlRpc;
// Interactive tests
std::string s;
for (;;) {
std::cout << "\nEnter line of raw text to encode:\n";
std::getline(std::cin, s); int main(int argc, char* argv[])
if (s.empty()) break;
{
std::cout << XmlRpcUtil::xmlEncode(s) << std::endl;
} // Basic tests
for (;;) { std::string empty;
std::cout << "\nEnter line of xml-encoded text to decode:\n";
std::getline(std::cin, s); assert(empty == XmlRpcUtil::xmlEncode(empty));
if (s.empty()) break;
assert(empty == XmlRpcUtil::xmlDecode(empty));
std::cout << XmlRpcUtil::xmlDecode(s) << std::endl;
} assert(empty == XmlRpcUtil::xmlEncode(""));
return 0; assert(empty == XmlRpcUtil::xmlDecode(""));
}
std::string raw("<>&'\"");
assert(XmlRpcUtil::xmlDecode(XmlRpcUtil::xmlEncode(raw)) == raw);
std::cout << "Basic tests passed.\n";
// Interactive tests
std::string s;
for (;;) {
std::cout << "\nEnter line of raw text to encode:\n";
std::getline(std::cin, s);
if (s.empty()) break;
std::cout << XmlRpcUtil::xmlEncode(s) << std::endl;
}
for (;;) {
std::cout << "\nEnter line of xml-encoded text to decode:\n";
std::getline(std::cin, s);
if (s.empty()) break;
std::cout << XmlRpcUtil::xmlDecode(s) << std::endl;
}
return 0;
}

View File

@ -1,207 +1,414 @@
// Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com. // Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com.
//
#include "XmlRpc.h" //
using namespace XmlRpc;
#include "XmlRpc.h"
#include <iostream>
using namespace robot::XmlRpc;
XmlRpcServer s;
#include <iostream>
// One argument is passed, an array of structs, each with a member named curly with
// an integer value. Return the sum of those values.
class ArrayOfStructsTest : public XmlRpcServerMethod
{
public: XmlRpcServer s;
ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result)
{
std::cerr << "ArrayOfStructsTest\n";
XmlRpcValue& arg1 = params[0]; // One argument is passed, an array of structs, each with a member named curly with
int n = arg1.size(), sum = 0;
for (int i=0; i<n; ++i) // an integer value. Return the sum of those values.
sum += int(arg1[i]["curly"]);
result = sum;
} class ArrayOfStructsTest : public XmlRpcServerMethod
} arrayOfStructsTest(&s);
{
// This handler takes a single parameter, a string, that contains any number of predefined public:
// entities, namely <, >, &, ' and ".
// The handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets, ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {}
// ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes.
// To validate, the numbers must be correct.
class CountTheEntities : public XmlRpcServerMethod void execute(XmlRpcValue& params, XmlRpcValue& result)
{
public: {
CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {}
std::cerr << "ArrayOfStructsTest\n";
void execute(XmlRpcValue& params, XmlRpcValue& result)
{ XmlRpcValue& arg1 = params[0];
std::cerr << "CountTheEntities\n";
std::string& arg = params[0]; int n = arg1.size(), sum = 0;
int ctLeftAngleBrackets = 0;
int ctRightAngleBrackets = 0; for (int i=0; i<n; ++i)
int ctAmpersands = 0;
int ctApostrophes = 0; sum += int(arg1[i]["curly"]);
int ctQuotes = 0;
int n = int(arg.length());
for (int i=0; i<n; ++i) result = sum;
switch (arg[i])
{ }
case '<': ++ctLeftAngleBrackets; break;
case '>': ++ctRightAngleBrackets; break; } arrayOfStructsTest(&s);
case '&': ++ctAmpersands; break;
case '\'': ++ctApostrophes; break;
case '\"': ++ctQuotes; break;
}
result["ctLeftAngleBrackets"] = ctLeftAngleBrackets; // This handler takes a single parameter, a string, that contains any number of predefined
result["ctRightAngleBrackets"] = ctRightAngleBrackets;
result["ctAmpersands"] = ctAmpersands; // entities, namely <, >, &, ' and ".
result["ctApostrophes"] = ctApostrophes;
result["ctQuotes"] = ctQuotes; // The handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets,
}
} countTheEntities(&s); // ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes.
// To validate, the numbers must be correct.
// This handler takes a single parameter, a struct, containing at least three elements
// named moe, larry and curly, all <i4>s. Your handler must add the three numbers and
// return the result. class CountTheEntities : public XmlRpcServerMethod
class EasyStructTest : public XmlRpcServerMethod {
{
public: public:
EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {}
CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result)
{
std::cerr << "EasyStructTest\n";
XmlRpcValue& arg1 = params[0]; void execute(XmlRpcValue& params, XmlRpcValue& result)
int sum = int(arg1["moe"]) + int(arg1["larry"]) + int(arg1["curly"]);
result = sum; {
}
} easyStructTest(&s); std::cerr << "CountTheEntities\n";
std::string& arg = params[0];
// This handler takes a single parameter, a struct. Your handler must return the struct.
int ctLeftAngleBrackets = 0;
class EchoStructTest : public XmlRpcServerMethod
{ int ctRightAngleBrackets = 0;
public:
EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {} int ctAmpersands = 0;
void execute(XmlRpcValue& params, XmlRpcValue& result) int ctApostrophes = 0;
{
std::cerr << "EchoStructTest\n"; int ctQuotes = 0;
result = params[0];
}
} echoStructTest(&s);
int n = int(arg.length());
for (int i=0; i<n; ++i)
// This handler takes six parameters, and returns an array containing all the parameters.
switch (arg[i])
class ManyTypesTest : public XmlRpcServerMethod
{ {
public:
ManyTypesTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.manyTypesTest", s) {} case '<': ++ctLeftAngleBrackets; break;
void execute(XmlRpcValue& params, XmlRpcValue& result) case '>': ++ctRightAngleBrackets; break;
{
std::cerr << "ManyTypesTest\n"; case '&': ++ctAmpersands; break;
result = params;
} case '\'': ++ctApostrophes; break;
} manyTypesTest(&s);
case '\"': ++ctQuotes; break;
}
// This handler takes a single parameter, which is an array containing between 100 and
// 200 elements. Each of the items is a string, your handler must return a string
// containing the concatenated text of the first and last elements.
result["ctLeftAngleBrackets"] = ctLeftAngleBrackets;
class ModerateSizeArrayCheck : public XmlRpcServerMethod result["ctRightAngleBrackets"] = ctRightAngleBrackets;
{
public: result["ctAmpersands"] = ctAmpersands;
ModerateSizeArrayCheck(XmlRpcServer* s) : XmlRpcServerMethod("validator1.moderateSizeArrayCheck", s) {}
result["ctApostrophes"] = ctApostrophes;
void execute(XmlRpcValue& params, XmlRpcValue& result)
{ result["ctQuotes"] = ctQuotes;
std::cerr << "ModerateSizeArrayCheck\n";
std::string s = params[0][0]; }
s += params[0][params[0].size()-1];
result = s; } countTheEntities(&s);
}
} moderateSizeArrayCheck(&s);
// This handler takes a single parameter, a struct, that models a daily calendar.
// At the top level, there is one struct for each year. Each year is broken down
// into months, and months into days. Most of the days are empty in the struct
// you receive, but the entry for April 1, 2000 contains a least three elements // This handler takes a single parameter, a struct, containing at least three elements
// named moe, larry and curly, all <i4>s. Your handler must add the three numbers
// and return the result. // named moe, larry and curly, all <i4>s. Your handler must add the three numbers and
class NestedStructTest : public XmlRpcServerMethod // return the result.
{
public:
NestedStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.nestedStructTest", s) {}
class EasyStructTest : public XmlRpcServerMethod
void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "NestedStructTest\n";
XmlRpcValue& dayStruct = params[0]["2000"]["04"]["01"]; public:
int sum = int(dayStruct["moe"]) + int(dayStruct["larry"]) + int(dayStruct["curly"]);
result = sum; EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {}
}
} nestedStructTest(&s);
void execute(XmlRpcValue& params, XmlRpcValue& result)
// This handler takes one parameter, and returns a struct containing three elements, {
// times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000.
std::cerr << "EasyStructTest\n";
class SimpleStructReturnTest : public XmlRpcServerMethod
{ XmlRpcValue& arg1 = params[0];
public:
SimpleStructReturnTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.simpleStructReturnTest", s) {} int sum = int(arg1["moe"]) + int(arg1["larry"]) + int(arg1["curly"]);
void execute(XmlRpcValue& params, XmlRpcValue& result) result = sum;
{
std::cerr << "SimpleStructReturnTest\n"; }
int n = params[0];
result["times10"] = n * 10; } easyStructTest(&s);
result["times100"] = n * 100;
result["times1000"] = n * 1000;
}
} simpleStructReturnTest(&s);
// This handler takes a single parameter, a struct. Your handler must return the struct.
int main(int argc, char* argv[])
{
if (argc != 2) { class EchoStructTest : public XmlRpcServerMethod
std::cerr << "Usage: Validator port\n";
return -1; {
}
int port = atoi(argv[1]); public:
XmlRpc::setVerbosity(5); EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {}
// Create the server socket on the specified port
s.bindAndListen(port);
void execute(XmlRpcValue& params, XmlRpcValue& result)
// Wait for requests indefinitely
s.work(-1.0); {
return 0; std::cerr << "EchoStructTest\n";
}
result = params[0];
}
} echoStructTest(&s);
// This handler takes six parameters, and returns an array containing all the parameters.
class ManyTypesTest : public XmlRpcServerMethod
{
public:
ManyTypesTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.manyTypesTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result)
{
std::cerr << "ManyTypesTest\n";
result = params;
}
} manyTypesTest(&s);
// This handler takes a single parameter, which is an array containing between 100 and
// 200 elements. Each of the items is a string, your handler must return a string
// containing the concatenated text of the first and last elements.
class ModerateSizeArrayCheck : public XmlRpcServerMethod
{
public:
ModerateSizeArrayCheck(XmlRpcServer* s) : XmlRpcServerMethod("validator1.moderateSizeArrayCheck", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result)
{
std::cerr << "ModerateSizeArrayCheck\n";
std::string s = params[0][0];
s += params[0][params[0].size()-1];
result = s;
}
} moderateSizeArrayCheck(&s);
// This handler takes a single parameter, a struct, that models a daily calendar.
// At the top level, there is one struct for each year. Each year is broken down
// into months, and months into days. Most of the days are empty in the struct
// you receive, but the entry for April 1, 2000 contains a least three elements
// named moe, larry and curly, all <i4>s. Your handler must add the three numbers
// and return the result.
class NestedStructTest : public XmlRpcServerMethod
{
public:
NestedStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.nestedStructTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result)
{
std::cerr << "NestedStructTest\n";
XmlRpcValue& dayStruct = params[0]["2000"]["04"]["01"];
int sum = int(dayStruct["moe"]) + int(dayStruct["larry"]) + int(dayStruct["curly"]);
result = sum;
}
} nestedStructTest(&s);
// This handler takes one parameter, and returns a struct containing three elements,
// times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000.
class SimpleStructReturnTest : public XmlRpcServerMethod
{
public:
SimpleStructReturnTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.simpleStructReturnTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result)
{
std::cerr << "SimpleStructReturnTest\n";
int n = params[0];
result["times10"] = n * 10;
result["times100"] = n * 100;
result["times1000"] = n * 1000;
}
} simpleStructReturnTest(&s);
int main(int argc, char* argv[])
{
if (argc != 2) {
std::cerr << "Usage: Validator port\n";
return -1;
}
int port = atoi(argv[1]);
robot::XmlRpc::setVerbosity(5);
// Create the server socket on the specified port
s.bindAndListen(port);
// Wait for requests indefinitely
s.work(-1.0);
return 0;
}