1// Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com. 2// 3#include "XmlRpc.h" 4using namespace XmlRpc; 5 6#include <iostream> 7 8 9XmlRpcServer s; 10 11 12// One argument is passed, an array of structs, each with a member named curly with 13// an integer value. Return the sum of those values. 14 15class ArrayOfStructsTest : public XmlRpcServerMethod 16{ 17public: 18 ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {} 19 20 void execute(XmlRpcValue& params, XmlRpcValue& result) 21 { 22 std::cerr << "ArrayOfStructsTest\n"; 23 XmlRpcValue& arg1 = params[0]; 24 int n = arg1.size(), sum = 0; 25 for (int i=0; i<n; ++i) 26 sum += int(arg1[i]["curly"]); 27 28 result = sum; 29 } 30} arrayOfStructsTest(&s); 31 32 33// This handler takes a single parameter, a string, that contains any number of predefined 34// entities, namely <, >, &, ' and ". 35// The handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets, 36// ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes. 37// To validate, the numbers must be correct. 38 39class CountTheEntities : public XmlRpcServerMethod 40{ 41public: 42 CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {} 43 44 void execute(XmlRpcValue& params, XmlRpcValue& result) 45 { 46 std::cerr << "CountTheEntities\n"; 47 std::string& arg = params[0]; 48 int ctLeftAngleBrackets = 0; 49 int ctRightAngleBrackets = 0; 50 int ctAmpersands = 0; 51 int ctApostrophes = 0; 52 int ctQuotes = 0; 53 54 int n = int(arg.length()); 55 for (int i=0; i<n; ++i) 56 switch (arg[i]) 57 { 58 case '<': ++ctLeftAngleBrackets; break; 59 case '>': ++ctRightAngleBrackets; break; 60 case '&': ++ctAmpersands; break; 61 case '\'': ++ctApostrophes; break; 62 case '\"': ++ctQuotes; break; 63 } 64 65 result["ctLeftAngleBrackets"] = ctLeftAngleBrackets; 66 result["ctRightAngleBrackets"] = ctRightAngleBrackets; 67 result["ctAmpersands"] = ctAmpersands; 68 result["ctApostrophes"] = ctApostrophes; 69 result["ctQuotes"] = ctQuotes; 70 } 71} countTheEntities(&s); 72 73 74 75// This handler takes a single parameter, a struct, containing at least three elements 76// named moe, larry and curly, all <i4>s. Your handler must add the three numbers and 77// return the result. 78 79class EasyStructTest : public XmlRpcServerMethod 80{ 81public: 82 EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {} 83 84 void execute(XmlRpcValue& params, XmlRpcValue& result) 85 { 86 std::cerr << "EasyStructTest\n"; 87 XmlRpcValue& arg1 = params[0]; 88 int sum = int(arg1["moe"]) + int(arg1["larry"]) + int(arg1["curly"]); 89 result = sum; 90 } 91} easyStructTest(&s); 92 93 94// This handler takes a single parameter, a struct. Your handler must return the struct. 95 96class EchoStructTest : public XmlRpcServerMethod 97{ 98public: 99 EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {} 100 101 void execute(XmlRpcValue& params, XmlRpcValue& result) 102 { 103 std::cerr << "EchoStructTest\n"; 104 result = params[0]; 105 } 106} echoStructTest(&s); 107 108 109 110// This handler takes six parameters, and returns an array containing all the parameters. 111 112class ManyTypesTest : public XmlRpcServerMethod 113{ 114public: 115 ManyTypesTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.manyTypesTest", s) {} 116 117 void execute(XmlRpcValue& params, XmlRpcValue& result) 118 { 119 std::cerr << "ManyTypesTest\n"; 120 result = params; 121 } 122} manyTypesTest(&s); 123 124 125 126// This handler takes a single parameter, which is an array containing between 100 and 127// 200 elements. Each of the items is a string, your handler must return a string 128// containing the concatenated text of the first and last elements. 129 130 131class ModerateSizeArrayCheck : public XmlRpcServerMethod 132{ 133public: 134 ModerateSizeArrayCheck(XmlRpcServer* s) : XmlRpcServerMethod("validator1.moderateSizeArrayCheck", s) {} 135 136 void execute(XmlRpcValue& params, XmlRpcValue& result) 137 { 138 std::cerr << "ModerateSizeArrayCheck\n"; 139 std::string s = params[0][0]; 140 s += params[0][params[0].size()-1]; 141 result = s; 142 } 143} moderateSizeArrayCheck(&s); 144 145 146// This handler takes a single parameter, a struct, that models a daily calendar. 147// At the top level, there is one struct for each year. Each year is broken down 148// into months, and months into days. Most of the days are empty in the struct 149// you receive, but the entry for April 1, 2000 contains a least three elements 150// named moe, larry and curly, all <i4>s. Your handler must add the three numbers 151// and return the result. 152 153class NestedStructTest : public XmlRpcServerMethod 154{ 155public: 156 NestedStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.nestedStructTest", s) {} 157 158 void execute(XmlRpcValue& params, XmlRpcValue& result) 159 { 160 std::cerr << "NestedStructTest\n"; 161 XmlRpcValue& dayStruct = params[0]["2000"]["04"]["01"]; 162 int sum = int(dayStruct["moe"]) + int(dayStruct["larry"]) + int(dayStruct["curly"]); 163 result = sum; 164 } 165} nestedStructTest(&s); 166 167 168 169// This handler takes one parameter, and returns a struct containing three elements, 170// times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000. 171 172class SimpleStructReturnTest : public XmlRpcServerMethod 173{ 174public: 175 SimpleStructReturnTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.simpleStructReturnTest", s) {} 176 177 void execute(XmlRpcValue& params, XmlRpcValue& result) 178 { 179 std::cerr << "SimpleStructReturnTest\n"; 180 int n = params[0]; 181 result["times10"] = n * 10; 182 result["times100"] = n * 100; 183 result["times1000"] = n * 1000; 184 } 185} simpleStructReturnTest(&s); 186 187 188 189int main(int argc, char* argv[]) 190{ 191 if (argc != 2) { 192 std::cerr << "Usage: Validator port\n"; 193 return -1; 194 } 195 int port = atoi(argv[1]); 196 197 XmlRpc::setVerbosity(5); 198 199 // Create the server socket on the specified port 200 s.bindAndListen(port); 201 202 // Wait for requests indefinitely 203 s.work(-1.0); 204 205 return 0; 206} 207 208