Change location of VES5.0 code
[demo.git] / vnfs / VES5.0 / evel / evel-library / code / evel_library / evel_jsonobject.c
1 /**************************************************************************//**
2  * @file
3  * Implementation of EVEL functions relating to json_object.
4  *
5  * License
6  * -------
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:  This product includes
18  *    software developed by the AT&T.
19  * 4. Neither the name of AT&T nor the names of its contributors may be used to
20  *    endorse or promote products derived from this software without specific
21  *    prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *****************************************************************************/
34
35 #include <string.h>
36 #include <assert.h>
37 #include <stdlib.h>
38
39 #include "jsmn.h"
40 #include "evel.h"
41 #include "evel_internal.h"
42
43 /**************************************************************************//**
44  * Create a new json object.
45  *
46  * @note    The mandatory fields on the Other must be supplied to this factory
47  *          function and are immutable once set.  Optional fields have explicit
48  *          setter functions, but again values may only be set once so that the
49  *          Other has immutable properties.
50  * @param name       name of the object.
51  * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT.
52  *          not used (i.e. posted) it must be released using ::evel_free_jsonobject.
53  * @retval  NULL  Failed to create the json object.
54  *****************************************************************************/
55 EVEL_JSON_OBJECT * evel_new_jsonobject(const char *const name)
56 {
57   EVEL_JSON_OBJECT *jobj = NULL;
58   EVEL_ENTER();
59
60   /***************************************************************************/
61   /* Check preconditions.                                                    */
62   /***************************************************************************/
63   assert(name != NULL);
64
65   /***************************************************************************/
66   /* Allocate the json object.                                                     */
67   /***************************************************************************/
68   jobj = malloc(sizeof(EVEL_JSON_OBJECT));
69   if (jobj == NULL)
70   {
71     log_error_state("Out of memory");
72     goto exit_label;
73   }
74   memset(jobj, 0, sizeof(EVEL_JSON_OBJECT));
75   EVEL_DEBUG("New json object is at %lp", jobj);
76
77   /***************************************************************************/
78   /* Initialize the fields.  Optional string values are   */
79   /* uninitialized (NULL).                                                   */
80   /***************************************************************************/
81   jobj->object_name = strdup(name);
82   evel_init_option_string(&jobj->objectschema);
83   evel_init_option_string(&jobj->objectschemaurl);
84   evel_init_option_string(&jobj->nfsubscribedobjname);
85   evel_init_option_string(&jobj->nfsubscriptionid);
86   dlist_initialize(&jobj->jsonobjectinstances);
87
88 exit_label:
89   EVEL_EXIT();
90   return jobj;
91 }
92
93
94 /**************************************************************************//**
95  * Create a new json object instance.
96  *
97  * @note    The mandatory fields on the Other must be supplied to this factory
98  *          function and are immutable once set.  Optional fields have explicit
99  *          setter functions, but again values may only be set once so that the
100  *          Other has immutable properties.
101  * @param   yourjson       json string.
102  * @returns pointer to the newly manufactured ::EVEL_JSON_OBJECT_INSTANCE.
103  *          not used (i.e. posted) it must be released using ::evel_free_jsonobjectinstance.
104  * @retval  NULL  Failed to create the json object instance.
105  *****************************************************************************/
106 EVEL_JSON_OBJECT_INSTANCE * evel_new_jsonobjinstance(const char *const yourjson)
107 {
108   EVEL_JSON_OBJECT_INSTANCE *jobjinst = NULL;
109   unsigned int length;
110   char *keyString = NULL;
111   jsmntok_t *key;
112   int resultCode;
113   jsmn_parser p;
114   jsmntok_t tokens[MAX_JSON_TOKENS]; // a number >= total number of tokens
115   int len=0;
116
117
118   EVEL_ENTER();
119
120   /***************************************************************************/
121   /* Check preconditions.                                                    */
122   /***************************************************************************/
123   assert(yourjson != NULL);
124   len = strlen(yourjson)+1;
125   assert(len > 0);
126
127   /***************************************************************************/
128   /*  Validate JSON for json object
129   /***************************************************************************/
130   jsmn_init(&p);
131   resultCode = jsmn_parse(&p, yourjson, len, tokens, sizeof(tokens)/sizeof(tokens[0]));
132   if( resultCode < 0 ){
133     log_error_state("Failed to parse json for object");
134     goto exit_label;
135   }
136
137   if (resultCode < 1 || tokens[0].type != JSMN_OBJECT) {
138     log_error_state("Error json object expected");
139     goto exit_label;
140   }
141
142   /***************************************************************************/
143   /* Allocate the json object.                                                     */
144   /***************************************************************************/
145   jobjinst = malloc(sizeof(EVEL_JSON_OBJECT_INSTANCE));
146   if (jobjinst == NULL)
147   {
148     log_error_state("Out of memory");
149     goto exit_label;
150   }
151   memset(jobjinst, 0, sizeof(EVEL_JSON_OBJECT_INSTANCE));
152
153   /***************************************************************************/
154   /* Initialize the fields.  Optional key values are   */
155   /* uninitialized (NULL).                                                   */
156   /***************************************************************************/
157   jobjinst->jsonstring = strdup(yourjson);
158   dlist_initialize(&jobjinst->object_keys);
159
160 exit_label:
161   EVEL_EXIT();
162   return jobjinst;
163 }
164
165
166 /**************************************************************************//**
167  * Create a new internal key.
168  *
169  * @note    The mandatory fields on the Other must be supplied to this factory
170  *          function and are immutable once set.  Optional fields have explicit
171  *          setter functions, but again values may only be set once so that the
172  *          Other has immutable properties.
173  * @param   keyname       name of the key.
174  * @returns pointer to the newly manufactured ::EVEL_INTERNAL_KEY.
175  *          not used (i.e. posted) it must be released using ::evel_free_internal_key.
176  * @retval  NULL  Failed to create the internal key.
177  *****************************************************************************/
178 EVEL_INTERNAL_KEY * evel_new_internal_key(char *keyname)
179 {
180   EVEL_INTERNAL_KEY *keyinst = NULL;
181   EVEL_ENTER();
182
183   /***************************************************************************/
184   /* Check preconditions.                                                    */
185   /***************************************************************************/
186   assert(keyname != NULL);
187
188   /***************************************************************************/
189   /* Allocate the key object.                                                     */
190   /***************************************************************************/
191   keyinst = malloc(sizeof(EVEL_INTERNAL_KEY));
192   if (keyinst == NULL)
193   {
194     log_error_state("Out of memory");
195     goto exit_label;
196   }
197   memset(keyinst, 0, sizeof(EVEL_INTERNAL_KEY));
198   keyinst->keyname = strdup(keyname);
199
200   /***************************************************************************/
201   /* Optional string values are  uninitialized (NULL).  */
202   /***************************************************************************/
203   evel_init_option_int(&keyinst->keyorder);
204   evel_init_option_string(&keyinst->keyvalue);
205
206 exit_label:
207   EVEL_EXIT();
208   return keyinst;
209 }
210
211 /**************************************************************************//**
212  * Set the keyorder  of the internal key instance.
213  *
214  * @note  The property is treated as immutable: it is only valid to call
215  *        the setter once.  However, we don't assert if the caller tries to
216  *        overwrite, just ignoring the update instead.
217  *
218  * @param int keyorder
219  *****************************************************************************/
220 void evel_internal_key_keyorder_set(EVEL_INTERNAL_KEY * pinst, const int keyorder)
221 {
222   assert (pinst != NULL);
223   evel_set_option_int(&pinst->keyorder,keyorder,"Key order");
224 }
225
226 /**************************************************************************//**
227  * Set the keyvalue  of the internal key instance.
228  *
229  * @note  The property is treated as immutable: it is only valid to call
230  *        the setter once.  However, we don't assert if the caller tries to
231  *        overwrite, just ignoring the update instead.
232  *
233  * @param string keyvalue
234  *****************************************************************************/
235 void evel_internal_key_keyvalue_set(EVEL_INTERNAL_KEY * pinst, const char * const keyval)
236 {
237   assert (pinst != NULL);
238   evel_set_option_string(&pinst->keyvalue,keyval,"Key Value");
239 }
240
241 /**************************************************************************//**
242  * Set the string values of json object
243  *
244  * @note  The property is treated as immutable: it is only valid to call
245  *        the setter once.  However, we don't assert if the caller tries to
246  *        overwrite, just ignoring the update instead.
247  *
248  * @param string object schema
249  *****************************************************************************/
250 void evel_jsonobject_objectschema_set(EVEL_JSON_OBJECT * pinst, const char * const objectschema)
251 {
252   assert (pinst != NULL);
253   evel_set_option_string(&pinst->objectschema,objectschema,"Object Schema");
254 }
255
256 /**************************************************************************//**
257  * Set the string values of json object
258  *
259  * @note  The property is treated as immutable: it is only valid to call
260  *        the setter once.  However, we don't assert if the caller tries to
261  *        overwrite, just ignoring the update instead.
262  *
263  * @param string object schema url
264  *****************************************************************************/
265 void evel_jsonobject_objectschemaurl_set(EVEL_JSON_OBJECT * pinst, const char * const objectschemaurl)
266 {
267   assert (pinst != NULL);
268   evel_set_option_string(&pinst->objectschemaurl,objectschemaurl,"Object Schema URL");
269 }
270
271 /**************************************************************************//**
272  * Set the string values of json object
273  *
274  * @note  The property is treated as immutable: it is only valid to call
275  *        the setter once.  However, we don't assert if the caller tries to
276  *        overwrite, just ignoring the update instead.
277  *
278  * @param string  NF Subscribed object name
279  *****************************************************************************/
280 void evel_jsonobject_nfsubscribedobjname_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscribedobjname)
281 {
282   assert (pinst != NULL);
283   evel_set_option_string(&pinst->nfsubscribedobjname,nfsubscribedobjname,"NF Subscribed Object Name");
284 }
285
286 /**************************************************************************//**
287  * Set the string values of json object
288  *
289  * @note  The property is treated as immutable: it is only valid to call
290  *        the setter once.  However, we don't assert if the caller tries to
291  *        overwrite, just ignoring the update instead.
292  *
293  * @param string  NF Subscription Id
294  *****************************************************************************/
295 void evel_jsonobject_nfsubscriptionid_set(EVEL_JSON_OBJECT * pinst, const char * const nfsubscriptionid)
296 {
297   assert (pinst != NULL);
298   evel_set_option_string(&pinst->nfsubscriptionid,nfsubscriptionid,"NF Subscription Id");
299 }
300
301 /**************************************************************************//**
302  * Set the Epoch time of the json object instance.
303  *
304  * @note  The property is treated as immutable: it is only valid to call
305  *        the setter once.  However, we don't assert if the caller tries to
306  *        overwrite, just ignoring the update instead.
307  *
308  * @param unsigned long long epoch time
309  *****************************************************************************/
310 void evel_epoch_microsec_set(EVEL_JSON_OBJECT_INSTANCE * pinst, const unsigned long long epmicrosec)
311 {
312   assert(epmicrosec != 0 );
313   pinst->objinst_epoch_microsec = epmicrosec;
314 }
315
316 /**************************************************************************//**
317  * Add a json object instance to jsonObject list.
318  *
319  * The name and value are null delimited ASCII strings.  The library takes
320  * a copy so the caller does not have to preserve values after the function
321  * returns.
322  *
323  * @param pobj         Pointer to the Other.
324  * @param jinst        Pointer to HashTable
325  *****************************************************************************/
326 void evel_jsonobject_add_jsoninstance(EVEL_JSON_OBJECT * pobj, EVEL_JSON_OBJECT_INSTANCE *jinst)
327 {
328   EVEL_ENTER();
329
330   /***************************************************************************/
331   /* Check preconditions.                                                    */
332   /***************************************************************************/
333   assert(pobj != NULL);
334   assert(jinst != NULL);
335
336   EVEL_DEBUG("Adding json object instance");
337
338   dlist_push_last(&pobj->jsonobjectinstances, jinst);
339
340   EVEL_EXIT();
341 }
342
343
344 /**************************************************************************//**
345  * Add a json object to jsonObject list.
346  *
347  * The name and value are null delimited ASCII strings.  The library takes
348  * a copy so the caller does not have to preserve values after the function
349  * returns.
350  *
351  * @param other     Pointer to the Other.
352  * @param jsonobj   Pointer to json object
353  *****************************************************************************/
354 void evel_jsonobjinst_add_objectkey(EVEL_JSON_OBJECT_INSTANCE * jsoninst, EVEL_INTERNAL_KEY *keyp)
355 {
356   EVEL_ENTER();
357
358   /***************************************************************************/
359   /* Check preconditions.                                                    */
360   /***************************************************************************/
361   assert(jsoninst != NULL);
362   assert(keyp != NULL);
363
364   EVEL_DEBUG("Adding jsonObject instance");
365
366   dlist_push_last(&jsoninst->object_keys, keyp);
367
368   EVEL_EXIT();
369 }
370
371 /**************************************************************************//**
372  * Free an internal key.
373  *
374  * Free off the internal key supplied.  Will free all the contained allocated memory.
375  *
376  *****************************************************************************/
377 void evel_free_internal_key(EVEL_INTERNAL_KEY * keyp)
378 {
379
380   EVEL_ENTER();
381
382   /***************************************************************************/
383   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
384   /* events as we do on the public API.                                      */
385   /***************************************************************************/
386   assert(keyp != NULL);
387
388   free(keyp->keyname);
389   evel_free_option_string(&keyp->keyvalue);
390   EVEL_EXIT();
391 }
392
393
394 /**************************************************************************//**
395  * Free an json object instance.
396  *
397  * Free off the json object instance supplied.
398  *  Will free all the contained allocated memory.
399  *
400  *****************************************************************************/
401 void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst)
402 {
403   EVEL_INTERNAL_KEY *other_field = NULL;
404
405   EVEL_ENTER();
406   assert(objinst != NULL);
407   assert(objinst->jsonstring != NULL);
408
409   free(objinst->jsonstring);
410
411   /***************************************************************************/
412   /* Free all internal internal keys
413   /***************************************************************************/
414   other_field = dlist_pop_last(&objinst->object_keys);
415   while (other_field != NULL)
416   {
417     EVEL_DEBUG("Freeing Object Instance Field (%s)",
418                other_field->keyname);
419     evel_free_internal_key(other_field);
420     other_field = dlist_pop_last(&objinst->object_keys);
421   }
422
423   EVEL_EXIT();
424 }
425
426 /**************************************************************************//**
427  * Free an json object.
428  *
429  * Free off the json object instance supplied.
430  *  Will free all the contained allocated memory.
431  *
432  *****************************************************************************/
433 void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj)
434 {
435   EVEL_JSON_OBJECT_INSTANCE *other_field = NULL;
436
437   EVEL_ENTER();
438   assert(jsobj != NULL);
439
440   free(jsobj->object_name);
441   evel_free_option_string(&jsobj->objectschema);
442   evel_free_option_string(&jsobj->objectschemaurl);
443   evel_free_option_string(&jsobj->nfsubscribedobjname);
444   evel_free_option_string(&jsobj->nfsubscriptionid);
445
446   /***************************************************************************/
447   /* Free all internal strings then the header itself.                       */
448   /***************************************************************************/
449   other_field = dlist_pop_last(&jsobj->jsonobjectinstances);
450   while (other_field != NULL)
451   {
452     EVEL_DEBUG("Freeing Object Instance Field (%s)",
453                other_field->jsonstring);
454     evel_free_jsonobjinst(other_field);
455     other_field = dlist_pop_last(&jsobj->jsonobjectinstances);
456   }
457
458   EVEL_EXIT();
459 }