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