1 // Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com. 2 // 3 #include "XmlRpc.h" 4 using namespace XmlRpc; 5 6 #include <iostream> 7 8 9 XmlRpcServer 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 15 class ArrayOfStructsTest : public XmlRpcServerMethod 16 { 17 public: 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 39 class CountTheEntities : public XmlRpcServerMethod 40 { 41 public: 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 79 class EasyStructTest : public XmlRpcServerMethod 80 { 81 public: 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 96 class EchoStructTest : public XmlRpcServerMethod 97 { 98 public: 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 112 class ManyTypesTest : public XmlRpcServerMethod 113 { 114 public: 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 131 class ModerateSizeArrayCheck : public XmlRpcServerMethod 132 { 133 public: 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 153 class NestedStructTest : public XmlRpcServerMethod 154 { 155 public: 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 172 class SimpleStructReturnTest : public XmlRpcServerMethod 173 { 174 public: 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 189 int 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