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 | |
16 | using namespace std; |
17 | using namespace jsonrpc; |
18 | |
19 | Procedure::Procedure() : procedureName("" ), procedureType(RPC_METHOD), returntype(JSON_BOOLEAN), paramDeclaration(PARAMS_BY_NAME) {} |
20 | |
21 | Procedure::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 | } |
37 | Procedure::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 | |
54 | bool Procedure::ValdiateParameters(const Json::Value ¶meters) 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 | } |
66 | const parameterNameList_t &Procedure::GetParameters() const { return this->parametersName; } |
67 | procedure_t Procedure::GetProcedureType() const { return this->procedureType; } |
68 | const std::string &Procedure::GetProcedureName() const { return this->procedureName; } |
69 | parameterDeclaration_t Procedure::GetParameterDeclarationType() const { return this->paramDeclaration; } |
70 | jsontype_t Procedure::GetReturnType() const { return this->returntype; } |
71 | |
72 | void Procedure::SetProcedureName(const string &name) { this->procedureName = name; } |
73 | void Procedure::SetProcedureType(procedure_t type) { this->procedureType = type; } |
74 | void Procedure::SetReturnType(jsontype_t type) { this->returntype = type; } |
75 | void Procedure::SetParameterDeclarationType(parameterDeclaration_t type) { this->paramDeclaration = type; } |
76 | |
77 | void Procedure::AddParameter(const string &name, jsontype_t type) { |
78 | this->parametersName[name] = type; |
79 | this->parametersPosition.push_back(type); |
80 | } |
81 | bool Procedure::ValidateNamedParameters(const Json::Value ¶meters) 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 | } |
92 | bool Procedure::ValidatePositionalParameters(const Json::Value ¶meters) 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 | } |
104 | bool 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 | |