LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/geojson/jsonc - json_object.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 286 222 77.6 %
Date: 2012-12-26 Functions: 41 35 85.4 %

       1                 : /*
       2                 :  * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
       3                 :  *
       4                 :  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
       5                 :  * Michael Clark <michael@metaparadigm.com>
       6                 :  *
       7                 :  * This library is free software; you can redistribute it and/or modify
       8                 :  * it under the terms of the MIT license. See COPYING for details.
       9                 :  *
      10                 :  */
      11                 : 
      12                 : #include "cpl_conv.h"
      13                 : 
      14                 : #include "config.h"
      15                 : 
      16                 : #include <stdio.h>
      17                 : #include <stdlib.h>
      18                 : #include <stddef.h>
      19                 : #include <string.h>
      20                 : 
      21                 : #include "debug.h"
      22                 : #include "printbuf.h"
      23                 : #include "linkhash.h"
      24                 : #include "arraylist.h"
      25                 : #include "json_object.h"
      26                 : #include "json_object_private.h"
      27                 : 
      28                 : #if !HAVE_STRNDUP
      29                 :   char* strndup(const char* str, size_t n);
      30                 : #endif /* !HAVE_STRNDUP */
      31                 : 
      32                 : /* #define REFCOUNT_DEBUG 1 */
      33                 : 
      34                 : const char *json_number_chars = "0123456789.+-eE";
      35                 : const char *json_hex_chars = "0123456789abcdef";
      36                 : 
      37                 : #ifdef REFCOUNT_DEBUG
      38                 : static const char* json_type_name[] = {
      39                 :   "null",
      40                 :   "boolean",
      41                 :   "double",
      42                 :   "int",
      43                 :   "object",
      44                 :   "array",
      45                 :   "string",
      46                 : };
      47                 : #endif /* REFCOUNT_DEBUG */
      48                 : 
      49                 : static void json_object_generic_delete(struct json_object* jso);
      50                 : static struct json_object* json_object_new(enum json_type o_type);
      51                 : 
      52                 : 
      53                 : /* ref count debugging */
      54                 : 
      55                 : #ifdef REFCOUNT_DEBUG
      56                 : 
      57                 : static struct lh_table *json_object_table;
      58                 : 
      59                 : static void json_object_init(void) __attribute__ ((constructor));
      60                 : static void json_object_init(void) {
      61                 :   MC_DEBUG("json_object_init: creating object table\n");
      62                 :   json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
      63                 : }
      64                 : 
      65                 : static void json_object_fini(void) __attribute__ ((destructor));
      66                 : static void json_object_fini(void) {
      67                 :   struct lh_entry *ent;
      68                 :   if(MC_GET_DEBUG()) {
      69                 :     if (json_object_table->count) {
      70                 :       MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
      71                 :            json_object_table->count);
      72                 :       lh_foreach(json_object_table, ent) {
      73                 :         struct json_object* obj = (struct json_object*)ent->v;
      74                 :         MC_DEBUG("\t%s:%p\n", json_type_name[obj->o_type], obj);
      75                 :       }
      76                 :     }
      77                 :   }
      78                 :   MC_DEBUG("json_object_fini: freeing object table\n");
      79                 :   lh_table_free(json_object_table);
      80                 : }
      81                 : #endif /* REFCOUNT_DEBUG */
      82                 : 
      83                 : 
      84                 : /* string escaping */
      85                 : 
      86             586 : static int json_escape_str(struct printbuf *pb, char *str)
      87                 : {
      88             586 :   int pos = 0, start_offset = 0;
      89                 :   unsigned char c;
      90                 :   do {
      91            4299 :     c = str[pos];
      92            4299 :     switch(c) {
      93                 :     case '\0':
      94             586 :       break;
      95                 :     case '\b':
      96                 :     case '\n':
      97                 :     case '\r':
      98                 :     case '\t':
      99                 :     case '"':
     100                 :     case '\\':
     101                 :     case '/':
     102               2 :       if(pos - start_offset > 0)
     103               2 :   printbuf_memappend(pb, str + start_offset, pos - start_offset);
     104               2 :       if(c == '\b') printbuf_memappend(pb, "\\b", 2);
     105               2 :       else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
     106               2 :       else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
     107               2 :       else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
     108               2 :       else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
     109               0 :       else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
     110               0 :       else if(c == '/') printbuf_memappend(pb, "\\/", 2);
     111               2 :       start_offset = ++pos;
     112               2 :       break;
     113                 :     default:
     114            3711 :       if(c < ' ') {
     115               0 :   if(pos - start_offset > 0)
     116               0 :     printbuf_memappend(pb, str + start_offset, pos - start_offset);
     117               0 :   sprintbuf(pb, "\\u00%c%c",
     118               0 :       json_hex_chars[c >> 4],
     119               0 :       json_hex_chars[c & 0xf]);
     120               0 :   start_offset = ++pos;
     121            3711 :       } else pos++;
     122                 :     }
     123            4299 :   } while(c);
     124             586 :   if(pos - start_offset > 0)
     125             586 :     printbuf_memappend(pb, str + start_offset, pos - start_offset);
     126             586 :   return 0;
     127                 : }
     128                 : 
     129                 : 
     130                 : /* reference counting */
     131                 : 
     132           19832 : extern struct json_object* json_object_get(struct json_object *jso)
     133                 : {
     134           19832 :   if(jso) {
     135           19730 :     jso->_ref_count++;
     136                 :   }
     137           19832 :   return jso;
     138                 : }
     139                 : 
     140           60281 : extern void json_object_put(struct json_object *jso)
     141                 : {
     142           60281 :   if(jso) {
     143           40265 :     jso->_ref_count--;
     144           40265 :     if(!jso->_ref_count) jso->_delete(jso);
     145                 :   }
     146           60281 : }
     147                 : 
     148                 : 
     149                 : /* generic object construction and destruction parts */
     150                 : 
     151           20535 : static void json_object_generic_delete(struct json_object* jso)
     152                 : {
     153                 : #ifdef REFCOUNT_DEBUG
     154                 :   MC_DEBUG("json_object_delete_%s: %p\n",
     155                 :      json_type_name[jso->o_type], jso);
     156                 :   lh_table_delete(json_object_table, jso);
     157                 : #endif /* REFCOUNT_DEBUG */
     158           20535 :   printbuf_free(jso->_pb);
     159           20535 :   free(jso);
     160           20535 : }
     161                 : 
     162           20535 : static struct json_object* json_object_new(enum json_type o_type)
     163                 : {
     164                 :   struct json_object *jso;
     165                 : 
     166           20535 :   jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
     167           20535 :   if(!jso) return NULL;
     168           20535 :   jso->o_type = o_type;
     169           20535 :   jso->_ref_count = 1;
     170           20535 :   jso->_delete = &json_object_generic_delete;
     171                 : #ifdef REFCOUNT_DEBUG
     172                 :   lh_table_insert(json_object_table, jso, jso);
     173                 :   MC_DEBUG("json_object_new_%s: %p\n", json_type_name[jso->o_type], jso);
     174                 : #endif /* REFCOUNT_DEBUG */
     175           20535 :   return jso;
     176                 : }
     177                 : 
     178                 : 
     179                 : /* type checking functions */
     180                 : 
     181             409 : int json_object_is_type(struct json_object *jso, enum json_type type)
     182                 : {
     183             409 :   return (jso->o_type == type);
     184                 : }
     185                 : 
     186            6714 : enum json_type json_object_get_type(struct json_object *jso)
     187                 : {
     188            6714 :   return jso->o_type;
     189                 : }
     190                 : 
     191                 : 
     192                 : /* json_object_to_json_string */
     193                 : 
     194             541 : const char* json_object_to_json_string(struct json_object *jso)
     195                 : {
     196             541 :   if(!jso) return "null";
     197             541 :   if(!jso->_pb) {
     198             541 :     if((jso->_pb = printbuf_new()) == NULL) return NULL;
     199                 :   } else {
     200               0 :     printbuf_reset(jso->_pb);
     201                 :   }
     202             541 :   if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
     203             541 :   return jso->_pb->buf;
     204                 : }
     205                 : 
     206                 : 
     207                 : /* json_object_object */
     208                 : 
     209             121 : static int json_object_object_to_json_string(struct json_object* jso,
     210                 :                struct printbuf *pb)
     211                 : {
     212             121 :   int i=0;
     213                 :   struct json_object_iter iter;
     214             121 :   iter.key = NULL;
     215             121 :   sprintbuf(pb, "{");
     216                 : 
     217                 :   /* CAW: scope operator to make ANSI correctness */
     218                 :   /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
     219             567 :   json_object_object_foreachC(jso, iter) {
     220             446 :       if(i) sprintbuf(pb, ",");
     221             446 :       sprintbuf(pb, " \"");
     222             446 :       json_escape_str(pb, iter.key);
     223             446 :       sprintbuf(pb, "\": ");
     224             446 :       if(iter.val == NULL) sprintbuf(pb, "null");
     225             446 :       else iter.val->_to_json_string(iter.val, pb);
     226             446 :       i++;
     227                 :   }
     228                 : 
     229             121 :   return sprintbuf(pb, " }");
     230                 : }
     231                 : 
     232            5350 : static void json_object_lh_entry_free(struct lh_entry *ent)
     233                 : {
     234            5350 :   free(ent->k);
     235            5350 :   json_object_put((struct json_object*)ent->v);
     236            5350 : }
     237                 : 
     238            1394 : static void json_object_object_delete(struct json_object* jso)
     239                 : {
     240            1394 :   lh_table_free(jso->o.c_object);
     241            1394 :   json_object_generic_delete(jso);
     242            1394 : }
     243                 : 
     244            1394 : struct json_object* json_object_new_object(void)
     245                 : {
     246            1394 :   struct json_object *jso = json_object_new(json_type_object);
     247            1394 :   if(!jso) return NULL;
     248            1394 :   jso->_delete = &json_object_object_delete;
     249            1394 :   jso->_to_json_string = &json_object_object_to_json_string;
     250            1394 :   jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
     251                 :           NULL, &json_object_lh_entry_free);
     252            1394 :   return jso;
     253                 : }
     254                 : 
     255            3772 : struct lh_table* json_object_get_object(struct json_object *jso)
     256                 : {
     257            3772 :   if(!jso) return NULL;
     258            3772 :   switch(jso->o_type) {
     259                 :   case json_type_object:
     260            3772 :     return jso->o.c_object;
     261                 :   default:
     262               0 :     return NULL;
     263                 :   }
     264                 : }
     265                 : 
     266            5350 : void json_object_object_add(struct json_object* jso, const char *key,
     267                 :           struct json_object *val)
     268                 : {
     269            5350 :   lh_table_delete(jso->o.c_object, key);
     270            5350 :   lh_table_insert(jso->o.c_object, strdup(key), val);
     271            5350 : }
     272                 : 
     273            1480 : struct json_object* json_object_object_get(struct json_object* jso, const char *key)
     274                 : {
     275            1480 :   return (struct json_object*) lh_table_lookup(jso->o.c_object, key);
     276                 : }
     277                 : 
     278               0 : void json_object_object_del(struct json_object* jso, const char *key)
     279                 : {
     280               0 :   lh_table_delete(jso->o.c_object, key);
     281               0 : }
     282                 : 
     283                 : 
     284                 : /* json_object_boolean */
     285                 : 
     286               0 : static int json_object_boolean_to_json_string(struct json_object* jso,
     287                 :                 struct printbuf *pb)
     288                 : {
     289               0 :   if(jso->o.c_boolean) return sprintbuf(pb, "true");
     290               0 :   else return sprintbuf(pb, "false");
     291                 : }
     292                 : 
     293              15 : struct json_object* json_object_new_boolean(boolean b)
     294                 : {
     295              15 :   struct json_object *jso = json_object_new(json_type_boolean);
     296              15 :   if(!jso) return NULL;
     297              15 :   jso->_to_json_string = &json_object_boolean_to_json_string;
     298              15 :   jso->o.c_boolean = b;
     299              15 :   return jso;
     300                 : }
     301                 : 
     302               0 : boolean json_object_get_boolean(struct json_object *jso)
     303                 : {
     304               0 :   if(!jso) return FALSE;
     305               0 :   switch(jso->o_type) {
     306                 :   case json_type_boolean:
     307               0 :     return jso->o.c_boolean;
     308                 :   case json_type_int:
     309               0 :     return (jso->o.c_int != 0);
     310                 :   case json_type_double:
     311               0 :     return (jso->o.c_double != 0);
     312                 :   case json_type_string:
     313               0 :     return (strlen(jso->o.c_string) != 0);
     314                 :   default:
     315               0 :     return FALSE;
     316                 :   }
     317                 : }
     318                 : 
     319                 : 
     320                 : /* json_object_int */
     321                 : 
     322             170 : static int json_object_int_to_json_string(struct json_object* jso,
     323                 :             struct printbuf *pb)
     324                 : {
     325             170 :   return sprintbuf(pb, "%d", jso->o.c_int);
     326                 : }
     327                 : 
     328             826 : struct json_object* json_object_new_int(int i)
     329                 : {
     330             826 :   struct json_object *jso = json_object_new(json_type_int);
     331             826 :   if(!jso) return NULL;
     332             826 :   jso->_to_json_string = &json_object_int_to_json_string;
     333             826 :   jso->o.c_int = i;
     334             826 :   return jso;
     335                 : }
     336                 : 
     337             153 : int json_object_get_int(struct json_object *jso)
     338                 : {
     339                 :   int cint;
     340                 : 
     341             153 :   if(!jso) return 0;
     342             153 :   switch(jso->o_type) {
     343                 :   case json_type_int:
     344             152 :     return jso->o.c_int;
     345                 :   case json_type_double:
     346               0 :     return (int)jso->o.c_double;
     347                 :   case json_type_boolean:
     348               0 :     return jso->o.c_boolean;
     349                 :   case json_type_string:
     350               1 :     if(sscanf(jso->o.c_string, "%d", &cint) == 1) return cint;
     351                 :   default:
     352               0 :     return 0;
     353                 :   }
     354                 : }
     355                 : 
     356                 : 
     357                 : /* json_object_double */
     358                 : 
     359                 : /* Begin: GDAL addition */
     360                 : /************************************************************************/
     361                 : /*                        json_OGRFormatDouble()                        */
     362                 : /* Copied & slightly adapted from ogrutils.cpp                          */
     363                 : /************************************************************************/
     364                 : 
     365             697 : static int json_OGRFormatDouble( char *pszBuffer, int nBufferLen, double dfVal,
     366                 :                                  char chDecimalSep, int nPrecision )
     367                 : {
     368                 :     int i;
     369             697 :     int bHasTruncated = FALSE;
     370                 :     char szFormat[16];
     371                 :     int ret;
     372                 :     
     373             697 :     sprintf(szFormat, "%%.%df", nPrecision);
     374                 : 
     375             697 :     ret = snprintf(pszBuffer, nBufferLen, szFormat, dfVal);
     376                 :     /* Windows CRT doesn't conform with C99 and return -1 when buffer is truncated */
     377             697 :     if (ret >= nBufferLen || ret == -1)
     378               0 :         return -1;
     379                 : 
     380                 :     while(TRUE)
     381                 :     {
     382             717 :         int nCountBeforeDot = 0;
     383             717 :         int iDotPos = -1;
     384             717 :         i = 0;
     385           13807 :         while( pszBuffer[i] != '\0' )
     386                 :         {
     387           13090 :             if ((pszBuffer[i] == '.' || pszBuffer[i] == ',') && chDecimalSep != '\0')
     388                 :             {
     389             717 :                 iDotPos = i;
     390             717 :                 pszBuffer[i] = chDecimalSep;
     391                 :             }
     392           11656 :             else if (iDotPos < 0 && pszBuffer[i] != '-')
     393             993 :                 nCountBeforeDot ++;
     394           12373 :             i++;
     395                 :         }
     396                 : 
     397                 :     /* -------------------------------------------------------------------- */
     398                 :     /*      Trim trailing 00000x's as they are likely roundoff error.       */
     399                 :     /* -------------------------------------------------------------------- */
     400             717 :         if( i > 10 && iDotPos >=0 )
     401                 :         {
     402            4148 :             if (/* && pszBuffer[i-1] == '1' &&*/
     403             717 :                 pszBuffer[i-2] == '0'
     404             697 :                 && pszBuffer[i-3] == '0'
     405             685 :                 && pszBuffer[i-4] == '0'
     406             683 :                 && pszBuffer[i-5] == '0'
     407             683 :                 && pszBuffer[i-6] == '0' )
     408                 :             {
     409             683 :                 pszBuffer[--i] = '\0';
     410                 :             }
     411              70 :             else if( i - 8 > iDotPos && /* pszBuffer[i-1] == '1' */
     412                 :                   /* && pszBuffer[i-2] == '0' && */
     413              34 :                     (nCountBeforeDot >= 4 || pszBuffer[i-3] == '0')
     414               2 :                     && (nCountBeforeDot >= 5 || pszBuffer[i-4] == '0')
     415               0 :                     && (nCountBeforeDot >= 6 || pszBuffer[i-5] == '0')
     416               0 :                     && (nCountBeforeDot >= 7 || pszBuffer[i-6] == '0')
     417               0 :                     && (nCountBeforeDot >= 8 || pszBuffer[i-7] == '0')
     418               0 :                     && pszBuffer[i-8] == '0'
     419               0 :                     && pszBuffer[i-9] == '0')
     420                 :             {
     421               0 :                 i -= 8;
     422               0 :                 pszBuffer[i] = '\0';
     423                 :             }
     424                 :         }
     425                 : 
     426                 :     /* -------------------------------------------------------------------- */
     427                 :     /*      Trim trailing zeros.                                            */
     428                 :     /* -------------------------------------------------------------------- */
     429           10162 :         while( i > 2 && pszBuffer[i-1] == '0' && pszBuffer[i-2] != '.' )
     430                 :         {
     431            8728 :             pszBuffer[--i] = '\0';
     432                 :         }
     433                 : 
     434                 :     /* -------------------------------------------------------------------- */
     435                 :     /*      Detect trailing 99999X's as they are likely roundoff error.     */
     436                 :     /* -------------------------------------------------------------------- */
     437             717 :         if( !bHasTruncated &&
     438                 :             i > 10 &&
     439                 :             iDotPos >= 0 &&
     440                 :             nPrecision >= 15)
     441                 :         {
     442             114 :             if (/*pszBuffer[i-1] == '9' && */
     443              32 :                  pszBuffer[i-2] == '9'
     444              22 :                 && pszBuffer[i-3] == '9'
     445              20 :                 && pszBuffer[i-4] == '9'
     446              20 :                 && pszBuffer[i-5] == '9'
     447              20 :                 && pszBuffer[i-6] == '9' )
     448                 :             {
     449              20 :                 snprintf(pszBuffer, nBufferLen, "%.9f", dfVal);
     450              20 :                 bHasTruncated = TRUE;
     451              20 :                 continue;
     452                 :             }
     453              12 :             else if (i - 9 > iDotPos && /*pszBuffer[i-1] == '9' && */
     454                 :                      /*pszBuffer[i-2] == '9' && */
     455               0 :                     (nCountBeforeDot >= 4 || pszBuffer[i-3] == '9')
     456               0 :                     && (nCountBeforeDot >= 5 || pszBuffer[i-4] == '9')
     457               0 :                     && (nCountBeforeDot >= 6 || pszBuffer[i-5] == '9')
     458               0 :                     && (nCountBeforeDot >= 7 || pszBuffer[i-6] == '9')
     459               0 :                     && (nCountBeforeDot >= 8 || pszBuffer[i-7] == '9')
     460               0 :                     && pszBuffer[i-8] == '9'
     461               0 :                     && pszBuffer[i-9] == '9')
     462                 :             {
     463               0 :                 sprintf(szFormat, "%%.%df", MIN(5,12 - nCountBeforeDot));
     464               0 :                 snprintf(pszBuffer, nBufferLen, szFormat, dfVal);
     465               0 :                 bHasTruncated = TRUE;
     466               0 :                 continue;
     467                 :             }
     468                 :         }
     469                 : 
     470                 :         break;
     471              20 :     }
     472                 : 
     473             697 :     return strlen(pszBuffer);
     474                 : }
     475                 : /* End: GDAL addition */
     476                 : 
     477             697 : static int json_object_double_to_json_string(struct json_object* jso,
     478                 :                struct printbuf *pb)
     479                 : {
     480                 :    /* GDAL modified */
     481                 :   char szBuffer[75];
     482             697 :   int ret = json_OGRFormatDouble( szBuffer, sizeof(szBuffer), jso->o.c_double, '.',
     483             697 :                                   (jso->_precision < 0) ? 15 : jso->_precision );
     484             697 :   if (ret < 0)
     485               0 :     return ret;
     486             697 :   return printbuf_memappend(pb, szBuffer, ret);
     487                 : }
     488                 : 
     489           10483 : struct json_object* json_object_new_double(double d)
     490                 : {
     491           10483 :   struct json_object *jso = json_object_new(json_type_double);
     492           10483 :   if(!jso) return NULL;
     493           10483 :   jso->_to_json_string = &json_object_double_to_json_string;
     494           10483 :   jso->o.c_double = d;
     495           10483 :   jso->_precision = -1; /* GDAL addition */
     496           10483 :   return jso;
     497                 : }
     498                 : 
     499                 : /* Begin: GDAL addition */
     500             172 : struct json_object* json_object_new_double_with_precision(double d, int nPrecision)
     501                 : {
     502             172 :   struct json_object *jso = json_object_new(json_type_double);
     503             172 :   if(!jso) return NULL;
     504             172 :   jso->_to_json_string = &json_object_double_to_json_string;
     505             172 :   jso->o.c_double = d;
     506             172 :   jso->_precision = (nPrecision < 32) ? nPrecision : 32;
     507             172 :   return jso;
     508                 : }
     509                 : /* End: GDAL addition */
     510                 : 
     511            4093 : double json_object_get_double(struct json_object *jso)
     512                 : {
     513            4093 :   if(!jso) return 0.0;
     514            4093 :   switch(jso->o_type) {
     515                 :   case json_type_double:
     516            4090 :     return jso->o.c_double;
     517                 :   case json_type_int:
     518               3 :     return jso->o.c_int;
     519                 :   case json_type_boolean:
     520               0 :     return jso->o.c_boolean;
     521                 :   case json_type_string:
     522               0 :     return CPLAtof(jso->o.c_string);
     523                 :   default:
     524               0 :     return 0.0;
     525                 :   }
     526                 : }
     527                 : 
     528                 : 
     529                 : /* json_object_string */
     530                 : 
     531             140 : static int json_object_string_to_json_string(struct json_object* jso,
     532                 :                struct printbuf *pb)
     533                 : {
     534             140 :   sprintbuf(pb, "\"");
     535             140 :   json_escape_str(pb, jso->o.c_string);
     536             140 :   sprintbuf(pb, "\"");
     537             140 :   return 0;
     538                 : }
     539                 : 
     540            2392 : static void json_object_string_delete(struct json_object* jso)
     541                 : {
     542            2392 :   free(jso->o.c_string);
     543            2392 :   json_object_generic_delete(jso);
     544            2392 : }
     545                 : 
     546            2392 : struct json_object* json_object_new_string(const char *s)
     547                 : {
     548            2392 :   struct json_object *jso = json_object_new(json_type_string);
     549            2392 :   if(!jso) return NULL;
     550            2392 :   jso->_delete = &json_object_string_delete;
     551            2392 :   jso->_to_json_string = &json_object_string_to_json_string;
     552            2392 :   jso->o.c_string = strdup(s);
     553            2392 :   return jso;
     554                 : }
     555                 : 
     556               0 : struct json_object* json_object_new_string_len(const char *s, int len)
     557                 : {
     558               0 :   struct json_object *jso = json_object_new(json_type_string);
     559               0 :   if(!jso) return NULL;
     560               0 :   jso->_delete = &json_object_string_delete;
     561               0 :   jso->_to_json_string = &json_object_string_to_json_string;
     562               0 :   jso->o.c_string = strndup(s, len);
     563               0 :   return jso;
     564                 : }
     565                 : 
     566            1519 : const char* json_object_get_string(struct json_object *jso)
     567                 : {
     568            1519 :   if(!jso) return NULL;
     569            1440 :   switch(jso->o_type) {
     570                 :   case json_type_string:
     571             949 :     return jso->o.c_string;
     572                 :   default:
     573             491 :     return json_object_to_json_string(jso);
     574                 :   }
     575                 : }
     576                 : 
     577                 : 
     578                 : /* json_object_array */
     579                 : 
     580             138 : static int json_object_array_to_json_string(struct json_object* jso,
     581                 :               struct printbuf *pb)
     582                 : {
     583                 :   int i;
     584             138 :   sprintbuf(pb, "[");
     585             420 :   for(i=0; i < json_object_array_length(jso); i++) {
     586                 :     struct json_object *val;
     587             282 :     if(i) { sprintbuf(pb, ", "); }
     588             128 :     else { sprintbuf(pb, " "); }
     589                 : 
     590             282 :       val = json_object_array_get_idx(jso, i);
     591             282 :     if(val == NULL) { sprintbuf(pb, "null"); }
     592             279 :     else { val->_to_json_string(val, pb); }
     593                 :   }
     594             138 :   return sprintbuf(pb, " ]");
     595                 : }
     596                 : 
     597           14967 : static void json_object_array_entry_free(void *data)
     598                 : {
     599           14967 :   json_object_put((struct json_object*)data);
     600           14967 : }
     601                 : 
     602            5253 : static void json_object_array_delete(struct json_object* jso)
     603                 : {
     604            5253 :   array_list_free(jso->o.c_array);
     605            5253 :   json_object_generic_delete(jso);
     606            5253 : }
     607                 : 
     608            5253 : struct json_object* json_object_new_array(void)
     609                 : {
     610            5253 :   struct json_object *jso = json_object_new(json_type_array);
     611            5253 :   if(!jso) return NULL;
     612            5253 :   jso->_delete = &json_object_array_delete;
     613            5253 :   jso->_to_json_string = &json_object_array_to_json_string;
     614            5253 :   jso->o.c_array = array_list_new(&json_object_array_entry_free);
     615            5253 :   return jso;
     616                 : }
     617                 : 
     618               0 : struct array_list* json_object_get_array(struct json_object *jso)
     619                 : {
     620               0 :   if(!jso) return NULL;
     621               0 :   switch(jso->o_type) {
     622                 :   case json_type_array:
     623               0 :     return jso->o.c_array;
     624                 :   default:
     625               0 :     return NULL;
     626                 :   }
     627                 : }
     628                 : 
     629            2804 : int json_object_array_length(struct json_object *jso)
     630                 : {
     631            2804 :   return array_list_length(jso->o.c_array);
     632                 : }
     633                 : 
     634           15018 : int json_object_array_add(struct json_object *jso,struct json_object *val)
     635                 : {
     636           15018 :   return array_list_add(jso->o.c_array, val);
     637                 : }
     638                 : 
     639               0 : int json_object_array_put_idx(struct json_object *jso, int idx,
     640                 :             struct json_object *val)
     641                 : {
     642               0 :   return array_list_put_idx(jso->o.c_array, idx, val);
     643                 : }
     644                 : 
     645            6915 : struct json_object* json_object_array_get_idx(struct json_object *jso,
     646                 :                 int idx)
     647                 : {
     648            6915 :   return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
     649                 : }
     650                 : 

Generated by: LCOV version 1.7