// Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com. // #include "XmlRpc.h" using namespace XmlRpc; #include <iostream> XmlRpcServer s; // 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: ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {} void execute(XmlRpcValue& params, XmlRpcValue& result) { std::cerr << "ArrayOfStructsTest\n"; XmlRpcValue& arg1 = params[0]; int n = arg1.size(), sum = 0; for (int i=0; i<n; ++i) sum += int(arg1[i]["curly"]); result = sum; } } arrayOfStructsTest(&s); // This handler takes a single parameter, a string, that contains any number of predefined // entities, namely <, >, &, ' and ". // The handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets, // ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes. // To validate, the numbers must be correct. class CountTheEntities : public XmlRpcServerMethod { public: CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {} void execute(XmlRpcValue& params, XmlRpcValue& result) { std::cerr << "CountTheEntities\n"; std::string& arg = params[0]; int ctLeftAngleBrackets = 0; int ctRightAngleBrackets = 0; int ctAmpersands = 0; int ctApostrophes = 0; int ctQuotes = 0; int n = int(arg.length()); for (int i=0; i<n; ++i) switch (arg[i]) { case '<': ++ctLeftAngleBrackets; break; case '>': ++ctRightAngleBrackets; break; case '&': ++ctAmpersands; break; case '\'': ++ctApostrophes; break; case '\"': ++ctQuotes; break; } result["ctLeftAngleBrackets"] = ctLeftAngleBrackets; result["ctRightAngleBrackets"] = ctRightAngleBrackets; result["ctAmpersands"] = ctAmpersands; result["ctApostrophes"] = ctApostrophes; result["ctQuotes"] = ctQuotes; } } countTheEntities(&s); // 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 EasyStructTest : public XmlRpcServerMethod { public: EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {} void execute(XmlRpcValue& params, XmlRpcValue& result) { std::cerr << "EasyStructTest\n"; XmlRpcValue& arg1 = params[0]; int sum = int(arg1["moe"]) + int(arg1["larry"]) + int(arg1["curly"]); result = sum; } } easyStructTest(&s); // This handler takes a single parameter, a struct. Your handler must return the struct. class EchoStructTest : public XmlRpcServerMethod { public: EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {} void execute(XmlRpcValue& params, XmlRpcValue& result) { 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]); XmlRpc::setVerbosity(5); // Create the server socket on the specified port s.bindAndListen(port); // Wait for requests indefinitely s.work(-1.0); return 0; }