JODA  0.13.1 (59b41972)
JSON On-Demand Analysis
IValueProvider.h
Go to the documentation of this file.
1 //
2 // Created by Nico Schäfer on 11/13/17.
3 //
4 
5 #ifndef JODA_IVALUEPROVIDER_H
6 #define JODA_IVALUEPROVIDER_H
7 #include <glog/logging.h>
8 #include <rapidjson/document.h>
9 #include <rapidjson/fwd.h>
10 
11 #include <cmath>
12 #include <experimental/optional>
13 #include <memory>
14 #include <string>
15 
17 
18 // Helper define, which creates a factory method used to create an instance of a
19 // function, given a list of parameters
20 #define CREATE_FACTORY(FCLASS) \
21  static std::unique_ptr<IValueProvider> _FACTORY( \
22  std::vector<std::unique_ptr<IValueProvider>> &&params) { \
23  return std::make_unique<FCLASS>(std::move(params)); \
24  }
25 
26 namespace joda::query {
33 enum IValueType {
40  IV_Null
41 };
42 
46 class WrongParameterException : public std::exception {
47  public:
48  WrongParameterException(const std::string &whatStr) : whatStr(whatStr) {}
49  virtual const char *what() const throw() { return whatStr.c_str(); }
50 
51  protected:
53  std::string whatStr;
54 };
55 
61  public:
62  WrongParameterTypeException(unsigned int i, IValueType expected,
63  const std::string &name) {
64  whatStr = name + ": Parameter " + std::to_string(i) +
65  " is of wrong type. Expected: ";
66  switch (expected) {
67  case IV_String:
68  whatStr += "String";
69  break;
70  case IV_Number:
71  whatStr += "Number";
72  break;
73  case IV_Bool:
74  whatStr += "Bool";
75  break;
76  case IV_Object:
77  whatStr += "Object";
78  break;
79  case IV_Array:
80  whatStr += "Array";
81  break;
82  case IV_Any:
83  whatStr += "Any";
84  break;
85  case IV_Null:
86  DCHECK(false) << "Expected null parameter? O.o";
87  break;
88  }
89  }
90 };
91 
97  public:
98  WrongParameterCountException(const std::string &name) {
99  whatStr = name + ": Wrong number of parameters";
100  };
101  WrongParameterCountException(unsigned int count, unsigned int expected,
102  const std::string &name, bool min = false) {
103 
104  whatStr = name + ": Expected ";
105  if(min) {
106  whatStr += "at least ";
107  }
108  whatStr += std::to_string(expected) +
109  " parameters, but got " + std::to_string(count);
110  }
111 };
112 
118  public:
120  const std::string &name) : WrongParameterCountException(name) {
121 
122  whatStr = name + ": Missing parameter " + std::to_string(i);
123  }
124 };
125 
131  public:
132  ConstParameterException(unsigned int i,
133  const std::string &name) {
134 
135  whatStr = name + ": Parameter " + std::to_string(i) + " has to be a constant.";
136  }
137 };
138 
144  public:
151  explicit IValueProvider(
152  std::vector<std::unique_ptr<IValueProvider>> &&parameters);
157  IValueProvider();
158 
159  virtual ~IValueProvider() = default;
160 
171  RJMemoryPoolAlloc &alloc) const = 0;
172 
182  virtual RJValue const *getValue(const RapidJsonDocument &json,
183  RJMemoryPoolAlloc &alloc) const = 0;
184 
188  virtual std::unique_ptr<IValueProvider> duplicate() const = 0;
192  virtual std::string toString() const;
197  virtual std::string getName() const = 0;
202  virtual bool isConst() const = 0;
207  virtual IValueType getReturnType() const = 0;
208  virtual bool isString() const { return getReturnType() == IV_String; };
209  virtual bool isNumber() const { return getReturnType() == IV_Number; };
210  virtual bool isBool() const { return getReturnType() == IV_Bool; };
211  virtual bool isObject() const { return getReturnType() == IV_Object; };
212  virtual bool isArray() const { return getReturnType() == IV_Array; };
213  virtual bool isNull() const { return getReturnType() == IV_Null; };
214  virtual bool isAny() const { return getReturnType() == IV_Any; };
215  virtual bool isAtom() const { return isString() || isNumber() || isBool(); };
216 
222  virtual std::vector<std::string> getAttributes() const {
223  std::vector<std::string> ret;
224  getAttributes(ret);
225  return ret;
226  }
227 
232  virtual void getAttributes(std::vector<std::string> &vec) const {
233  for (auto &&param : params) {
234  param->getAttributes(vec);
235  }
236  }
237 
244  bool equal(IValueProvider *other, const RapidJsonDocument &json) const {
245  RJMemoryPoolAlloc tmpAlloc;
246  const RJValue *lhs;
247  RJValue tmplhs;
248  const RJValue *rhs;
249  RJValue tmprhs;
250  // Get Pointer to value
251  if (isAtom()) {
252  tmplhs = getAtomValue(json, tmpAlloc);
253  lhs = &tmplhs;
254  } else {
255  lhs = getValue(json, tmpAlloc);
256  }
257  if (lhs == nullptr) return false;
258  // Get Pointer to List
259  if (other->isAtom()) {
260  tmprhs = other->getAtomValue(json, tmpAlloc);
261  rhs = &tmprhs;
262  } else {
263  rhs = other->getValue(json, tmpAlloc);
264  }
265  if (rhs == nullptr) return false;
266 
267  auto lhsType = lhs->GetType();
268  auto rhsType = rhs->GetType();
269  if (lhsType != rhsType) return false; // If different types, false
270 
271  if (lhsType == rapidjson::kTrueType && rhsType == rapidjson::kTrueType)
272  return true;
273  if (lhsType == rapidjson::kFalseType && rhsType == rapidjson::kFalseType)
274  return true;
275 
276  if (lhsType == rapidjson::kNumberType &&
277  rhsType == rapidjson::kNumberType) {
278  if (lhs->IsUint64() && rhs->IsUint64())
279  return lhs->GetUint64() == rhs->GetUint64();
280  if (lhs->IsInt64() && rhs->IsInt64())
281  return lhs->GetInt64() == rhs->GetInt64();
282  return fabs(lhs->GetDouble() - rhs->GetDouble()) <
283  std::numeric_limits<double>::epsilon();
284  }
285 
286  if (lhsType == rapidjson::kStringType &&
287  rhsType == rapidjson::kStringType) {
288  return strcmp(lhs->GetString(), rhs->GetString()) == 0;
289  }
290 
291  if (lhsType == rapidjson::kNullType && rhsType == rapidjson::kNullType) {
292  return true;
293  }
294 
295  return *lhs == *rhs; // Deep equality check
296  }
297 
302  virtual bool comparable() const {
303  return getReturnType() == IV_String || getReturnType() == IV_Number;
304  };
309  virtual bool equalizable() const {
310  return getReturnType() == IV_String || getReturnType() == IV_Number ||
312  getReturnType() == IV_Array;
313  };
314 
315  static void replaceConstSubexpressions(std::unique_ptr<IValueProvider> &val);
316  static bool constBoolCheck(std::unique_ptr<IValueProvider> &val);
317 
318  protected:
319  bool getParamString(std::string &ret,
320  const std::unique_ptr<IValueProvider> &val,
321  const RapidJsonDocument &json) const {
322  RJMemoryPoolAlloc alloc;
323  if (!val->isAtom()) {
324  auto *retPtr = val->getValue(json, alloc);
325  if (retPtr != nullptr && retPtr->IsString()) {
326  ret = retPtr->GetString();
327  return true;
328  }
329  } else if (val->isString()) {
330  auto retVal = val->getAtomValue(json, alloc);
331  if (retVal.IsString()) {
332  ret = retVal.GetString();
333  return true;
334  }
335  }
336  return false;
337  }
338 
344  void checkParamSize(unsigned int expected);
345 
351  void checkMinParamSize(unsigned int expected);
352 
359  void checkParamType(unsigned int i, IValueType expected);
360 
367  void checkOptionalParamType(unsigned int i, IValueType expected);
368 
369  std::vector<std::unique_ptr<IValueProvider>> duplicateParameters() const;
370 
371  std::string getParameterStringRepresentation() const;
372 
373  std::vector<std::unique_ptr<IValueProvider>> params;
374 };
375 } // namespace joda::query
376 
377 #endif // JODA_IVALUEPROVIDER_H
rapidjson::MemoryPoolAllocator< RJBaseAlloc > RJMemoryPoolAlloc
Definition: RJFwd.h:26
rapidjson::GenericValue< RJChar, RJMemoryPoolAlloc > RJValue
Definition: RJFwd.h:29
Definition: RapidJsonDocument.h:22
Definition: IValueProvider.h:130
ConstParameterException(unsigned int i, const std::string &name)
Definition: IValueProvider.h:132
Definition: IValueProvider.h:143
virtual std::string getName() const =0
void checkMinParamSize(unsigned int expected)
Definition: IValueProvider.cpp:118
virtual bool isAny() const
Definition: IValueProvider.h:214
IValueProvider()
Definition: IValueProvider.cpp:84
virtual bool isConst() const =0
std::vector< std::unique_ptr< IValueProvider > > params
Definition: IValueProvider.h:373
void checkParamSize(unsigned int expected)
Definition: IValueProvider.cpp:112
virtual bool isAtom() const
Definition: IValueProvider.h:215
virtual bool isArray() const
Definition: IValueProvider.h:212
std::vector< std::unique_ptr< IValueProvider > > duplicateParameters() const
Definition: IValueProvider.cpp:104
static void replaceConstSubexpressions(std::unique_ptr< IValueProvider > &val)
Definition: IValueProvider.cpp:11
virtual ~IValueProvider()=default
virtual std::unique_ptr< IValueProvider > duplicate() const =0
bool getParamString(std::string &ret, const std::unique_ptr< IValueProvider > &val, const RapidJsonDocument &json) const
Definition: IValueProvider.h:319
virtual bool equalizable() const
Definition: IValueProvider.h:309
bool equal(IValueProvider *other, const RapidJsonDocument &json) const
Definition: IValueProvider.h:244
void checkOptionalParamType(unsigned int i, IValueType expected)
Definition: IValueProvider.cpp:134
virtual IValueType getReturnType() const =0
virtual bool isBool() const
Definition: IValueProvider.h:210
void checkParamType(unsigned int i, IValueType expected)
Definition: IValueProvider.cpp:125
virtual RJValue getAtomValue(const RapidJsonDocument &json, RJMemoryPoolAlloc &alloc) const =0
std::string getParameterStringRepresentation() const
Definition: IValueProvider.cpp:87
virtual bool comparable() const
Definition: IValueProvider.h:302
virtual std::string toString() const
Definition: IValueProvider.cpp:99
virtual bool isObject() const
Definition: IValueProvider.h:211
virtual RJValue const * getValue(const RapidJsonDocument &json, RJMemoryPoolAlloc &alloc) const =0
virtual std::vector< std::string > getAttributes() const
Definition: IValueProvider.h:222
virtual bool isNumber() const
Definition: IValueProvider.h:209
static bool constBoolCheck(std::unique_ptr< IValueProvider > &val)
Definition: IValueProvider.cpp:62
virtual bool isString() const
Definition: IValueProvider.h:208
virtual void getAttributes(std::vector< std::string > &vec) const
Definition: IValueProvider.h:232
virtual bool isNull() const
Definition: IValueProvider.h:213
Definition: IValueProvider.h:117
MissingParameterException(unsigned int i, const std::string &name)
Definition: IValueProvider.h:119
Definition: IValueProvider.h:96
WrongParameterCountException(const std::string &name)
Definition: IValueProvider.h:98
WrongParameterCountException(unsigned int count, unsigned int expected, const std::string &name, bool min=false)
Definition: IValueProvider.h:101
Definition: IValueProvider.h:46
virtual const char * what() const
Definition: IValueProvider.h:49
WrongParameterException(const std::string &whatStr)
Definition: IValueProvider.h:48
std::string whatStr
Definition: IValueProvider.h:53
Definition: IValueProvider.h:60
WrongParameterTypeException(unsigned int i, IValueType expected, const std::string &name)
Definition: IValueProvider.h:62
Definition: AttributeStatAggregator.h:12
IValueType
Definition: IValueProvider.h:33
@ IV_Object
Definition: IValueProvider.h:37
@ IV_Number
Definition: IValueProvider.h:35
@ IV_Bool
Definition: IValueProvider.h:36
@ IV_Null
Definition: IValueProvider.h:40
@ IV_String
Definition: IValueProvider.h:34
@ IV_Any
Definition: IValueProvider.h:39
@ IV_Array
Definition: IValueProvider.h:38