1 /*************************************************************************//**
3 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 ****************************************************************************/
18 /**************************************************************************//**
20 * Implementation of EVEL functions relating to json_object.
22 ****************************************************************************/
30 #include "evel_internal.h"
32 /**************************************************************************//**
33 * Create a new json object.
35 * @note The mandatory fields on the Other must be supplied to this factory
36 * function and are immutable once set. Optional fields have explicit
37 * setter functions, but again values may only be set once so that the
38 * Other has immutable properties.
39 * @param name name of the object.
40 * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT.
41 * not used (i.e. posted) it must be released using ::evel_free_jsonobject.
42 * @retval NULL Failed to create the json object.
43 *****************************************************************************/
44 EVEL_JSON_OBJECT * evel_new_jsonobject(const char *const name)
46 EVEL_JSON_OBJECT *jobj = NULL;
49 /***************************************************************************/
50 /* Check preconditions. */
51 /***************************************************************************/
54 /***************************************************************************/
55 /* Allocate the json object. */
56 /***************************************************************************/
57 jobj = malloc(sizeof(EVEL_JSON_OBJECT));
60 log_error_state("Out of memory");
63 memset(jobj, 0, sizeof(EVEL_JSON_OBJECT));
64 EVEL_DEBUG("New json object is at %lp", jobj);
66 /***************************************************************************/
67 /* Initialize the fields. Optional string values are */
68 /* uninitialized (NULL). */
69 /***************************************************************************/
70 jobj->object_name = strdup(name);
71 evel_init_option_string(&jobj->objectschema);
72 evel_init_option_string(&jobj->objectschemaurl);
73 evel_init_option_string(&jobj->nfsubscribedobjname);
74 evel_init_option_string(&jobj->nfsubscriptionid);
75 dlist_initialize(&jobj->jsonobjectinstances);
83 /**************************************************************************//**
84 * Create a new json object instance.
86 * @note The mandatory fields on the Other must be supplied to this factory
87 * function and are immutable once set. Optional fields have explicit
88 * setter functions, but again values may only be set once so that the
89 * Other has immutable properties.
90 * @param yourjson json string.
91 * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT_INSTANCE.
92 * not used (i.e. posted) it must be released using ::evel_free_jsonobjectinstance.
93 * @retval NULL Failed to create the json object instance.
94 *****************************************************************************/
95 EVEL_JSON_OBJECT_INSTANCE * evel_new_jsonobjinstance(const char *const yourjson)
97 EVEL_JSON_OBJECT_INSTANCE *jobjinst = NULL;
99 char *keyString = NULL;
103 jsmntok_t tokens[MAX_JSON_TOKENS]; // a number >= total number of tokens
109 /***************************************************************************/
110 /* Check preconditions. */
111 /***************************************************************************/
112 assert(yourjson != NULL);
113 len = strlen(yourjson)+1;
116 /***************************************************************************/
117 /* Validate JSON for json object
118 /***************************************************************************/
120 resultCode = jsmn_parse(&p, yourjson, len, tokens, sizeof(tokens)/sizeof(tokens[0]));
121 if( resultCode < 0 ){
122 log_error_state("Failed to parse json for object");
126 if (resultCode < 1 || tokens[0].type != JSMN_OBJECT) {
127 log_error_state("Error json object expected");
131 /***************************************************************************/
132 /* Allocate the json object. */
133 /***************************************************************************/
134 jobjinst = malloc(sizeof(EVEL_JSON_OBJECT_INSTANCE));
135 if (jobjinst == NULL)
137 log_error_state("Out of memory");
140 memset(jobjinst, 0, sizeof(EVEL_JSON_OBJECT_INSTANCE));
142 /***************************************************************************/
143 /* Initialize the fields. Optional key values are */
144 /* uninitialized (NULL). */
145 /***************************************************************************/
146 jobjinst->jsonstring = strdup(yourjson);
147 dlist_initialize(&jobjinst->object_keys);
155 /**************************************************************************//**
156 * Create a new internal key.
158 * @note The mandatory fields on the Other must be supplied to this factory
159 * function and are immutable once set. Optional fields have explicit
160 * setter functions, but again values may only be set once so that the
161 * Other has immutable properties.
162 * @param keyname name of the key.
163 * @returns pointer to the newly manufactured ::EVEL_INTERNAL_KEY.
164 * not used (i.e. posted) it must be released using ::evel_free_internal_key.
165 * @retval NULL Failed to create the internal key.
166 *****************************************************************************/
167 EVEL_INTERNAL_KEY * evel_new_internal_key(char *keyname)
169 EVEL_INTERNAL_KEY *keyinst = NULL;
172 /***************************************************************************/
173 /* Check preconditions. */
174 /***************************************************************************/
175 assert(keyname != NULL);
177 /***************************************************************************/
178 /* Allocate the key object. */
179 /***************************************************************************/
180 keyinst = malloc(sizeof(EVEL_INTERNAL_KEY));
183 log_error_state("Out of memory");
186 memset(keyinst, 0, sizeof(EVEL_INTERNAL_KEY));
187 keyinst->keyname = strdup(keyname);
189 /***************************************************************************/
190 /* Optional string values are uninitialized (NULL). */
191 /***************************************************************************/
192 evel_init_option_int(&keyinst->keyorder);
193 evel_init_option_string(&keyinst->keyvalue);
200 /**************************************************************************//**
201 * Set the keyorder of the internal key instance.
203 * @note The property is treated as immutable: it is only valid to call
204 * the setter once. However, we don't assert if the caller tries to
205 * overwrite, just ignoring the update instead.
207 * @param int keyorder
208 *****************************************************************************/
209 void evel_internal_key_keyorder_set(EVEL_INTERNAL_KEY * pinst, const int keyorder)
211 assert (pinst != NULL);
212 evel_set_option_int(&pinst->keyorder,keyorder,"Key order");
215 /**************************************************************************//**
216 * Set the keyvalue of the internal key instance.
218 * @note The property is treated as immutable: it is only valid to call
219 * the setter once. However, we don't assert if the caller tries to
220 * overwrite, just ignoring the update instead.
222 * @param string keyvalue
223 *****************************************************************************/
224 void evel_internal_key_keyvalue_set(EVEL_INTERNAL_KEY * pinst, const char * const keyval)
226 assert (pinst != NULL);
227 evel_set_option_string(&pinst->keyvalue,keyval,"Key Value");
230 /**************************************************************************//**
231 * Set the string values of json object
233 * @note The property is treated as immutable: it is only valid to call
234 * the setter once. However, we don't assert if the caller tries to
235 * overwrite, just ignoring the update instead.
237 * @param string object schema
238 *****************************************************************************/
239 void evel_jsonobject_objectschema_set(EVEL_JSON_OBJECT * pinst, const char * const objectschema)
241 assert (pinst != NULL);
242 evel_set_option_string(&pinst->objectschema,objectschema,"Object Schema");
245 /**************************************************************************//**
246 * Set the string values of json object
248 * @note The property is treated as immutable: it is only valid to call
249 * the setter once. However, we don't assert if the caller tries to
250 * overwrite, just ignoring the update instead.
252 * @param string object schema url
253 *****************************************************************************/
254 void evel_jsonobject_objectschemaurl_set(EVEL_JSON_OBJECT * pinst, const char * const objectschemaurl)
256 assert (pinst != NULL);
257 evel_set_option_string(&pinst->objectschemaurl,objectschemaurl,"Object Schema URL");
260 /**************************************************************************//**
261 * Set the string values of json object
263 * @note The property is treated as immutable: it is only valid to call
264 * the setter once. However, we don't assert if the caller tries to
265 * overwrite, just ignoring the update instead.
267 * @param string NF Subscribed object name
268 *****************************************************************************/
269 void evel_jsonobject_nfsubscribedobjname_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscribedobjname)
271 assert (pinst != NULL);
272 evel_set_option_string(&pinst->nfsubscribedobjname,nfsubscribedobjname,"NF Subscribed Object Name");
275 /**************************************************************************//**
276 * Set the string values of json object
278 * @note The property is treated as immutable: it is only valid to call
279 * the setter once. However, we don't assert if the caller tries to
280 * overwrite, just ignoring the update instead.
282 * @param string NF Subscription Id
283 *****************************************************************************/
284 void evel_jsonobject_nfsubscriptionid_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscriptionid)
286 assert (pinst != NULL);
287 evel_set_option_string(&pinst->nfsubscriptionid,nfsubscriptionid,"NF Subscription Id");
290 /**************************************************************************//**
291 * Set the Epoch time of the json object instance.
293 * @note The property is treated as immutable: it is only valid to call
294 * the setter once. However, we don't assert if the caller tries to
295 * overwrite, just ignoring the update instead.
297 * @param unsigned long long epoch time
298 *****************************************************************************/
299 void evel_epoch_microsec_set(EVEL_JSON_OBJECT_INSTANCE * pinst, const unsigned long long epmicrosec)
301 assert(epmicrosec != 0 );
302 pinst->objinst_epoch_microsec = epmicrosec;
305 /**************************************************************************//**
306 * Add a json object instance to jsonObject list.
308 * The name and value are null delimited ASCII strings. The library takes
309 * a copy so the caller does not have to preserve values after the function
312 * @param pobj Pointer to the Other.
313 * @param jinst Pointer to HashTable
314 *****************************************************************************/
315 void evel_jsonobject_add_jsoninstance(EVEL_JSON_OBJECT * pobj, EVEL_JSON_OBJECT_INSTANCE *jinst)
319 /***************************************************************************/
320 /* Check preconditions. */
321 /***************************************************************************/
322 assert(pobj != NULL);
323 assert(jinst != NULL);
325 EVEL_DEBUG("Adding json object instance");
327 dlist_push_last(&pobj->jsonobjectinstances, jinst);
333 /**************************************************************************//**
334 * Add a json object to jsonObject list.
336 * The name and value are null delimited ASCII strings. The library takes
337 * a copy so the caller does not have to preserve values after the function
340 * @param other Pointer to the Other.
341 * @param jsonobj Pointer to json object
342 *****************************************************************************/
343 void evel_jsonobjinst_add_objectkey(EVEL_JSON_OBJECT_INSTANCE * jsoninst, EVEL_INTERNAL_KEY *keyp)
347 /***************************************************************************/
348 /* Check preconditions. */
349 /***************************************************************************/
350 assert(jsoninst != NULL);
351 assert(keyp != NULL);
353 EVEL_DEBUG("Adding jsonObject instance");
355 dlist_push_last(&jsoninst->object_keys, keyp);
360 /**************************************************************************//**
361 * Free an internal key.
363 * Free off the internal key supplied. Will free all the contained allocated memory.
365 *****************************************************************************/
366 void evel_free_internal_key(EVEL_INTERNAL_KEY * keyp)
371 /***************************************************************************/
372 /* Check preconditions. As an internal API we don't allow freeing NULL */
373 /* events as we do on the public API. */
374 /***************************************************************************/
375 assert(keyp != NULL);
378 evel_free_option_string(&keyp->keyvalue);
383 /**************************************************************************//**
384 * Free an json object instance.
386 * Free off the json object instance supplied.
387 * Will free all the contained allocated memory.
389 *****************************************************************************/
390 void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst)
392 EVEL_INTERNAL_KEY *other_field = NULL;
395 assert(objinst != NULL);
396 assert(objinst->jsonstring != NULL);
398 free(objinst->jsonstring);
400 /***************************************************************************/
401 /* Free all internal internal keys
402 /***************************************************************************/
403 other_field = dlist_pop_last(&objinst->object_keys);
404 while (other_field != NULL)
406 EVEL_DEBUG("Freeing Object Instance Field (%s)",
407 other_field->keyname);
408 evel_free_internal_key(other_field);
409 other_field = dlist_pop_last(&objinst->object_keys);
415 /**************************************************************************//**
416 * Free an json object.
418 * Free off the json object instance supplied.
419 * Will free all the contained allocated memory.
421 *****************************************************************************/
422 void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj)
424 EVEL_JSON_OBJECT_INSTANCE *other_field = NULL;
427 assert(jsobj != NULL);
429 free(jsobj->object_name);
430 evel_free_option_string(&jsobj->objectschema);
431 evel_free_option_string(&jsobj->objectschemaurl);
432 evel_free_option_string(&jsobj->nfsubscribedobjname);
433 evel_free_option_string(&jsobj->nfsubscriptionid);
435 /***************************************************************************/
436 /* Free all internal strings then the header itself. */
437 /***************************************************************************/
438 other_field = dlist_pop_last(&jsobj->jsonobjectinstances);
439 while (other_field != NULL)
441 EVEL_DEBUG("Freeing Object Instance Field (%s)",
442 other_field->jsonstring);
443 evel_free_jsonobjinst(other_field);
444 other_field = dlist_pop_last(&jsobj->jsonobjectinstances);