RDK Documentation (Open Sourced RDK Components)
AampJsonObject.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2020 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 /**
21  * @file AampJsonObject.cpp
22  * @brief File to handle Json format object
23  */
24 
25 #include <vector>
26 
27 #include "AampJsonObject.h"
28 #include "AampUtils.h"
29 #include "_base64.h"
30 
31 
32 
33 AampJsonObject::AampJsonObject() : mParent(NULL), mJsonObj()
34 {
35  mJsonObj = cJSON_CreateObject();
36 }
37 
38 AampJsonObject::AampJsonObject(const std::string& jsonStr) : mParent(NULL), mJsonObj()
39 {
40  mJsonObj = cJSON_Parse(jsonStr.c_str());
41 
42  if (!mJsonObj)
43  {
44  throw AampJsonParseException();
45  }
46 }
47 
48 AampJsonObject::AampJsonObject(const char* jsonStr) : mParent(NULL), mJsonObj()
49 {
50  mJsonObj = cJSON_Parse(jsonStr);
51 
52  if (!mJsonObj)
53  {
54  throw AampJsonParseException();
55  }
56 }
57 
58 AampJsonObject::~AampJsonObject()
59 {
60  if (!mParent)
61  {
62  cJSON_Delete(mJsonObj);
63  }
64 }
65 
66 /**
67  * @brief Add a string value
68  */
69 bool AampJsonObject::add(const std::string& name, const std::string& value, const ENCODING encoding)
70 {
71  bool res = false;
72 
73  if (encoding == ENCODING_STRING)
74  {
75  res = add(name, cJSON_CreateString(value.c_str()));
76  }
77  else
78  {
79  res = add(name, std::vector<uint8_t>(value.begin(), value.end()), encoding);
80  }
81 
82  return res;
83 }
84 
85 /**
86  * @brief Add a string value
87  */
88 bool AampJsonObject::add(const std::string& name, const char *value, const ENCODING encoding)
89 {
90  return add(name, std::string(value), encoding);
91 }
92 
93 /**
94  * @brief Add a vector of string values as a JSON array
95  */
96 bool AampJsonObject::add(const std::string& name, const std::vector<std::string>& values)
97 {
98  cJSON* arr = cJSON_CreateArray();
99  for (auto value : values)
100  {
101  cJSON_AddItemToArray(arr, cJSON_CreateString(value.c_str()));
102  }
103  return add(name, arr);
104 }
105 
106 /**
107  * @brief Add the provided bytes after encoding in the specified encoding
108  */
109 bool AampJsonObject::add(const std::string& name, const std::vector<uint8_t>& values, const ENCODING encoding)
110 {
111  bool res = false;
112 
113  switch (encoding)
114  {
115  case ENCODING_STRING:
116  {
117  std::string strValue(values.begin(), values.end());
118  res = add(name, cJSON_CreateString(strValue.c_str()));
119  }
120  break;
121 
122  case ENCODING_BASE64:
123  {
124  const char *encodedResponse = base64_Encode((const unsigned char*)&values[0], values.size());
125  if (encodedResponse != NULL)
126  {
127  res = add(name, cJSON_CreateString(encodedResponse));
128  free((void*)encodedResponse);
129  }
130  }
131  break;
132 
133  case ENCODING_BASE64_URL:
134  {
135  const char *encodedResponse = aamp_Base64_URL_Encode((const unsigned char*)&values[0], values.size());
136  if (encodedResponse != NULL)
137  {
138  res = add(name, cJSON_CreateString(encodedResponse));
139  free((void*)encodedResponse);
140  }
141  }
142  break;
143 
144  default:
145  /* Unsupported encoding format */
146  break;
147  }
148 
149  return res;
150 }
151 
152 /**
153  * @brief Add a vector of #AampJsonObject as a JSON array
154  */
155 bool AampJsonObject::add(const std::string& name, AampJsonObject& value)
156 {
157  cJSON_AddItemToObject(mJsonObj, name.c_str(), value.mJsonObj);
158  value.mParent = this;
159  return true;
160 }
161 
162 /**
163  * @brief Add a vector of string values as a JSON array
164  */
165 bool AampJsonObject::add(const std::string& name, std::vector<AampJsonObject*>& values)
166 {
167  cJSON *arr = cJSON_CreateArray();
168  for (auto& obj : values)
169  {
170  cJSON_AddItemToArray(arr, obj->mJsonObj);
171  obj->mParent = this;
172  }
173  return add(name, arr);
174 }
175 
176 /**
177  * @brief Add a cJSON value
178  */
179 bool AampJsonObject::add(const std::string& name, cJSON *value)
180 {
181  if (NULL == value)
182  {
183  return false;
184  }
185  cJSON_AddItemToObject(mJsonObj, name.c_str(), value);
186  return true;
187 }
188 
189 
190 /**
191  * @brief Add a bool value
192  */
193 bool AampJsonObject::add(const std::string& name, bool value)
194 {
195  cJSON_AddItemToObject(mJsonObj, name.c_str(), cJSON_CreateBool(value));
196  return true;
197 }
198 
199 /**
200  * @brief Add a int value
201  */
202 bool AampJsonObject::add(const std::string& name, int value)
203 {
204  cJSON_AddItemToObject(mJsonObj, name.c_str(), cJSON_CreateNumber(value));
205  return true;
206 }
207 
208 /**
209  * @brief Add a double value
210  */
211 bool AampJsonObject::add(const std::string& name, double value)
212 {
213  cJSON_AddItemToObject(mJsonObj, name.c_str(), cJSON_CreateNumber(value));
214  return true;
215 }
216 
217 /**
218  * @brief Add a long value
219  */
220 bool AampJsonObject::add(const std::string& name, long value)
221 {
222  cJSON_AddItemToObject(mJsonObj, name.c_str(), cJSON_CreateNumber(value));
223  return true;
224 }
225 
226 /**
227  * @brief Set cJSON value
228  */
229 bool AampJsonObject::set(AampJsonObject *parent, cJSON *object)
230 {
231  this->mParent = parent;
232  this->mJsonObj = object;
233  /**< return true always to match the template */
234  return true;
235 }
236 
237 /**
238  * @brief Get the AampJson object from json data within the Json data
239  */
240 bool AampJsonObject::get(const std::string& name, AampJsonObject &value)
241 {
242  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
243  bool retValue = false;
244  if (strObj)
245  {
246  retValue = value.set(this, strObj);
247  }
248  return retValue;
249 }
250 
251 /**
252  * @brief Get a string value
253  */
254 bool AampJsonObject::get(const std::string& name, std::string& value)
255 {
256  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
257 
258  if (strObj)
259  {
260  char *strValue = cJSON_GetStringValue(strObj);
261  if (strValue)
262  {
263  value = strValue;
264  return true;
265  }
266  }
267  return false;
268 }
269 
270 /**
271  * @brief Get a int value from a JSON data
272  */
273 bool AampJsonObject::get(const std::string& name, int& value)
274 {
275  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
276  bool retValue = false;
277  if (strObj)
278  {
279  /**< time being commented due to unsupport in cJSON current version; and assuming value is 1
280  * Required version 1.7.13 **/
281  //retValue = cJSON_GetNumberValue(strObj);
282  value = (int)strObj->valuedouble;
283  retValue = true;
284  }
285  return retValue;
286 }
287 
288 /**
289  * @brief Get a string value
290  */
291 bool AampJsonObject::get(const std::string& name, std::vector<std::string>& values)
292 {
293  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
294  cJSON *object = NULL;
295  bool retVal = false;
296  cJSON_ArrayForEach(object, strObj)
297  {
298  char *strValue = cJSON_GetStringValue(object);
299  if (strValue)
300  {
301  values.push_back(std::string(strValue));
302  retVal = true;
303  }
304  }
305  return retVal;
306 }
307 
308 /**
309  * @brief Get a string value as a vector of bytes
310  */
311 bool AampJsonObject::get(const std::string& name, std::vector<uint8_t>& values, const ENCODING encoding)
312 {
313  bool res = false;
314  std::string strValue;
315 
316  if (get(name, strValue))
317  {
318  values.clear();
319 
320  switch (encoding)
321  {
322  case ENCODING_STRING:
323  {
324  values.insert(values.begin(), strValue.begin(), strValue.end());
325  }
326  break;
327 
328  case ENCODING_BASE64:
329  {
330  size_t decodedSize = 0;
331  const unsigned char *decodedResponse = base64_Decode(strValue.c_str(), &decodedSize, strValue.length());
332  if (decodedResponse != NULL)
333  {
334  values.insert(values.begin(), decodedResponse, decodedResponse + decodedSize);
335  res = true;
336  free((void *)decodedResponse);
337  }
338  }
339  break;
340 
341  case ENCODING_BASE64_URL:
342  {
343  size_t decodedSize = 0;
344  const unsigned char *decodedResponse = aamp_Base64_URL_Decode(strValue.c_str(), &decodedSize, strValue.length());
345  if (decodedResponse != NULL)
346  {
347  values.insert(values.begin(), decodedResponse, decodedResponse + decodedSize);
348  res = true;
349  free((void *)decodedResponse);
350  }
351  }
352  break;
353 
354  default:
355  /* Unsupported encoding format */
356  break;
357  }
358  }
359  return res;
360 }
361 
362 /**
363  * @brief Print the constructed JSON to a string
364  */
366 {
367  char *jsonString = cJSON_Print(mJsonObj);
368  if (NULL != jsonString)
369  {
370  std::string retStr(jsonString);
371  cJSON_free(jsonString);
372  return retStr;
373  }
374  return "";
375 }
376 
377 /**
378  * @brief Print the constructed JSON to a string
379  */
381 {
382  char *jsonString = cJSON_PrintUnformatted(mJsonObj);
383  if (NULL != jsonString)
384  {
385  std::string retStr(jsonString);
386  cJSON_free(jsonString);
387  return retStr;
388  }
389  return "";
390 }
391 
392 /**
393  * @brief Print the constructed JSON into the provided vector
394  */
395 void AampJsonObject::print(std::vector<uint8_t>& data)
396 {
397  std::string jsonOutputStr = print();
398  (void)data.insert(data.begin(), jsonOutputStr.begin(), jsonOutputStr.end());
399 }
400 
401 /**
402  * @brief Check whether the value is Array or not
403  */
404 bool AampJsonObject::isArray(const std::string& name)
405 {
406  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
407  bool retVal = false;
408  if (strObj)
409  {
410  retVal = cJSON_IsArray(strObj);
411  }
412  return retVal;
413 }
414 
415 /**
416  * @brief Check whether the value is String or not
417  */
418 bool AampJsonObject::isString(const std::string& name)
419 {
420  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
421  bool retVal = false;
422  if (strObj)
423  {
424  retVal = cJSON_IsString(strObj);
425  }
426  return retVal;
427 }
428 
429 /**
430  * @brief Check whether the value is Number or not
431  */
432 bool AampJsonObject::isNumber(const std::string& name)
433 {
434  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
435  bool retVal = false;
436  if (strObj)
437  {
438  retVal = cJSON_IsNumber(strObj);
439  }
440  return retVal;
441 }
442 
443 /**
444  * @brief Check whether the value is Object or not
445  */
446 bool AampJsonObject::isObject(const std::string& name)
447 {
448  cJSON *strObj = cJSON_GetObjectItem(mJsonObj, name.c_str());
449  bool retVal = false;
450  if (strObj)
451  {
452  retVal = cJSON_IsObject(strObj);
453  }
454  return retVal;
455 }
AampJsonObject::set
bool set(AampJsonObject *parent, cJSON *object)
Set cJSON value.
Definition: AampJsonObject.cpp:229
AampJsonParseException
Handles the exception for JSON parser.
Definition: AampJsonObject.h:252
AampJsonObject::get
bool get(const std::string &name, std::vector< std::string > &values)
Get a string value.
Definition: AampJsonObject.cpp:291
AampJsonObject::isArray
bool isArray(const std::string &name)
Check whether the value is Array or not.
Definition: AampJsonObject.cpp:404
AampJsonObject::isObject
bool isObject(const std::string &name)
Check whether the value is Object or not.
Definition: AampJsonObject.cpp:446
AampJsonObject::isString
bool isString(const std::string &name)
Check whether the value is String or not.
Definition: AampJsonObject.cpp:418
AampJsonObject::ENCODING_BASE64
@ ENCODING_BASE64
Definition: AampJsonObject.h:49
base64_Encode
char * base64_Encode(const unsigned char *src, size_t len)
convert blob of binary data to ascii base64-encoded equivalent
Definition: _base64.cpp:37
AampJsonObject.h
File to handle Json format.
_base64.h
base64 source Encoder/Decoder
AampJsonObject::print
std::string print()
Print the constructed JSON to a string.
Definition: AampJsonObject.cpp:365
AampJsonObject::ENCODING
ENCODING
Definition: AampJsonObject.h:46
aamp_Base64_URL_Decode
unsigned char * aamp_Base64_URL_Decode(const char *src, size_t *len, size_t srcLen)
decode base64 URL encoded data to binary equivalent
Definition: AampUtils.cpp:340
AampJsonObject::ENCODING_STRING
@ ENCODING_STRING
Definition: AampJsonObject.h:48
AampJsonObject::isNumber
bool isNumber(const std::string &name)
Check whether the value is Number or not.
Definition: AampJsonObject.cpp:432
AampJsonObject::print_UnFormatted
std::string print_UnFormatted()
Print the constructed JSON to a string.
Definition: AampJsonObject.cpp:380
AampJsonObject::add
bool add(const std::string &name, const std::string &value, const ENCODING encoding=ENCODING_STRING)
Add a string value.
Definition: AampJsonObject.cpp:69
aamp_Base64_URL_Encode
char * aamp_Base64_URL_Encode(const unsigned char *src, size_t len)
convert blob of binary data to ascii base64-URL-encoded equivalent
Definition: AampUtils.cpp:304
AampJsonObject::ENCODING_BASE64_URL
@ ENCODING_BASE64_URL
Definition: AampJsonObject.h:50
base64_Decode
unsigned char * base64_Decode(const char *src, size_t *len, size_t srcLen)
decode base64 encoded data to binary equivalent
Definition: _base64.cpp:91
AampJsonObject
Utility class to construct a JSON string.
Definition: AampJsonObject.h:37