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;
101 jsmntok_t tokens[MAX_JSON_TOKENS]; // a number >= total number of tokens
107 /***************************************************************************/
108 /* Check preconditions. */
109 /***************************************************************************/
110 assert(yourjson != NULL);
111 len = strlen(yourjson)+1;
114 /***************************************************************************/
115 /* Validate JSON for json object
116 /***************************************************************************/
118 resultCode = jsmn_parse(&p, yourjson, len, tokens, sizeof(tokens)/sizeof(tokens[0]));
119 if( resultCode < 0 ){
120 log_error_state("Failed to parse json for object");
124 if (resultCode < 1 || tokens[0].type != JSMN_OBJECT) {
125 log_error_state("Error json object expected");
129 /***************************************************************************/
130 /* Allocate the json object. */
131 /***************************************************************************/
132 jobjinst = malloc(sizeof(EVEL_JSON_OBJECT_INSTANCE));
133 if (jobjinst == NULL)
135 log_error_state("Out of memory");
138 memset(jobjinst, 0, sizeof(EVEL_JSON_OBJECT_INSTANCE));
140 /***************************************************************************/
141 /* Initialize the fields. Optional key values are */
142 /* uninitialized (NULL). */
143 /***************************************************************************/
144 jobjinst->jsonstring = strdup(yourjson);
145 dlist_initialize(&jobjinst->object_keys);
153 /**************************************************************************//**
154 * Create a new internal key.
156 * @note The mandatory fields on the Other must be supplied to this factory
157 * function and are immutable once set. Optional fields have explicit
158 * setter functions, but again values may only be set once so that the
159 * Other has immutable properties.
160 * @param keyname name of the key.
161 * @returns pointer to the newly manufactured ::EVEL_INTERNAL_KEY.
162 * not used (i.e. posted) it must be released using ::evel_free_internal_key.
163 * @retval NULL Failed to create the internal key.
164 *****************************************************************************/
165 EVEL_INTERNAL_KEY * evel_new_internal_key(char *keyname)
167 EVEL_INTERNAL_KEY *keyinst = NULL;
170 /***************************************************************************/
171 /* Check preconditions. */
172 /***************************************************************************/
173 assert(keyname != NULL);
175 /***************************************************************************/
176 /* Allocate the key object. */
177 /***************************************************************************/
178 keyinst = malloc(sizeof(EVEL_INTERNAL_KEY));
181 log_error_state("Out of memory");
184 memset(keyinst, 0, sizeof(EVEL_INTERNAL_KEY));
185 keyinst->keyname = strdup(keyname);
187 /***************************************************************************/
188 /* Optional string values are uninitialized (NULL). */
189 /***************************************************************************/
190 evel_init_option_int(&keyinst->keyorder);
191 evel_init_option_string(&keyinst->keyvalue);
198 /**************************************************************************//**
199 * Set the keyorder of the internal key instance.
201 * @note The property is treated as immutable: it is only valid to call
202 * the setter once. However, we don't assert if the caller tries to
203 * overwrite, just ignoring the update instead.
205 * @param int keyorder
206 *****************************************************************************/
207 void evel_internal_key_keyorder_set(EVEL_INTERNAL_KEY * pinst, const int keyorder)
209 assert (pinst != NULL);
210 evel_set_option_int(&pinst->keyorder,keyorder,"Key order");
213 /**************************************************************************//**
214 * Set the keyvalue of the internal key instance.
216 * @note The property is treated as immutable: it is only valid to call
217 * the setter once. However, we don't assert if the caller tries to
218 * overwrite, just ignoring the update instead.
220 * @param string keyvalue
221 *****************************************************************************/
222 void evel_internal_key_keyvalue_set(EVEL_INTERNAL_KEY * pinst, const char * const keyval)
224 assert (pinst != NULL);
225 evel_set_option_string(&pinst->keyvalue,keyval,"Key Value");
228 /**************************************************************************//**
229 * Set the string values of json object
231 * @note The property is treated as immutable: it is only valid to call
232 * the setter once. However, we don't assert if the caller tries to
233 * overwrite, just ignoring the update instead.
235 * @param string object schema
236 *****************************************************************************/
237 void evel_jsonobject_objectschema_set(EVEL_JSON_OBJECT * pinst, const char * const objectschema)
239 assert (pinst != NULL);
240 evel_set_option_string(&pinst->objectschema,objectschema,"Object Schema");
243 /**************************************************************************//**
244 * Set the string values of json object
246 * @note The property is treated as immutable: it is only valid to call
247 * the setter once. However, we don't assert if the caller tries to
248 * overwrite, just ignoring the update instead.
250 * @param string object schema url
251 *****************************************************************************/
252 void evel_jsonobject_objectschemaurl_set(EVEL_JSON_OBJECT * pinst, const char * const objectschemaurl)
254 assert (pinst != NULL);
255 evel_set_option_string(&pinst->objectschemaurl,objectschemaurl,"Object Schema URL");
258 /**************************************************************************//**
259 * Set the string values of json object
261 * @note The property is treated as immutable: it is only valid to call
262 * the setter once. However, we don't assert if the caller tries to
263 * overwrite, just ignoring the update instead.
265 * @param string NF Subscribed object name
266 *****************************************************************************/
267 void evel_jsonobject_nfsubscribedobjname_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscribedobjname)
269 assert (pinst != NULL);
270 evel_set_option_string(&pinst->nfsubscribedobjname,nfsubscribedobjname,"NF Subscribed Object Name");
273 /**************************************************************************//**
274 * Set the string values of json object
276 * @note The property is treated as immutable: it is only valid to call
277 * the setter once. However, we don't assert if the caller tries to
278 * overwrite, just ignoring the update instead.
280 * @param string NF Subscription Id
281 *****************************************************************************/
282 void evel_jsonobject_nfsubscriptionid_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscriptionid)
284 assert (pinst != NULL);
285 evel_set_option_string(&pinst->nfsubscriptionid,nfsubscriptionid,"NF Subscription Id");
288 /**************************************************************************//**
289 * Set the Epoch time of the json object instance.
291 * @note The property is treated as immutable: it is only valid to call
292 * the setter once. However, we don't assert if the caller tries to
293 * overwrite, just ignoring the update instead.
295 * @param unsigned long long epoch time
296 *****************************************************************************/
297 void evel_epoch_microsec_set(EVEL_JSON_OBJECT_INSTANCE * pinst, const unsigned long long epmicrosec)
299 assert(epmicrosec != 0 );
300 pinst->objinst_epoch_microsec = epmicrosec;
303 /**************************************************************************//**
304 * Add a json object instance to jsonObject list.
306 * The name and value are null delimited ASCII strings. The library takes
307 * a copy so the caller does not have to preserve values after the function
310 * @param pobj Pointer to the Other.
311 * @param jinst Pointer to HashTable
312 *****************************************************************************/
313 void evel_jsonobject_add_jsoninstance(EVEL_JSON_OBJECT * pobj, EVEL_JSON_OBJECT_INSTANCE *jinst)
317 /***************************************************************************/
318 /* Check preconditions. */
319 /***************************************************************************/
320 assert(pobj != NULL);
321 assert(jinst != NULL);
323 EVEL_DEBUG("Adding json object instance");
325 dlist_push_last(&pobj->jsonobjectinstances, jinst);
331 /**************************************************************************//**
332 * Add a json object to jsonObject list.
334 * The name and value are null delimited ASCII strings. The library takes
335 * a copy so the caller does not have to preserve values after the function
338 * @param other Pointer to the Other.
339 * @param jsonobj Pointer to json object
340 *****************************************************************************/
341 void evel_jsonobjinst_add_objectkey(EVEL_JSON_OBJECT_INSTANCE * jsoninst, EVEL_INTERNAL_KEY *keyp)
345 /***************************************************************************/
346 /* Check preconditions. */
347 /***************************************************************************/
348 assert(jsoninst != NULL);
349 assert(keyp != NULL);
351 EVEL_DEBUG("Adding jsonObject instance");
353 dlist_push_last(&jsoninst->object_keys, keyp);
358 /**************************************************************************//**
359 * Free an internal key.
361 * Free off the internal key supplied. Will free all the contained allocated memory.
363 *****************************************************************************/
364 void evel_free_internal_key(EVEL_INTERNAL_KEY * keyp)
369 /***************************************************************************/
370 /* Check preconditions. As an internal API we don't allow freeing NULL */
371 /* events as we do on the public API. */
372 /***************************************************************************/
373 assert(keyp != NULL);
376 evel_free_option_string(&keyp->keyvalue);
381 /**************************************************************************//**
382 * Free an json object instance.
384 * Free off the json object instance supplied.
385 * Will free all the contained allocated memory.
387 *****************************************************************************/
388 void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst)
390 EVEL_INTERNAL_KEY *other_field = NULL;
393 assert(objinst != NULL);
394 assert(objinst->jsonstring != NULL);
396 free(objinst->jsonstring);
398 /***************************************************************************/
399 /* Free all internal internal keys
400 /***************************************************************************/
401 other_field = dlist_pop_last(&objinst->object_keys);
402 while (other_field != NULL)
404 EVEL_DEBUG("Freeing Object Instance Field (%s)",
405 other_field->keyname);
406 evel_free_internal_key(other_field);
407 other_field = dlist_pop_last(&objinst->object_keys);
413 /**************************************************************************//**
414 * Free an json object.
416 * Free off the json object instance supplied.
417 * Will free all the contained allocated memory.
419 *****************************************************************************/
420 void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj)
422 EVEL_JSON_OBJECT_INSTANCE *other_field = NULL;
425 assert(jsobj != NULL);
427 free(jsobj->object_name);
428 evel_free_option_string(&jsobj->objectschema);
429 evel_free_option_string(&jsobj->objectschemaurl);
430 evel_free_option_string(&jsobj->nfsubscribedobjname);
431 evel_free_option_string(&jsobj->nfsubscriptionid);
433 /***************************************************************************/
434 /* Free all internal strings then the header itself. */
435 /***************************************************************************/
436 other_field = dlist_pop_last(&jsobj->jsonobjectinstances);
437 while (other_field != NULL)
439 EVEL_DEBUG("Freeing Object Instance Field (%s)",
440 other_field->jsonstring);
441 evel_free_jsonobjinst(other_field);
442 other_field = dlist_pop_last(&jsobj->jsonobjectinstances);