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:
ArrayOfStructsTest(XmlRpcServer * s)18 ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {}
19
execute(XmlRpcValue & params,XmlRpcValue & result)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:
CountTheEntities(XmlRpcServer * s)42 CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {}
43
execute(XmlRpcValue & params,XmlRpcValue & result)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:
EasyStructTest(XmlRpcServer * s)82 EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {}
83
execute(XmlRpcValue & params,XmlRpcValue & result)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:
EchoStructTest(XmlRpcServer * s)99 EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {}
100
execute(XmlRpcValue & params,XmlRpcValue & result)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:
ManyTypesTest(XmlRpcServer * s)115 ManyTypesTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.manyTypesTest", s) {}
116
execute(XmlRpcValue & params,XmlRpcValue & result)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:
ModerateSizeArrayCheck(XmlRpcServer * s)134 ModerateSizeArrayCheck(XmlRpcServer* s) : XmlRpcServerMethod("validator1.moderateSizeArrayCheck", s) {}
135
execute(XmlRpcValue & params,XmlRpcValue & result)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:
NestedStructTest(XmlRpcServer * s)156 NestedStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.nestedStructTest", s) {}
157
execute(XmlRpcValue & params,XmlRpcValue & result)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:
SimpleStructReturnTest(XmlRpcServer * s)175 SimpleStructReturnTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.simpleStructReturnTest", s) {}
176
execute(XmlRpcValue & params,XmlRpcValue & result)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
main(int argc,char * argv[])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