Multi-ApplicationOnlineProfiling  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
jsonCache.c
Go to the documentation of this file.
1 #include "jsonCache.h"
2 
3 #include <string.h>
4 #include <errno.h>
5 #include <limits.h>
6 
7 /*
8  MAIN Json type definition
9  */
10 
11 
12 
13 void json_incref( json_t *json )
14 {
15  json_lock( json );
16 
17  json_incref_lf( json );
18 
19  json_unlock( json );
20 }
21 
22 
23 void json_decref( json_t *json )
24 {
25  json_lock( json );
26 
27  if( json_decref_lf( json ) )
28  json_unlock( json );
29 }
30 
32 {
33  /*
34  COMPUTE SIZE
35  */
36  size_t extra_type_size = 0;
37 
38  switch( type )
39  {
40  case JSON_NULL:
41  extra_type_size = sizeof( json_null_t );
42  break;
43  case JSON_BOOL:
44  extra_type_size = sizeof( json_bool_t );
45  break;
46  case JSON_STRING:
47  extra_type_size = sizeof( json_string_t );
48  break;
49  case JSON_INT:
50  extra_type_size = sizeof( json_int_t );
51  break;
52  case JSON_REAL:
53  extra_type_size = sizeof( json_real_t );
54  break;
55  case JSON_OBJECT:
56  extra_type_size = sizeof( json_object_t );
57  break;
58  case JSON_ARRAY:
59  extra_type_size = sizeof( json_array_t );
60  break;
62  printf("Warning : Unhandled JSON type...\n");
63  break;
64  }
65 
66  if( extra_type_size == 0 )
67  {
68  /* We put the default HERE */
69  return NULL;
70  }
71 
72  /*
73  ALLOCATE
74  */
75 
76  json_t * json = malloc( sizeof( json_t ) + extra_type_size );
77 
78  if (!json )
79  {
80  perror( "malloc" );
81  return NULL;
82  }
83 
84  /*
85  INIT CONTAINER
86  */
87 
88  json->type = type;
89  json->refcounter = 1;
90 
91  pthread_spin_init( &json->lock, 0 );
92 
93  return json;
94 }
95 
96 
97 void __json_t_release( json_t *json )
98 {
99  if( !json )
100  return;
101 
102  /*
103  CLEAN OBJECT
104  */
105 
106  switch( json->type )
107  {
108  case JSON_NULL:
109  json_null_destroy(json);
110  break;
111  case JSON_BOOL:
112  json_bool_destroy(json);
113  break;
114  case JSON_STRING:
115  json_string_destroy(json);
116  break;
117  case JSON_INT:
118  json_int_destroy(json);
119  break;
120  case JSON_REAL:
121  json_real_destroy(json);
122  break;
123  case JSON_OBJECT:
124  json_object_destroy(json);
125  break;
126  case JSON_ARRAY:
127  json_array_destroy(json);
128  break;
129  case JSON_SOMETHING_ELSE:
130  printf("Warning : Unhandled JSON type...\n");
131  break;
132  }
133 
134 
135  pthread_spin_destroy( &json->lock );
136 
137  free( json );
138 }
139 
140 
141 /*
142  BASIC Types
143  */
144 
146 {
147  json_t * ret = __json_t_init( JSON_NULL );
148  return ret;
149 }
150 
152 {
153 
154 }
155 
156 json_t * json_bool( int thruth )
157 {
158  json_t * ret = __json_t_init( JSON_BOOL );
159 
160  /* INIT PACKED */
161  json_bool_t * b = json_to_bool( ret );
162  b->value = thruth;
163 
164  return ret;
165 }
166 
168 {
169  json_bool_t * b = json_to_bool( json );
170  b->value = 255;
171 }
172 
173 json_t * json_string( char * string )
174 {
175  json_t * ret = __json_t_init( JSON_STRING );
176 
177  /* INIT PACKED */
178  json_string_t * s = json_to_string( ret );
179  s->value = strdup( string );
180 
181  return ret;
182 }
183 
184 json_t * json_string_l( char *string , int len )
185 {
186  json_t * ret = __json_t_init( JSON_STRING );
187 
188  /* INIT PACKED */
189  json_string_t * s = json_to_string( ret );
190 
191  s->value = malloc( len + 1 );
192 
193  if( ! s->value )
194  {
195  perror( "malloc" );
196  return NULL;
197  }
198 
199  memcpy( s->value , string, len );
200  s->value[ len ] = '\0';
201 
202  return ret;
203 }
204 
206 {
207  json_string_t * s = json_to_string( json );
208  free( s->value );
209  s->value = NULL;
210 }
211 
212 json_t * json_int( int64_t value )
213 {
214  json_t * ret = __json_t_init( JSON_INT );
215 
216  /* INIT PACKED */
217  json_int_t * i = json_to_int( ret );
218  i->value = value;
219 
220  return ret;
221 }
222 
224 {
225  json_int_t * i = json_to_int( json );
226  i->value = 0;
227 }
228 
229 json_t * json_real( double value )
230 {
231  json_t * ret = __json_t_init( JSON_REAL );
232 
233  /* INIT PACKED */
234  json_real_t * r = json_to_real( ret );
235  r->value = value;
236 
237  return ret;
238 }
239 
241 {
242  json_real_t * r = json_to_real( json );
243  r->value = 0.0;
244 }
245 
246 /*
247  CONTAINERS Types
248  */
249 
251 {
252  if( !strlen( key ) || !elem )
253  return NULL;
254 
255  struct ObjectHT_entry * ret = malloc( sizeof( struct ObjectHT_entry ) );
256 
257  if( !ret )
258  {
259  perror("malloc");
260  return NULL;
261  }
262 
263 
264  ret->key = strdup( key );
265 
266  json_incref_lf( elem );
267 
268  ret->elem = elem;
269  ret->prev = NULL;
270 
271  return ret;
272 }
273 
275 {
276  if( !ent )
277  return;
278 
280 
281  free( ent->key );
282  ent->key = NULL;
283 
284  json_decref( ent->elem );
285  ent->elem = NULL;
286 
287  free( ent );
288 }
289 
290 
291 
292 
294 {
295 
296  struct ObjectHT_entry *new = ObjectHT_entry_new( key, elem );
297 
298  if( !new )
299  return NULL;
300 
301  if( prev )
302  {
303  new->prev = prev;
304  }
305 
306  return new;
307 }
308 
309 
310 void ObjectHT_init( struct ObjectHT *ht, int pow2_size )
311 {
312  int size = 0;
313 
314  int i;
315  for( i = 0 ; i < pow2_size ; i++ )
316  size |= (0x1 << i );
317 
318  ht->pow2_size = pow2_size;
319 
320  ht->entries = calloc( sizeof( struct ObjectHT_entry *) , size );
321 
322  if( ! ht->entries )
323  {
324  perror("malloc");
325  abort();
326  }
327 
328  ht->size = size;
329 }
330 
331 
332 void ObjectHT_release( struct ObjectHT *ht )
333 {
334  int i;
335 
336  for( i = 0 ; i < ht->size ; i++ )
337  {
338  ObjectHT_entry_release( ht->entries[ i ] );
339  }
340 
341 
342  free( ht->entries );
343  ht->entries = NULL;
344  ht->size = 0;
345 
346 }
347 
348 static inline unsigned int hashString( char *s , int bit_width )
349 {
350  unsigned int ret = 0;
351  int i = 1;
352 
353  while( *s )
354  {
355  ret += *s;
356  ret ^= (*s << (((i++)%7) * 4));
357  s++;
358  }
359 
360  int dec = 32 - bit_width;
361 
362  ret += ret >> dec;
363  ret = (ret << dec) >> dec;
364 
365  return ret?ret-1:ret;
366 }
367 
368 static inline int same_string( char *a, char *b )
369 {
370  do
371  {
372  if( *a != *b )
373  return 0;
374 
375  a++;
376  b++;
377  }while( *a && *b );
378 
379  if( *a == *b )
380  return 1;
381  else
382  return 0;
383 
384 }
385 
386 
387 struct ObjectHT_entry * ObjectHT_get( struct ObjectHT *ht, char *key )
388 {
389  if( !key || !ht )
390  return NULL;
391 
392  unsigned int bucket = hashString( key , ht->pow2_size );
393 
394  struct ObjectHT_entry * ent = ht->entries[bucket];
395 
396  while( ent )
397  {
398 
399  if( same_string( ent->key, key ) )
400  return ent;
401 
402  ent = ent->prev;
403  }
404 
405  return NULL;
406 }
407 
408 
409 void ObjectHT_set( struct ObjectHT *ht, char *key, json_t * elem )
410 {
411  if( !elem || !ht || !key )
412  return;
413 
414  struct ObjectHT_entry *ent = ObjectHT_get( ht, key );
415 
416  if( ent )
417  {
418  json_decref( ent->elem );
419  json_incref_lf( elem );
420  ent->elem = elem;
421  }
422  else
423  {
424  unsigned int bucket = hashString( key , ht->pow2_size );
425  ht->entries[bucket] = ObjectHT_entry_push( ht->entries[bucket], key, elem );
426  }
427 }
428 
429 struct ObjectHT_entry * __ObjectHT_delete( struct ObjectHT_entry *ent, char *key, int did_delete )
430 {
431  if( !ent )
432  return NULL;
433 
434  if( did_delete )
435  return ent;
436 
437  /* We could speedup this using a DL list... */
438  if( same_string( ent->key, key ) )
439  {
440  struct ObjectHT_entry * ret = __ObjectHT_delete( ent->prev, key, 1 );
441 
442  json_decref( ent->elem );
443  free( ent->key );
444  free( ent );
445 
446  return ret;
447  }
448 
449  struct ObjectHT_entry * ret = __ObjectHT_delete( ent->prev, key, 0 );
450 
451  if( ret != ent->prev )
452  {
453  ent->prev = ret;
454  }
455 
456  return ent;
457 }
458 
459 
460 
461 void ObjectHT_delete( struct ObjectHT *ht, char *key )
462 {
463  unsigned int bucket = hashString( key , ht->pow2_size );
464  ht->entries[ bucket ] = __ObjectHT_delete( ht->entries[ bucket ], key, 0 );
465 }
466 
467 
469 {
470  json_t * ret = __json_t_init( JSON_OBJECT );
471 
472  /* INIT PACKED */
473  json_object_t * o = json_to_object( ret );
474 
475  ObjectHT_init( &o->ht, 13 );
476 
477  return ret;
478 }
479 
481 {
482  json_object_t * o = json_to_object( json );
483 
484  ObjectHT_release( &o->ht );
485 }
486 
488 {
489  json_object_t * o = json_to_object( json );
490 
491  json_lock( json );
492 
493  ObjectHT_set( &o->ht, key, elem );
494 
495  json_unlock( json );
496 
497  return elem;
498 }
499 
500 json_t * json_object_get( json_t * json, char *key )
501 {
502  json_object_t * o = json_to_object( json );
503 
504  json_t *ret = NULL;
505 
506  json_lock( json );
507 
508  struct ObjectHT_entry *ent = ObjectHT_get( &o->ht, key );
509 
510  ret = ent?ent->elem:NULL;
511 
512  if( ret )
513  json_incref( ret );
514 
515  json_unlock( json );
516 
517  return ret;
518 }
519 
521 {
522  json_object_t * o = json_to_object( json );
523 
524  json_lock( json );
525 
526  ObjectHT_delete( &o->ht, key );
527 
528  json_unlock( json );
529 
530  return json;
531 }
532 
533 
534 
535 /*
536  ARRAY
537  */
538 
539 
541 {
542  json_t * ret = __json_t_init( JSON_ARRAY );
543 
544  /* INIT PACKED */
545  json_array_t * a = json_to_array( ret );
546 
547  a->content = NULL;
548  a->size = 0;
549 
550  return ret;
551 }
552 
553 int json_array_guarantee( json_array_t *a, unsigned int offset, int count )
554 {
555  if( count == 0 )
556  return 0;
557 
558  size_t overflow = 0;
559 
560  if( a->size < offset )
561  overflow = offset - a->size;
562 
563  a->content = realloc( a->content, (a->size + count + overflow) * sizeof( json_t * ) );
564 
565  if( !a->content )
566  {
567  perror("realloc");
568  return 1;
569  }
570 
571  if( overflow )
572  {
573  /* PAD the array with NULL values */
574  int i;
575  for( i = a->size; i < offset; i++ )
576  {
577  a->content[i] = json_null();
578  }
579  }
580 
581 
582  if( offset < a->size )
583  {
584  memmove( a->content + offset + count , a->content + offset, (a->size - offset) * sizeof( json_t * ) );
585  }
586 
587  a->size += count + overflow;
588 
589  return 0;
590 }
591 
592 json_t * json_array_push_at(json_t *json, unsigned int offset, json_t * elem)
593 {
594  json_incref_lf( elem );
595 
596  json_lock( json );
597 
598  json_array_t *array = json_to_array( json );
599 
600  if( json_array_guarantee( array, offset, 1 ) )
601  return NULL;
602 
603  array->content[ offset ] = elem;
604 
605  json_unlock( json );
606 
607  return elem;
608 }
609 
611 {
612  json_array_t *array = json_to_array( json );
613  return json_array_push_at(json, array->size, elem);
614 }
615 
616 
617 
618 json_t * json_array_get( json_t *json, unsigned int offset )
619 {
620  json_t * ret = NULL;
621 
622  json_array_t *array = json_to_array( json );
623 
624  if( array->size <= offset )
625  return ret;
626 
627  json_lock( json );
628  ret = array->content[ offset ];
629  json_incref( ret );
630  json_unlock( json );
631 
632  return ret;
633 }
634 
635 json_t * json_array_set( json_t *json, unsigned int offset , json_t * elem)
636 {
637  json_array_t *array = json_to_array( json );
638 
639  if( array->size <= offset )
640  return NULL;
641 
642  json_incref_lf( elem );
643 
644  json_lock( json );
645 
646  json_decref( array->content[ offset ] );
647  array->content[ offset ] = elem;
648 
649  json_unlock( json );
650 
651  return elem;
652 }
653 
654 
655 json_t * json_array_del( json_t *json, unsigned int offset )
656 {
657  json_array_t *array = json_to_array( json );
658 
659  if( array->size <= offset )
660  return NULL;
661 
662  json_lock( json );
663 
664  json_decref( array->content[offset] );
665  array->content[offset] = NULL;
666 
667  if( array->size == 1 )
668  {
669  free( array->content );
670  array->content = NULL;
671  array->size = 0;
672 
673  json_unlock( json );
674  return json;
675  }
676  else
677  {
678  if( offset < (array->size - 1) )
679  {
680  memmove( &array->content[offset], &array->content[offset + 1], (array->size - offset ) * sizeof( json_t * ) );
681  }
682 
683  array->content = realloc( array->content, (array->size - 1) * sizeof( json_t * ) );
684 
685  if( !array->content )
686  {
687  perror("realloc");
688  abort();
689  }
690  }
691 
692  array->size--;
693 
694  json_unlock( json );
695 
696  return json;
697 }
698 
699 
701 {
702  json_array_t * array = json_to_array( json );
703 
704  int i;
705 
706  for( i = 0 ; i < array->size ; i++ )
707  json_decref( array->content[i] );
708 
709  free( array->content );
710  array->content = NULL;
711 
712  array->size = 0;
713 
714 }
715 
716 /*
717  Dumping
718  */
719 
721 {
722  char *s;
723  size_t len;
724  size_t buff_len;
725 };
726 
727 void string_buff_init( struct string_buff * sb )
728 {
729  sb->s = NULL;
730  sb->len = 0;
731  sb->buff_len = 1024*1024;
732 }
733 
734 void string_buff_release( struct string_buff * sb )
735 {
736  free( sb->s );
737  string_buff_init( sb );
738 }
739 
740 
741 void string_buff_push( struct string_buff * sb, char * s )
742 {
743  if( !s || !sb)
744  return;
745 
746  int len = strlen( s );
747 
748  if( !len )
749  return;
750 
751  while( sb->buff_len <= sb->len + len + 1 )
752  {
753  sb->buff_len *= 2;
754  }
755 
756  sb->s = realloc( sb->s, sb->buff_len );
757 
758  if( !sb->s )
759  {
760  perror("realloc");
761  abort();
762  }
763 
764  memcpy( sb->s + sb->len , s, len + 1 );
765 
766  sb->len += len;
767 }
768 
769 
770 char * c_newline( newline )
771 {
772  if( newline )
773  return "\n";
774  else
775  return "";
776 }
777 
778 void stream_indent( char *tmp_buff, struct string_buff *out, int depth )
779 {
780  int i;
781  tmp_buff[0] = '\0';
782 
783  for( i = 0 ; i < depth && i < 4095 ; i++)
784  tmp_buff[i] = '\t';
785 
786  tmp_buff[depth] = '\0';
787  string_buff_push( out, tmp_buff );
788 }
789 
790 
791 void __json_dump( char *tmp_buff, struct string_buff *out, json_t * json, int depth, int indent, int newline, int lock )
792 {
793  if( !json )
794  return;
795 
796  int i;
797 
798  if( indent )
799  {
800  stream_indent( tmp_buff, out, depth );
801  }
802 
803  if( lock )
804  json_lock( json );
805 
806 
807  switch( json->type )
808  {
809  case JSON_NULL:
810  string_buff_push( out, " null " );
811  break;
812  case JSON_BOOL:
813 
814  snprintf( tmp_buff, 4096, " %s ", json_to_bool( json )->value?"true":"false" );
815  string_buff_push( out, tmp_buff );
816  break;
817  case JSON_STRING:
818  string_buff_push( out, " \"" );
819  snprintf( tmp_buff, 4096, "%s", json_to_string( json )->value );
820  string_buff_push( out, tmp_buff );
821  string_buff_push( out, "\" " );
822  break;
823  case JSON_INT:
824  snprintf( tmp_buff, 4096, " %ld ", json_to_int( json )->value );
825  string_buff_push( out, tmp_buff );
826  break;
827  case JSON_REAL:
828  snprintf( tmp_buff, 4096, " %g ", json_to_real( json )->value );
829  string_buff_push( out, tmp_buff );
830  break;
831  case JSON_OBJECT:
832  /* OPEN OBJECT */
833  snprintf( tmp_buff, 4096, " {%s", c_newline( newline ) );
834  string_buff_push( out, tmp_buff );
835 
836  /* DUMP OBJECT */
837 
838  /*
839  * This strange do while loop is made in order to put the comas
840  * at the right places as we do not have a counter but
841  * only an iterator.
842  */
843 
845 
846  json_object_iterator_init( &it, json );
847 
848  int is_first = 0;
849  int cont = 0;
850 
851  do
852  {
853  if( is_first != 0 )
854  {
855  /* WRITE KEY */
856  snprintf( tmp_buff, 4096, " \"%s\" : %s", json_object_iterator_key( &it ), c_newline( newline ) );
857  string_buff_push( out, tmp_buff );
858  /* WRITE ENTITY */
859  __json_dump( tmp_buff, out, json_object_iterator_elem( &it ), depth + 1 , indent, newline, lock );
860  is_first++;
861  }
862  else
863  {
864  is_first++;
865  }
866 
867  cont = json_object_iterator_next( &it );
868 
869  /* IF AN ENTRY FOLLOWS */
870  if( cont /* NO COMA FOR THE LAST */
871  && is_first != 1 /* NO COMA FOR THE FIRST DUMMY*/)
872  {
873  snprintf( tmp_buff, 4096, ",%s", c_newline( newline ) );
874  string_buff_push( out, tmp_buff );
875  }
876 
877  }while( cont );
878 
879 
880  /* SUGAR NEWLINE AND INDENT */
881  snprintf( tmp_buff, 4096, "%s", c_newline( newline ) );
882  string_buff_push( out, tmp_buff );
883 
884  if( indent )
885  {
886  stream_indent( tmp_buff, out, depth );
887  }
888 
889  /* CLOSE OBJECT */
890  snprintf( tmp_buff, 4096, "} ");
891  string_buff_push( out, tmp_buff );
892 
893  break;
894  case JSON_ARRAY:
895  /* OPEN ARRAY */
896  snprintf( tmp_buff, 4096, " [%s", c_newline( newline ) );
897  string_buff_push( out, tmp_buff );
898 
899  /* DUMP ARRAY */
900  json_array_t *a = json_to_array( json );
901 
902  for( i = 0 ; i < a->size; i++ )
903  {
904  /* WRITE ENTITY */
905  __json_dump( tmp_buff, out, a->content[i], depth + 1 , indent, newline, lock );
906 
907  /* CLOSE ENTRY */
908  if( i != ( a->size - 1 ) )
909  {
910  snprintf( tmp_buff, 4096, ",%s", c_newline( newline ) );
911  string_buff_push( out, tmp_buff );
912  }
913  }
914 
915  /* SUGAR NEWLINE AND INDENT */
916  snprintf( tmp_buff, 4096, "%s", c_newline( newline ) );
917  string_buff_push( out, tmp_buff );
918 
919  if( indent )
920  {
921  stream_indent( tmp_buff, out, depth );
922  }
923 
924  /* CLOSE ARRAY */
925  snprintf( tmp_buff, 4096, "] ");
926  string_buff_push( out, tmp_buff );
927  break;
928  case JSON_SOMETHING_ELSE:
929  printf("Warning : Unhandled JSON type...\n");
930  break;
931  }
932 
933  if( lock )
934  json_unlock( json );
935 }
936 
937 
938 char * json_dump( json_t * json, json_format mode )
939 {
940  char *tmp_buff = malloc( 4096 );
941 
942  if( !tmp_buff )
943  {
944  perror( "malloc" );
945  return NULL;
946  }
947 
948  struct string_buff out;
949  string_buff_init( &out );
950 
951  int indent;
952  int newline;
953 
954  if( mode & JSON_COMPACT )
955  {
956  indent = 0;
957  newline = 0;
958  }
959  else
960  {
961  indent = 1;
962  newline = 1;
963  }
964 
965  int lock = 1;
966 
967  if( mode & JSON_NO_LOCK )
968  lock = 0;
969 
970 
971  __json_dump( tmp_buff, &out, json, 0, indent, newline, lock );
972 
973 
974  free( tmp_buff );
975 
976  return out.s;
977 }
978 
979 
980 void json_dump_f(FILE * f, json_t * json, json_format mode )
981 {
982  char * dump = json_dump( json, mode );
983 
984  fprintf( f, "%s" , dump );
985 
986  free( dump );
987 }
988 
989 
990 /*
991  PARSING
992  */
993 
994 int is_alphanumeric( char * c )
995 {
996  if( !c )
997  return 0;
998 
999 
1000  if( 'a' <= *c && *c <= 'z' )
1001  return 1;
1002 
1003  if( 'A' <= *c && *c <= 'Z' )
1004  return 1;
1005 
1006  if( '0' <= *c && *c <= '9' )
1007  return 1;
1008 
1009  return 0;
1010 }
1011 
1012 int is_numeric( char * c )
1013 {
1014  if( !c )
1015  return 0;
1016 
1017  if( '0' <= *c && *c <= '9' )
1018  return 1;
1019 
1020  return 0;
1021 }
1022 
1023 
1024 int pad_buff( char **buff, char expect )
1025 {
1026 
1027  char *s = *buff;
1028 
1029  while( *s && *s != expect )
1030  {
1031 
1032  if( *s != ' ' && *s != '\n' && *s != '\t' )
1033  {
1034  *buff = s;
1035  return 1;
1036  }
1037 
1038 
1039  s++;
1040  }
1041 
1042  *buff = s;
1043 
1044  return 0;
1045 }
1046 
1047 
1048 char * parse_string( char ** json_string )
1049 {
1050  char *s = *json_string;
1051 
1052  /* First quote */
1053  if( pad_buff( &s, '"' ) )
1054  return NULL;
1055 
1056  s++;
1057 
1058  char *string_start = s;
1059 
1060  int skip_next_quote = 0;
1061 
1062  /* Second quote */
1063  while( (*s != '"' || skip_next_quote ) && *s )
1064  {
1065 
1066  if( *s == '\\' )
1067  skip_next_quote = 1;
1068 
1069  if( skip_next_quote )
1070  skip_next_quote = 0;
1071 
1072  s++;
1073  }
1074 
1075  if( *s != '"' )
1076  return NULL;
1077 
1078  *s = '\0';
1079 
1080  *json_string = s + 1;
1081 
1082  return string_start;
1083 }
1084 
1085 
1086 int is_true( char *s )
1087 {
1088  if( *s == 't' || *s == 'T')
1089  {
1090  if( *(s + 1 ) == 'r' || *(s + 1 ) == 'R' )
1091  {
1092  if( *(s + 2 ) == 'u' || *(s + 2 ) == 'U' )
1093  {
1094  if( *(s + 3 ) == 'e' || *(s + 3 ) == 'E' )
1095  {
1096  return 1;
1097  }
1098  }
1099  }
1100  }
1101 
1102  return 0;
1103 }
1104 
1105 int is_false( char *s )
1106 {
1107 
1108  if( *s == 'f' || *s == 'F')
1109  {
1110  if( *(s + 1 ) == 'a' || *(s + 1 ) == 'A' )
1111  {
1112  if( *(s + 2 ) == 'l' || *(s + 2 ) == 'L' )
1113  {
1114  if( *(s + 3 ) == 's' || *(s + 3 ) == 'S' )
1115  {
1116  if( *(s + 4 ) == 'e' || *(s + 4 ) == 'E' )
1117  {
1118  return 1;
1119  }
1120  }
1121  }
1122  }
1123  }
1124 
1125  return 0;
1126 }
1127 
1128 int is_null( char *s )
1129 {
1130 
1131  if( *s == 'n' || *s == 'N')
1132  {
1133  if( *(s + 1 ) == 'u' || *(s + 1 ) == 'U' )
1134  {
1135  if( *(s + 2 ) == 'l' || *(s + 2 ) == 'L' )
1136  {
1137  if( *(s + 3 ) == 'l' || *(s + 3 ) == 'L' )
1138  {
1139  return 1;
1140  }
1141  }
1142  }
1143  }
1144 
1145  return 0;
1146 }
1147 
1148 
1149 int json_infer_type( char * ent )
1150 {
1151  char *s = ent;
1152 
1153  while( *s )
1154  {
1155  if( *s == ',' || *s == '}' || *s == ']' )
1156  return JSON_NULL;
1157 
1158  if( is_null( s ) )
1159  return JSON_NULL;
1160 
1161  if( *s == '"' )
1162  return JSON_STRING;
1163 
1164  if( *s == '{' )
1165  return JSON_OBJECT;
1166 
1167  if( *s == '[' )
1168  return JSON_ARRAY;
1169 
1170  if( is_numeric( s ) )
1171  {
1172  while( *s && *s != '}' && *s != ']' && *s != ',' )
1173  {
1174  if( *s == 'e' || *s == 'E' || *s == '.' )
1175  return JSON_REAL;
1176 
1177  s++;
1178  }
1179 
1180  return JSON_INT;
1181  }
1182 
1183 
1184  if( is_true( s ) || is_false( s ) )
1185  return JSON_BOOL;
1186 
1187  s++;
1188  }
1189 
1190  return JSON_SOMETHING_ELSE;
1191 }
1192 
1193 
1194 json_t * json_parse_int( char ** buff )
1195 {
1196  char *s = *buff;
1197 
1198  pad_buff( &s, '\0' );
1199 
1200  char * begin = s;
1201 
1202  while( *s && *s != ',' && *s != ']' && *s != '}' )
1203  {
1204  s++;
1205  }
1206 
1207  char end_char = *s;
1208  *s = '\0';
1209 
1210  char *end = NULL;
1211  errno = 0;
1212  long int val = strtoll( begin , &end, 10);
1213 
1214  if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
1215  || (errno != 0 && val == 0)) {
1216  perror("strtol");
1217  return NULL;
1218  }
1219 
1220  if( end == begin )
1221  return NULL;
1222 
1223  *s = end_char;
1224 
1225  return json_int( val );
1226 }
1227 
1228 json_t * json_parse_real( char ** buff )
1229 {
1230  char *s = *buff;
1231 
1232  pad_buff( &s, '\0' );
1233 
1234  char * begin = s;
1235 
1236  while( *s && *s != ',' && *s != ']' && *s != '}' )
1237  {
1238  s++;
1239  }
1240 
1241  char end_char = *s;
1242  *s = '\0';
1243 
1244  char *end = NULL;
1245  errno = 0;
1246  long double val = strtold(begin, &end);
1247 
1248  if ((errno == ERANGE ) || (errno != 0 && val == 0.0)) {
1249  perror("strtold");
1250  return NULL;
1251  }
1252 
1253  if( end == begin )
1254  return NULL;
1255 
1256 
1257  *s = end_char;
1258 
1259  return json_real( val );
1260 }
1261 
1262 
1263 json_t * json_parse_string( char ** buff )
1264 {
1265  char * string = parse_string( buff );
1266 
1267  if( !string )
1268  return NULL;
1269 
1270  return json_string( string );
1271 }
1272 
1273 
1275 {
1276  char *s = *json_string;
1277 
1278  pad_buff( &s, '\0' );
1279 
1280  if( is_true( s ) )
1281  {
1282  *json_string += 4;
1283  return json_bool( 1 );
1284  }
1285  else
1286  {
1287  if( is_false( s ) )
1288  {
1289  *json_string += 5;
1290  return json_bool( 0 );
1291  }
1292  }
1293 
1294 
1295  return json_null();
1296 }
1297 
1298 
1300 {
1301  char *s = *json_string;
1302 
1303  if( pad_buff( &s, '[' ) )
1304  {
1305  return NULL;
1306  }
1307 
1308  if( *s != '[' )
1309  {
1310  return NULL;
1311  }
1312 
1313 
1314  s++;
1315 
1316 
1317  json_t *ret = json_array();
1318 
1319  while( *s && *s != ']' )
1320  {
1321  json_t *elem = _json_parse( &s );
1322 
1323  if( !elem )
1324  {
1325  goto json_parse_array_error;
1326  }
1327 
1328  json_lock( elem );
1329 
1330  json_array_push( ret, elem );
1331 
1332  json_decref_lf( elem );
1333 
1334  json_unlock( elem );
1335 
1336  while( *s && *s != ',' && *s != ']' )
1337  s++;
1338 
1339  if( *s == ']' )
1340  break;
1341 
1342  if( !(*s) )
1343  break;
1344 
1345  s++;
1346  }
1347 
1348 
1349  if( pad_buff( &s, ']' ) )
1350  {
1351  goto json_parse_array_error;
1352  }
1353 
1354  if( *s != ']' )
1355  {
1356  goto json_parse_array_error;
1357  }
1358 
1359  *json_string = s + 1;
1360 
1361  return ret;
1362 
1363 json_parse_array_error:
1364  json_decref( ret );
1365  return NULL;
1366 }
1367 
1368 
1369 
1370 char * json_parse_key ( char ** json_string )
1371 {
1372  char *key = parse_string( json_string );
1373 
1374  /* SKIP Key separator */
1375 
1376  char * s = *json_string;
1377 
1378  if( pad_buff( &s, ':' ) )
1379  {
1380  return NULL;
1381  }
1382 
1383  if( *s != ':' )
1384  {
1385  return NULL;
1386  }
1387 
1388  *json_string = s + 1;
1389 
1390  return key;
1391 }
1392 
1393 
1394 
1396 {
1397  char *s = *json_string;
1398 
1399  if( pad_buff( &s, '{' ) )
1400  {
1401  return NULL;
1402  }
1403 
1404  if( *s != '{' )
1405  return NULL;
1406 
1407  s++;
1408 
1409  json_t *ret = json_object();
1410 
1411  while( *s != '}' && *s)
1412  {
1413  //printf("KEY : " );
1414 
1415  char * key = json_parse_key( &s );
1416 
1417  if( !key )
1418  {
1419  goto json_parse_object_error;
1420  }
1421 
1422  json_t *elem = _json_parse( &s );
1423 
1424  if( !elem )
1425  {
1426  //printf("NO ELEM\n");
1427  goto json_parse_object_error;
1428  }
1429 
1430  json_lock( elem );
1431 
1432  json_object_set( ret, key, elem );
1433 
1434  json_decref_lf( elem );
1435 
1436  json_unlock( elem );
1437 
1438 
1439 
1440  while( *s && *s != ',' && *s != '}' )
1441  s++;
1442 
1443  if( *s == '}' )
1444  break;
1445 
1446  if( !(*s) )
1447  break;
1448 
1449  s++;
1450  }
1451 
1452  if( *s != '}' )
1453  {
1454  goto json_parse_object_error;
1455  }
1456 
1457  *json_string = s + 1;
1458 
1459  return ret;
1460 
1461 json_parse_object_error:
1462  json_decref( ret );
1463  return NULL;
1464 }
1465 
1466 
1467 
1468 
1469 json_t * _json_parse( char ** buff )
1470 {
1471 
1472  if( *buff == '\0' )
1473  return NULL;
1474 
1475  switch( json_infer_type( *buff ) )
1476  {
1477  case JSON_NULL :
1478  //printf("NULL\n");
1479  return json_null();
1480  case JSON_BOOL:
1481  return json_parse_bool( buff );
1482  case JSON_STRING:
1483  //printf("STRING : ");
1484  return json_parse_string( buff );
1485  case JSON_INT:
1486  //printf("INT\n");
1487  return json_parse_int( buff );
1488  case JSON_REAL:
1489  //printf("REAL\n");
1490  return json_parse_real( buff );
1491  case JSON_OBJECT:
1492  //printf("OBJECT\n");
1493  return json_parse_object( buff );
1494  case JSON_ARRAY:
1495  //printf("ARRAY\n");
1496  return json_parse_array( buff );
1497  case JSON_SOMETHING_ELSE:
1498  return NULL;
1499  }
1500 
1501  return NULL;
1502 }
1503 
1504 json_t * json_parse( char * json )
1505 {
1506  char * tmp = strdup( json );
1507 
1508  char *s = tmp;
1509 
1510  json_t *ret =_json_parse( &s );
1511 
1512  free( tmp );
1513 
1514  return ret;
1515 }
1516 
1517 /*
1518  CACHE Implementation
1519  */
1520 
1521 
1522 void jsonCache_init( struct jsonCache *c, void (*set_handler)( char *, json_t *, void *), void (*delete_handler)( char *, void *), void *ctx )
1523 {
1524  c->cache = json_object();
1525  c->set_handler = set_handler;
1526  c->delete_handler = delete_handler;
1527  c->ctx = ctx;
1528 }
1529 
1530 
1531 void jsonCache_release( struct jsonCache *c )
1532 {
1533  json_decref( c->cache );
1534  c->cache = NULL;
1535  c->set_handler = NULL;
1536  c->delete_handler = NULL;
1537 }
1538 
1539 json_t * jsonCache_get( struct jsonCache *c, char *key )
1540 {
1541  if( !c->cache )
1542  {
1543  printf("ERROR : There is no cache !\n");
1544  abort();
1545  }
1546 
1547  return json_object_get( c->cache, key );
1548 }
1549 
1550 void _jsonCache_delete( struct jsonCache *c, char *key, int docommit )
1551 {
1552  if( !c->cache )
1553  {
1554  printf("ERROR : There is no cache !\n");
1555  abort();
1556  }
1557 
1558  json_object_delete( c->cache, key );
1559 
1560  if( c->delete_handler && docommit )
1561  (c->delete_handler)( key, c->ctx );
1562 }
1563 
1564 
1565 void jsonCache_delete( struct jsonCache *c, char *key )
1566 {
1567  _jsonCache_delete( c, key, 1 );
1568 }
1569 
1570 void jsonCache_delete_nocommit( struct jsonCache *c, char *key )
1571 {
1572  printf("==> Delete %s\n", key );
1573  _jsonCache_delete( c, key, 0 );
1574 }
1575 
1576 
1577 
1578 void jsonCache_commit( struct jsonCache *c, char *key )
1579 {
1580  if( !c->set_handler )
1581  return;
1582 
1583  json_t * elem = jsonCache_get( c, key );
1584 
1585  if( elem )
1586  {
1587  (c->set_handler)( key, elem, c->ctx );
1588  json_decref( elem );
1589  }
1590 }
1591 
1592 
1593 void _jsonCache_set( struct jsonCache *c, char *key, json_t * elem, int do_commit )
1594 {
1595  if( !c->cache )
1596  {
1597  printf("ERROR : There is no cache !\n");
1598  abort();
1599  }
1600 
1601  if( !elem )
1602  {
1603  printf("Warning : No element provided !\n");
1604  return;
1605  }
1606 
1607  json_lock( elem );
1608 
1609  json_object_set( c->cache, key, elem );
1610 
1611  if( c->set_handler && do_commit )
1612  (c->set_handler)( key, elem, c->ctx );
1613 
1614  json_unlock( elem );
1615 
1616 
1617 }
1618 
1619 void jsonCache_set( struct jsonCache *c, char *key, json_t * elem )
1620 {
1621  _jsonCache_set( c, key, elem, 1 );
1622 }
1623 
1624 
1625 void jsonCache_set_nocommit( struct jsonCache *c, char *key, json_t * elem )
1626 {
1627  _jsonCache_set( c, key, elem, 0 );
1628 }
1629 
1630 
1631 void _jsonCache_set_json( struct jsonCache *c, char *key, char *json, int do_commit )
1632 {
1633  if( !c->cache || !json )
1634  return;
1635 
1636  json_t * elem = json_parse( json );
1637 
1638  if( !elem )
1639  {
1640  return;
1641  }
1642 
1643  _jsonCache_set( c, key, elem, do_commit );
1644 
1645  json_decref( elem );
1646 }
1647 
1648 void jsonCache_set_json( struct jsonCache *c, char *key, char *json )
1649 {
1650  _jsonCache_set_json( c, key, json, 1 );
1651 }
1652 
1653 void jsonCache_set_json_nocommit( struct jsonCache *c, char *key, char *json )
1654 {
1655  _jsonCache_set_json( c, key, json, 0 );
1656 }
1657 
1658 
1659 
1660 char * jsonCache_json( struct jsonCache *c, char *key, json_format mode )
1661 {
1662  json_t *elem = jsonCache_get( c, key );
1663 
1664  if( !elem )
1665  return "{}";
1666 
1667  return json_dump( elem , mode );
1668 }
1669 
1670 
1671 
1672 
void jsonCache_set(struct jsonCache *c, char *key, json_t *elem)
Definition: jsonCache.c:1619
json_t * json_parse_array(char **json_string)
Definition: jsonCache.c:1299
enum json_type_e json_type
void _jsonCache_set(struct jsonCache *c, char *key, json_t *elem, int do_commit)
Definition: jsonCache.c:1593
static void json_unlock(json_t *json)
Definition: jsonCache.h:47
void jsonCache_delete(struct jsonCache *c, char *key)
Definition: jsonCache.c:1565
json_t * json_object_get(json_t *json, char *key)
Definition: jsonCache.c:500
int json_infer_type(char *ent)
Definition: jsonCache.c:1149
json_t * json_string(char *string)
Definition: jsonCache.c:173
size_t len
Definition: jsonCache.c:723
void _jsonCache_delete(struct jsonCache *c, char *key, int docommit)
Definition: jsonCache.c:1550
int is_false(char *s)
Definition: jsonCache.c:1105
void ObjectHT_entry_release(struct ObjectHT_entry *ent)
Definition: jsonCache.c:274
struct ObjectHT ht
Definition: jsonCache.h:192
void jsonCache_set_json(struct jsonCache *c, char *key, char *json)
Definition: jsonCache.c:1648
json_t * json_array_del(json_t *json, unsigned int offset)
Definition: jsonCache.c:655
void * ctx
Definition: jsonCache.h:366
json_t * json_parse_object(char **json_string)
Definition: jsonCache.c:1395
struct ObjectHT_entry ** entries
Definition: jsonCache.h:175
char * json_parse_key(char **json_string)
Definition: jsonCache.c:1370
struct json_real_s json_real_t
json_t * json_int(int64_t value)
Definition: jsonCache.c:212
struct json_null_s json_null_t
struct ObjectHT_entry * ObjectHT_get(struct ObjectHT *ht, char *key)
Definition: jsonCache.c:387
size_t size
Definition: jsonCache.h:176
json_t * __json_t_init(json_type type)
Definition: jsonCache.c:31
void json_bool_destroy(json_t *json)
Definition: jsonCache.c:167
char * s
Definition: jsonCache.c:722
void jsonCache_init(struct jsonCache *c, void(*set_handler)(char *, json_t *, void *), void(*delete_handler)(char *, void *), void *ctx)
Definition: jsonCache.c:1522
#define json_to_array(a)
Definition: jsonCache.h:238
#define json_to_int(a)
Definition: jsonCache.h:235
void __json_t_release(json_t *json)
Definition: jsonCache.c:97
static void json_object_iterator_init(json_object_iterator *it, json_t *json)
Definition: jsonCache.h:252
void json_string_destroy(json_t *json)
Definition: jsonCache.c:205
void json_array_destroy(json_t *json)
Definition: jsonCache.c:700
int64_t value
Definition: jsonCache.h:140
void json_decref(json_t *json)
Definition: jsonCache.c:23
double value
Definition: jsonCache.h:152
static void json_lock(json_t *json)
Definition: jsonCache.h:38
char * value
Definition: jsonCache.h:127
json_t * json_null()
Definition: jsonCache.c:145
size_t refcounter
Definition: jsonCache.h:32
json_t * json_array_push_at(json_t *json, unsigned int offset, json_t *elem)
Definition: jsonCache.c:592
json_t * json_array_set(json_t *json, unsigned int offset, json_t *elem)
Definition: jsonCache.c:635
static int json_decref_lf(json_t *json)
Definition: jsonCache.h:78
void __json_dump(char *tmp_buff, struct string_buff *out, json_t *json, int depth, int indent, int newline, int lock)
Definition: jsonCache.c:791
#define json_to_real(a)
Definition: jsonCache.h:236
int is_numeric(char *c)
Definition: jsonCache.c:1012
void json_dump_f(FILE *f, json_t *json, json_format mode)
Definition: jsonCache.c:980
json_t * json_bool(int thruth)
Definition: jsonCache.c:156
struct ObjectHT_entry * ObjectHT_entry_push(struct ObjectHT_entry *prev, char *key, json_t *elem)
Definition: jsonCache.c:293
static void json_incref_lf(json_t *json)
Definition: jsonCache.h:69
size_t buff_len
Definition: jsonCache.c:724
struct ObjectHT_entry * prev
Definition: jsonCache.h:170
int pow2_size
Definition: jsonCache.h:177
void jsonCache_commit(struct jsonCache *c, char *key)
Definition: jsonCache.c:1578
struct json_bool_s json_bool_t
json_format
Definition: jsonCache.h:332
json_t * elem
Definition: jsonCache.h:168
json_type type
Definition: jsonCache.h:31
void _jsonCache_set_json(struct jsonCache *c, char *key, char *json, int do_commit)
Definition: jsonCache.c:1631
char * key
Definition: jsonCache.h:167
void ObjectHT_delete(struct ObjectHT *ht, char *key)
Definition: jsonCache.c:461
int is_alphanumeric(char *c)
Definition: jsonCache.c:994
void jsonCache_set_json_nocommit(struct jsonCache *c, char *key, char *json)
Definition: jsonCache.c:1653
json_t * json_object_set(json_t *json, char *key, json_t *elem)
Definition: jsonCache.c:487
struct json_array_s json_array_t
static int same_string(char *a, char *b)
Definition: jsonCache.c:368
struct json_string_s json_string_t
struct ObjectHT_entry * ObjectHT_entry_new(char *key, json_t *elem)
Definition: jsonCache.c:250
void jsonCache_release(struct jsonCache *c)
Definition: jsonCache.c:1531
void string_buff_release(struct string_buff *sb)
Definition: jsonCache.c:734
struct json_object_s json_object_t
struct ObjectHT_entry * __ObjectHT_delete(struct ObjectHT_entry *ent, char *key, int did_delete)
Definition: jsonCache.c:429
json_t * jsonCache_get(struct jsonCache *c, char *key)
Definition: jsonCache.c:1539
json_t * json_parse_real(char **buff)
Definition: jsonCache.c:1228
json_t * json_object()
Definition: jsonCache.c:468
json_t * json_array_get(json_t *json, unsigned int offset)
Definition: jsonCache.c:618
int pad_buff(char **buff, char expect)
Definition: jsonCache.c:1024
void stream_indent(char *tmp_buff, struct string_buff *out, int depth)
Definition: jsonCache.c:778
int is_true(char *s)
Definition: jsonCache.c:1086
pthread_spinlock_t lock
Definition: jsonCache.h:34
json_t * json_parse(char *json)
Definition: jsonCache.c:1504
json_t * json_string_l(char *string, int len)
Definition: jsonCache.c:184
void ObjectHT_release(struct ObjectHT *ht)
Definition: jsonCache.c:332
#define json_to_bool(a)
Definition: jsonCache.h:233
#define json_to_string(a)
Definition: jsonCache.h:234
size_t size
Definition: jsonCache.h:211
int is_null(char *s)
Definition: jsonCache.c:1128
char * json_dump(json_t *json, json_format mode)
Definition: jsonCache.c:938
void ObjectHT_init(struct ObjectHT *ht, int pow2_size)
Definition: jsonCache.c:310
json_t * json_parse_int(char **buff)
Definition: jsonCache.c:1194
void(* delete_handler)(char *, void *)
Definition: jsonCache.h:365
void json_object_destroy(json_t *json)
Definition: jsonCache.c:480
void jsonCache_delete_nocommit(struct jsonCache *c, char *key)
Definition: jsonCache.c:1570
void string_buff_init(struct string_buff *sb)
Definition: jsonCache.c:727
json_t * _json_parse(char **buff)
Definition: jsonCache.c:1469
char * parse_string(char **json_string)
Definition: jsonCache.c:1048
void json_int_destroy(json_t *json)
Definition: jsonCache.c:223
static json_t * json_object_iterator_elem(json_object_iterator *it)
Definition: jsonCache.h:317
void jsonCache_set_nocommit(struct jsonCache *c, char *key, json_t *elem)
Definition: jsonCache.c:1625
void string_buff_push(struct string_buff *sb, char *s)
Definition: jsonCache.c:741
void json_incref(json_t *json)
Definition: jsonCache.c:13
static int json_object_iterator_next(json_object_iterator *it)
Definition: jsonCache.h:271
json_t * json_parse_bool(char **json_string)
Definition: jsonCache.c:1274
static unsigned int hashString(char *s, int bit_width)
Definition: jsonCache.c:348
json_t * json_object_delete(json_t *json, char *key)
Definition: jsonCache.c:520
json_t ** content
Definition: jsonCache.h:210
json_t * cache
Definition: jsonCache.h:362
struct json_int_s json_int_t
void json_null_destroy(json_t *json)
Definition: jsonCache.c:151
json_t * json_array()
Definition: jsonCache.c:540
char value
Definition: jsonCache.h:111
json_t * json_array_push(json_t *json, json_t *elem)
Definition: jsonCache.c:610
void json_real_destroy(json_t *json)
Definition: jsonCache.c:240
#define json_to_object(a)
Definition: jsonCache.h:237
char * jsonCache_json(struct jsonCache *c, char *key, json_format mode)
Definition: jsonCache.c:1660
json_t * json_parse_string(char **buff)
Definition: jsonCache.c:1263
int json_array_guarantee(json_array_t *a, unsigned int offset, int count)
Definition: jsonCache.c:553
void(* set_handler)(char *, json_t *, void *)
Definition: jsonCache.h:364
static char * json_object_iterator_key(json_object_iterator *it)
Definition: jsonCache.h:306
void ObjectHT_set(struct ObjectHT *ht, char *key, json_t *elem)
Definition: jsonCache.c:409
char * c_newline(newline)
Definition: jsonCache.c:770
Definition: jsonCache.h:165
json_t * json_real(double value)
Definition: jsonCache.c:229