1/*************************************************************************
2 * libjson-rpc-cpp
3 *************************************************************************
4 * @file procedure.cpp
5 * @date 31.12.2012
6 * @author Peter Spiess-Knafl <dev@spiessknafl.at>
7 * @license See attached LICENSE.txt
8 ************************************************************************/
9
10#include "procedure.h"
11#include "errors.h"
12#include "exception.h"
13#include <cstdarg>
14#include <vector>
15
16using namespace std;
17using namespace jsonrpc;
18
19Procedure::Procedure() : procedureName(""), procedureType(RPC_METHOD), returntype(JSON_BOOLEAN), paramDeclaration(PARAMS_BY_NAME) {}
20
21Procedure::Procedure(const string &name, parameterDeclaration_t paramType, jsontype_t returntype, ...) {
22 va_list parameters;
23 va_start(parameters, returntype);
24 const char *paramname = va_arg(parameters, const char *);
25 jsontype_t type;
26 while (paramname != NULL) {
27 type = (jsontype_t)va_arg(parameters, int);
28 this->AddParameter(paramname, type);
29 paramname = va_arg(parameters, const char *);
30 }
31 va_end(parameters);
32 this->procedureName = name;
33 this->returntype = returntype;
34 this->procedureType = RPC_METHOD;
35 this->paramDeclaration = paramType;
36}
37Procedure::Procedure(const string &name, parameterDeclaration_t paramType, ...) {
38 va_list parameters;
39 va_start(parameters, paramType);
40 const char *paramname = va_arg(parameters, const char *);
41 jsontype_t type;
42 while (paramname != NULL) {
43 type = (jsontype_t)va_arg(parameters, int);
44 this->AddParameter(paramname, type);
45 paramname = va_arg(parameters, const char *);
46 }
47 va_end(parameters);
48 this->procedureName = name;
49 this->procedureType = RPC_NOTIFICATION;
50 this->paramDeclaration = paramType;
51 this->returntype = JSON_BOOLEAN;
52}
53
54bool Procedure::ValdiateParameters(const Json::Value &parameters) const {
55 if (this->parametersName.empty()) {
56 return true;
57 }
58 if (parameters.isArray() && this->paramDeclaration == PARAMS_BY_POSITION) {
59 return this->ValidatePositionalParameters(parameters);
60 } else if (parameters.isObject() && this->paramDeclaration == PARAMS_BY_NAME) {
61 return this->ValidateNamedParameters(parameters);
62 } else {
63 return false;
64 }
65}
66const parameterNameList_t &Procedure::GetParameters() const { return this->parametersName; }
67procedure_t Procedure::GetProcedureType() const { return this->procedureType; }
68const std::string &Procedure::GetProcedureName() const { return this->procedureName; }
69parameterDeclaration_t Procedure::GetParameterDeclarationType() const { return this->paramDeclaration; }
70jsontype_t Procedure::GetReturnType() const { return this->returntype; }
71
72void Procedure::SetProcedureName(const string &name) { this->procedureName = name; }
73void Procedure::SetProcedureType(procedure_t type) { this->procedureType = type; }
74void Procedure::SetReturnType(jsontype_t type) { this->returntype = type; }
75void Procedure::SetParameterDeclarationType(parameterDeclaration_t type) { this->paramDeclaration = type; }
76
77void Procedure::AddParameter(const string &name, jsontype_t type) {
78 this->parametersName[name] = type;
79 this->parametersPosition.push_back(type);
80}
81bool Procedure::ValidateNamedParameters(const Json::Value &parameters) const {
82 bool ok = parameters.isObject() || parameters.isNull();
83 for (map<string, jsontype_t>::const_iterator it = this->parametersName.begin(); ok == true && it != this->parametersName.end(); ++it) {
84 if (!parameters.isMember(it->first)) {
85 ok = false;
86 } else {
87 ok = this->ValidateSingleParameter(it->second, parameters[it->first]);
88 }
89 }
90 return ok;
91}
92bool Procedure::ValidatePositionalParameters(const Json::Value &parameters) const {
93 bool ok = true;
94
95 if (parameters.size() != this->parametersPosition.size()) {
96 return false;
97 }
98
99 for (unsigned int i = 0; ok && i < this->parametersPosition.size(); i++) {
100 ok = this->ValidateSingleParameter(this->parametersPosition.at(i), parameters[i]);
101 }
102 return ok;
103}
104bool Procedure::ValidateSingleParameter(jsontype_t expectedType, const Json::Value &value) const {
105 bool ok = true;
106 switch (expectedType) {
107 case JSON_STRING:
108 if (!value.isString())
109 ok = false;
110 break;
111 case JSON_BOOLEAN:
112 if (!value.isBool())
113 ok = false;
114 break;
115 case JSON_INTEGER:
116 if (!value.isIntegral())
117 ok = false;
118 break;
119 case JSON_REAL:
120 if (!value.isDouble())
121 ok = false;
122 break;
123 case JSON_NUMERIC:
124 if (!value.isNumeric())
125 ok = false;
126 break;
127 case JSON_OBJECT:
128 if (!value.isObject())
129 ok = false;
130 break;
131 case JSON_ARRAY:
132 if (!value.isArray())
133 ok = false;
134 break;
135 }
136 return ok;
137}
138