LCOV - code coverage report
Current view: top level - lib - json.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 666 721 92.4 %
Date: 2016-09-14 01:02:56 Functions: 68 70 97.1 %
Branches: 316 372 84.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2009, 2010, 2011, 2012, 2014, 2015 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : 
      19                 :            : #include "openvswitch/json.h"
      20                 :            : 
      21                 :            : #include <ctype.h>
      22                 :            : #include <errno.h>
      23                 :            : #include <float.h>
      24                 :            : #include <limits.h>
      25                 :            : #include <string.h>
      26                 :            : 
      27                 :            : #include "openvswitch/dynamic-string.h"
      28                 :            : #include "hash.h"
      29                 :            : #include "openvswitch/shash.h"
      30                 :            : #include "unicode.h"
      31                 :            : #include "util.h"
      32                 :            : 
      33                 :            : /* The type of a JSON token. */
      34                 :            : enum json_token_type {
      35                 :            :     T_EOF = 0,
      36                 :            :     T_BEGIN_ARRAY = '[',
      37                 :            :     T_END_ARRAY = ']',
      38                 :            :     T_BEGIN_OBJECT = '{',
      39                 :            :     T_END_OBJECT = '}',
      40                 :            :     T_NAME_SEPARATOR = ':',
      41                 :            :     T_VALUE_SEPARATOR = ',',
      42                 :            :     T_FALSE = UCHAR_MAX + 1,
      43                 :            :     T_NULL,
      44                 :            :     T_TRUE,
      45                 :            :     T_INTEGER,
      46                 :            :     T_REAL,
      47                 :            :     T_STRING
      48                 :            : };
      49                 :            : 
      50                 :            : /* A JSON token.
      51                 :            :  *
      52                 :            :  * RFC 4627 doesn't define a lexical structure for JSON but I believe this to
      53                 :            :  * be compliant with the standard.
      54                 :            :  */
      55                 :            : struct json_token {
      56                 :            :     enum json_token_type type;
      57                 :            :     union {
      58                 :            :         double real;
      59                 :            :         long long int integer;
      60                 :            :         const char *string;
      61                 :            :     } u;
      62                 :            : };
      63                 :            : 
      64                 :            : enum json_lex_state {
      65                 :            :     JSON_LEX_START,             /* Not inside a token. */
      66                 :            :     JSON_LEX_NUMBER,            /* Reading a number. */
      67                 :            :     JSON_LEX_KEYWORD,           /* Reading a keyword. */
      68                 :            :     JSON_LEX_STRING,            /* Reading a quoted string. */
      69                 :            :     JSON_LEX_ESCAPE             /* In a quoted string just after a "\". */
      70                 :            : };
      71                 :            : 
      72                 :            : enum json_parse_state {
      73                 :            :     JSON_PARSE_START,           /* Beginning of input. */
      74                 :            :     JSON_PARSE_END,             /* End of input. */
      75                 :            : 
      76                 :            :     /* Objects. */
      77                 :            :     JSON_PARSE_OBJECT_INIT,     /* Expecting '}' or an object name. */
      78                 :            :     JSON_PARSE_OBJECT_NAME,     /* Expecting an object name. */
      79                 :            :     JSON_PARSE_OBJECT_COLON,    /* Expecting ':'. */
      80                 :            :     JSON_PARSE_OBJECT_VALUE,    /* Expecting an object value. */
      81                 :            :     JSON_PARSE_OBJECT_NEXT,     /* Expecting ',' or '}'. */
      82                 :            : 
      83                 :            :     /* Arrays. */
      84                 :            :     JSON_PARSE_ARRAY_INIT,      /* Expecting ']' or a value. */
      85                 :            :     JSON_PARSE_ARRAY_VALUE,     /* Expecting a value. */
      86                 :            :     JSON_PARSE_ARRAY_NEXT       /* Expecting ',' or ']'. */
      87                 :            : };
      88                 :            : 
      89                 :            : struct json_parser_node {
      90                 :            :     struct json *json;
      91                 :            : };
      92                 :            : 
      93                 :            : /* A JSON parser. */
      94                 :            : struct json_parser {
      95                 :            :     int flags;
      96                 :            : 
      97                 :            :     /* Lexical analysis. */
      98                 :            :     enum json_lex_state lex_state;
      99                 :            :     struct ds buffer;           /* Buffer for accumulating token text. */
     100                 :            :     int line_number;
     101                 :            :     int column_number;
     102                 :            :     int byte_number;
     103                 :            : 
     104                 :            :     /* Parsing. */
     105                 :            :     enum json_parse_state parse_state;
     106                 :            : #define JSON_MAX_HEIGHT 1000
     107                 :            :     struct json_parser_node *stack;
     108                 :            :     size_t height, allocated_height;
     109                 :            :     char *member_name;
     110                 :            : 
     111                 :            :     /* Parse status. */
     112                 :            :     bool done;
     113                 :            :     char *error;                /* Error message, if any, null if none yet. */
     114                 :            : };
     115                 :            : 
     116                 :            : static struct json *json_create(enum json_type type);
     117                 :            : static void json_parser_input(struct json_parser *, struct json_token *);
     118                 :            : 
     119                 :            : static void json_error(struct json_parser *p, const char *format, ...)
     120                 :            :     OVS_PRINTF_FORMAT(2, 3);
     121                 :            : 
     122                 :            : const char *
     123                 :      12183 : json_type_to_string(enum json_type type)
     124                 :            : {
     125   [ -  -  -  -  :      12183 :     switch (type) {
             +  -  +  - ]
     126                 :            :     case JSON_NULL:
     127                 :          0 :         return "null";
     128                 :            : 
     129                 :            :     case JSON_FALSE:
     130                 :          0 :         return "false";
     131                 :            : 
     132                 :            :     case JSON_TRUE:
     133                 :          0 :         return "true";
     134                 :            : 
     135                 :            :     case JSON_OBJECT:
     136                 :          0 :         return "object";
     137                 :            : 
     138                 :            :     case JSON_ARRAY:
     139                 :         12 :         return "array";
     140                 :            : 
     141                 :            :     case JSON_INTEGER:
     142                 :            :     case JSON_REAL:
     143                 :          0 :         return "number";
     144                 :            : 
     145                 :            :     case JSON_STRING:
     146                 :      12171 :         return "string";
     147                 :            : 
     148                 :            :     case JSON_N_TYPES:
     149                 :            :     default:
     150                 :          0 :         return "<invalid>";
     151                 :            :     }
     152                 :            : }
     153                 :            : 
     154                 :            : /* Functions for manipulating struct json. */
     155                 :            : 
     156                 :            : struct json *
     157                 :     125444 : json_null_create(void)
     158                 :            : {
     159                 :     125444 :     return json_create(JSON_NULL);
     160                 :            : }
     161                 :            : 
     162                 :            : struct json *
     163                 :     545294 : json_boolean_create(bool b)
     164                 :            : {
     165         [ +  + ]:     545294 :     return json_create(b ? JSON_TRUE : JSON_FALSE);
     166                 :            : }
     167                 :            : 
     168                 :            : struct json *
     169                 :   11903325 : json_string_create_nocopy(char *s)
     170                 :            : {
     171                 :   11903325 :     struct json *json = json_create(JSON_STRING);
     172                 :   11903325 :     json->u.string = s;
     173                 :   11903325 :     return json;
     174                 :            : }
     175                 :            : 
     176                 :            : struct json *
     177                 :   11494500 : json_string_create(const char *s)
     178                 :            : {
     179                 :   11494500 :     return json_string_create_nocopy(xstrdup(s));
     180                 :            : }
     181                 :            : 
     182                 :            : struct json *
     183                 :    1314686 : json_array_create_empty(void)
     184                 :            : {
     185                 :    1314686 :     struct json *json = json_create(JSON_ARRAY);
     186                 :    1314686 :     json->u.array.elems = NULL;
     187                 :    1314686 :     json->u.array.n = 0;
     188                 :    1314686 :     json->u.array.n_allocated = 0;
     189                 :    1314686 :     return json;
     190                 :            : }
     191                 :            : 
     192                 :            : void
     193                 :    3053914 : json_array_add(struct json *array_, struct json *element)
     194                 :            : {
     195                 :    3053914 :     struct json_array *array = json_array(array_);
     196         [ +  + ]:    3053914 :     if (array->n >= array->n_allocated) {
     197                 :    2585813 :         array->elems = x2nrealloc(array->elems, &array->n_allocated,
     198                 :            :                                   sizeof *array->elems);
     199                 :            :     }
     200                 :    3053914 :     array->elems[array->n++] = element;
     201                 :    3053914 : }
     202                 :            : 
     203                 :            : void
     204                 :    1183959 : json_array_trim(struct json *array_)
     205                 :            : {
     206                 :    1183959 :     struct json_array *array = json_array(array_);
     207         [ +  + ]:    1183959 :     if (array->n < array->n_allocated){
     208                 :     134800 :         array->n_allocated = array->n;
     209                 :     134800 :         array->elems = xrealloc(array->elems, array->n * sizeof *array->elems);
     210                 :            :     }
     211                 :    1183959 : }
     212                 :            : 
     213                 :            : struct json *
     214                 :    2002524 : json_array_create(struct json **elements, size_t n)
     215                 :            : {
     216                 :    2002524 :     struct json *json = json_create(JSON_ARRAY);
     217                 :    2002524 :     json->u.array.elems = elements;
     218                 :    2002524 :     json->u.array.n = n;
     219                 :    2002524 :     json->u.array.n_allocated = n;
     220                 :    2002524 :     return json;
     221                 :            : }
     222                 :            : 
     223                 :            : struct json *
     224                 :     136759 : json_array_create_1(struct json *elem0)
     225                 :            : {
     226                 :     136759 :     struct json **elems = xmalloc(sizeof *elems);
     227                 :     136759 :     elems[0] = elem0;
     228                 :     136759 :     return json_array_create(elems, 1);
     229                 :            : }
     230                 :            : 
     231                 :            : struct json *
     232                 :     832048 : json_array_create_2(struct json *elem0, struct json *elem1)
     233                 :            : {
     234                 :     832048 :     struct json **elems = xmalloc(2 * sizeof *elems);
     235                 :     832048 :     elems[0] = elem0;
     236                 :     832048 :     elems[1] = elem1;
     237                 :     832048 :     return json_array_create(elems, 2);
     238                 :            : }
     239                 :            : 
     240                 :            : struct json *
     241                 :      75299 : json_array_create_3(struct json *elem0, struct json *elem1, struct json *elem2)
     242                 :            : {
     243                 :      75299 :     struct json **elems = xmalloc(3 * sizeof *elems);
     244                 :      75299 :     elems[0] = elem0;
     245                 :      75299 :     elems[1] = elem1;
     246                 :      75299 :     elems[2] = elem2;
     247                 :      75299 :     return json_array_create(elems, 3);
     248                 :            : }
     249                 :            : 
     250                 :            : struct json *
     251                 :   10141595 : json_object_create(void)
     252                 :            : {
     253                 :   10141595 :     struct json *json = json_create(JSON_OBJECT);
     254                 :   10141595 :     json->u.object = xmalloc(sizeof *json->u.object);
     255                 :   10141595 :     shash_init(json->u.object);
     256                 :   10141595 :     return json;
     257                 :            : }
     258                 :            : 
     259                 :            : struct json *
     260                 :    4491189 : json_integer_create(long long int integer)
     261                 :            : {
     262                 :    4491189 :     struct json *json = json_create(JSON_INTEGER);
     263                 :    4491189 :     json->u.integer = integer;
     264                 :    4491189 :     return json;
     265                 :            : }
     266                 :            : 
     267                 :            : struct json *
     268                 :       1053 : json_real_create(double real)
     269                 :            : {
     270                 :       1053 :     struct json *json = json_create(JSON_REAL);
     271                 :       1053 :     json->u.real = real;
     272                 :       1053 :     return json;
     273                 :            : }
     274                 :            : 
     275                 :            : void
     276                 :   23533540 : json_object_put(struct json *json, const char *name, struct json *value)
     277                 :            : {
     278                 :   23533540 :     json_destroy(shash_replace(json->u.object, name, value));
     279                 :   23533540 : }
     280                 :            : 
     281                 :            : void
     282                 :    1243299 : json_object_put_string(struct json *json, const char *name, const char *value)
     283                 :            : {
     284                 :    1243299 :     json_object_put(json, name, json_string_create(value));
     285                 :    1243299 : }
     286                 :            : 
     287                 :            : const char *
     288                 :     985542 : json_string(const struct json *json)
     289                 :            : {
     290         [ -  + ]:     985542 :     ovs_assert(json->type == JSON_STRING);
     291                 :     985542 :     return json->u.string;
     292                 :            : }
     293                 :            : 
     294                 :            : struct json_array *
     295                 :    4403313 : json_array(const struct json *json)
     296                 :            : {
     297         [ -  + ]:    4403313 :     ovs_assert(json->type == JSON_ARRAY);
     298                 :    4403313 :     return CONST_CAST(struct json_array *, &json->u.array);
     299                 :            : }
     300                 :            : 
     301                 :            : struct shash *
     302                 :    7044699 : json_object(const struct json *json)
     303                 :            : {
     304         [ -  + ]:    7044699 :     ovs_assert(json->type == JSON_OBJECT);
     305                 :    7044699 :     return CONST_CAST(struct shash *, json->u.object);
     306                 :            : }
     307                 :            : 
     308                 :            : bool
     309                 :      59931 : json_boolean(const struct json *json)
     310                 :            : {
     311 [ +  + ][ -  + ]:      59931 :     ovs_assert(json->type == JSON_TRUE || json->type == JSON_FALSE);
     312                 :      59931 :     return json->type == JSON_TRUE;
     313                 :            : }
     314                 :            : 
     315                 :            : double
     316                 :      54255 : json_real(const struct json *json)
     317                 :            : {
     318 [ +  + ][ -  + ]:      54255 :     ovs_assert(json->type == JSON_REAL || json->type == JSON_INTEGER);
     319         [ +  + ]:      54255 :     return json->type == JSON_REAL ? json->u.real : json->u.integer;
     320                 :            : }
     321                 :            : 
     322                 :            : int64_t
     323                 :       3317 : json_integer(const struct json *json)
     324                 :            : {
     325         [ -  + ]:       3317 :     ovs_assert(json->type == JSON_INTEGER);
     326                 :       3317 :     return json->u.integer;
     327                 :            : }
     328                 :            : 
     329                 :            : static void json_destroy_object(struct shash *object);
     330                 :            : static void json_destroy_array(struct json_array *array);
     331                 :            : 
     332                 :            : /* Frees 'json' and everything it points to, recursively. */
     333                 :            : void
     334                 :   54646391 : json_destroy(struct json *json)
     335                 :            : {
     336         [ +  + ]:   54646391 :     if (json) {
     337   [ +  +  +  +  :   30754174 :         switch (json->type) {
                   -  - ]
     338                 :            :         case JSON_OBJECT:
     339                 :   10141544 :             json_destroy_object(json->u.object);
     340                 :   10141544 :             break;
     341                 :            : 
     342                 :            :         case JSON_ARRAY:
     343                 :    3317184 :             json_destroy_array(&json->u.array);
     344                 :    3317184 :             break;
     345                 :            : 
     346                 :            :         case JSON_STRING:
     347                 :   11903271 :             free(json->u.string);
     348                 :   11903271 :             break;
     349                 :            : 
     350                 :            :         case JSON_NULL:
     351                 :            :         case JSON_FALSE:
     352                 :            :         case JSON_TRUE:
     353                 :            :         case JSON_INTEGER:
     354                 :            :         case JSON_REAL:
     355                 :    5392175 :             break;
     356                 :            : 
     357                 :            :         case JSON_N_TYPES:
     358                 :          0 :             OVS_NOT_REACHED();
     359                 :            :         }
     360                 :   30754174 :         free(json);
     361                 :            :     }
     362                 :   54646391 : }
     363                 :            : 
     364                 :            : static void
     365                 :   10141544 : json_destroy_object(struct shash *object)
     366                 :            : {
     367                 :            :     struct shash_node *node, *next;
     368                 :            : 
     369 [ +  + ][ -  + ]:   33391866 :     SHASH_FOR_EACH_SAFE (node, next, object) {
                 [ +  + ]
     370                 :   23250322 :         struct json *value = node->data;
     371                 :            : 
     372                 :   23250322 :         json_destroy(value);
     373                 :   23250322 :         shash_delete(object, node);
     374                 :            :     }
     375                 :   10141544 :     shash_destroy(object);
     376                 :   10141544 :     free(object);
     377                 :   10141544 : }
     378                 :            : 
     379                 :            : static void
     380                 :    3317184 : json_destroy_array(struct json_array *array)
     381                 :            : {
     382                 :            :     size_t i;
     383                 :            : 
     384         [ +  + ]:   10189451 :     for (i = 0; i < array->n; i++) {
     385                 :    6872267 :         json_destroy(array->elems[i]);
     386                 :            :     }
     387                 :    3317184 :     free(array->elems);
     388                 :    3317184 : }
     389                 :            : 
     390                 :            : static struct json *json_clone_object(const struct shash *object);
     391                 :            : static struct json *json_clone_array(const struct json_array *array);
     392                 :            : 
     393                 :            : /* Returns a deep copy of 'json'. */
     394                 :            : struct json *
     395                 :    7646740 : json_clone(const struct json *json)
     396                 :            : {
     397   [ +  +  +  +  :    7646740 :     switch (json->type) {
                +  +  - ]
     398                 :            :     case JSON_OBJECT:
     399                 :    2771329 :         return json_clone_object(json->u.object);
     400                 :            : 
     401                 :            :     case JSON_ARRAY:
     402                 :     589530 :         return json_clone_array(&json->u.array);
     403                 :            : 
     404                 :            :     case JSON_STRING:
     405                 :    2797633 :         return json_string_create(json->u.string);
     406                 :            : 
     407                 :            :     case JSON_NULL:
     408                 :            :     case JSON_FALSE:
     409                 :            :     case JSON_TRUE:
     410                 :     229245 :         return json_create(json->type);
     411                 :            : 
     412                 :            :     case JSON_INTEGER:
     413                 :    1258846 :         return json_integer_create(json->u.integer);
     414                 :            : 
     415                 :            :     case JSON_REAL:
     416                 :        157 :         return json_real_create(json->u.real);
     417                 :            : 
     418                 :            :     case JSON_N_TYPES:
     419                 :            :     default:
     420                 :          0 :         OVS_NOT_REACHED();
     421                 :            :     }
     422                 :            : }
     423                 :            : 
     424                 :            : static struct json *
     425                 :    2771329 : json_clone_object(const struct shash *object)
     426                 :            : {
     427                 :            :     struct shash_node *node;
     428                 :            :     struct json *json;
     429                 :            : 
     430                 :    2771329 :     json = json_object_create();
     431 [ +  + ][ -  + ]:    9088687 :     SHASH_FOR_EACH (node, object) {
     432                 :    6317358 :         struct json *value = node->data;
     433                 :    6317358 :         json_object_put(json, node->name, json_clone(value));
     434                 :            :     }
     435                 :    2771329 :     return json;
     436                 :            : }
     437                 :            : 
     438                 :            : static struct json *
     439                 :     589530 : json_clone_array(const struct json_array *array)
     440                 :            : {
     441                 :            :     struct json **elems;
     442                 :            :     size_t i;
     443                 :            : 
     444                 :     589530 :     elems = xmalloc(array->n * sizeof *elems);
     445         [ +  + ]:    1764657 :     for (i = 0; i < array->n; i++) {
     446                 :    1175127 :         elems[i] = json_clone(array->elems[i]);
     447                 :            :     }
     448                 :     589530 :     return json_array_create(elems, array->n);
     449                 :            : }
     450                 :            : 
     451                 :            : static size_t
     452                 :          0 : json_hash_object(const struct shash *object, size_t basis)
     453                 :            : {
     454                 :            :     const struct shash_node **nodes;
     455                 :            :     size_t n, i;
     456                 :            : 
     457                 :          0 :     nodes = shash_sort(object);
     458                 :          0 :     n = shash_count(object);
     459         [ #  # ]:          0 :     for (i = 0; i < n; i++) {
     460                 :          0 :         const struct shash_node *node = nodes[i];
     461                 :          0 :         basis = hash_string(node->name, basis);
     462                 :          0 :         basis = json_hash(node->data, basis);
     463                 :            :     }
     464                 :          0 :     free(nodes);
     465                 :          0 :     return basis;
     466                 :            : }
     467                 :            : 
     468                 :            : static size_t
     469                 :          0 : json_hash_array(const struct json_array *array, size_t basis)
     470                 :            : {
     471                 :            :     size_t i;
     472                 :            : 
     473                 :          0 :     basis = hash_int(array->n, basis);
     474         [ #  # ]:          0 :     for (i = 0; i < array->n; i++) {
     475                 :          0 :         basis = json_hash(array->elems[i], basis);
     476                 :            :     }
     477                 :          0 :     return basis;
     478                 :            : }
     479                 :            : 
     480                 :            : size_t
     481                 :      49670 : json_hash(const struct json *json, size_t basis)
     482                 :            : {
     483   [ -  -  +  +  :      49670 :     switch (json->type) {
                +  -  - ]
     484                 :            :     case JSON_OBJECT:
     485                 :          0 :         return json_hash_object(json->u.object, basis);
     486                 :            : 
     487                 :            :     case JSON_ARRAY:
     488                 :          0 :         return json_hash_array(&json->u.array, basis);
     489                 :            : 
     490                 :            :     case JSON_STRING:
     491                 :      14524 :         return hash_string(json->u.string, basis);
     492                 :            : 
     493                 :            :     case JSON_NULL:
     494                 :            :     case JSON_FALSE:
     495                 :            :     case JSON_TRUE:
     496                 :         54 :         return hash_int(json->type << 8, basis);
     497                 :            : 
     498                 :            :     case JSON_INTEGER:
     499                 :      35092 :         return hash_int(json->u.integer, basis);
     500                 :            : 
     501                 :            :     case JSON_REAL:
     502                 :          0 :         return hash_double(json->u.real, basis);
     503                 :            : 
     504                 :            :     case JSON_N_TYPES:
     505                 :            :     default:
     506                 :          0 :         OVS_NOT_REACHED();
     507                 :            :     }
     508                 :            : }
     509                 :            : 
     510                 :            : static bool
     511                 :        358 : json_equal_object(const struct shash *a, const struct shash *b)
     512                 :            : {
     513                 :            :     struct shash_node *a_node;
     514                 :            : 
     515         [ -  + ]:        358 :     if (shash_count(a) != shash_count(b)) {
     516                 :          0 :         return false;
     517                 :            :     }
     518                 :            : 
     519 [ +  + ][ -  + ]:       1000 :     SHASH_FOR_EACH (a_node, a) {
     520                 :        643 :         struct shash_node *b_node = shash_find(b, a_node->name);
     521 [ +  - ][ +  + ]:        643 :         if (!b_node || !json_equal(a_node->data, b_node->data)) {
     522                 :          1 :             return false;
     523                 :            :         }
     524                 :            :     }
     525                 :            : 
     526                 :        357 :     return true;
     527                 :            : }
     528                 :            : 
     529                 :            : static bool
     530                 :         80 : json_equal_array(const struct json_array *a, const struct json_array *b)
     531                 :            : {
     532                 :            :     size_t i;
     533                 :            : 
     534         [ -  + ]:         80 :     if (a->n != b->n) {
     535                 :          0 :         return false;
     536                 :            :     }
     537                 :            : 
     538         [ +  + ]:        160 :     for (i = 0; i < a->n; i++) {
     539         [ -  + ]:         80 :         if (!json_equal(a->elems[i], b->elems[i])) {
     540                 :          0 :             return false;
     541                 :            :         }
     542                 :            :     }
     543                 :            : 
     544                 :         80 :     return true;
     545                 :            : }
     546                 :            : 
     547                 :            : bool
     548                 :      37731 : json_equal(const struct json *a, const struct json *b)
     549                 :            : {
     550         [ -  + ]:      37731 :     if (a->type != b->type) {
     551                 :          0 :         return false;
     552                 :            :     }
     553                 :            : 
     554   [ +  +  +  +  :      37731 :     switch (a->type) {
                +  -  - ]
     555                 :            :     case JSON_OBJECT:
     556                 :        358 :         return json_equal_object(a->u.object, b->u.object);
     557                 :            : 
     558                 :            :     case JSON_ARRAY:
     559                 :         80 :         return json_equal_array(&a->u.array, &b->u.array);
     560                 :            : 
     561                 :            :     case JSON_STRING:
     562                 :        435 :         return !strcmp(a->u.string, b->u.string);
     563                 :            : 
     564                 :            :     case JSON_NULL:
     565                 :            :     case JSON_FALSE:
     566                 :            :     case JSON_TRUE:
     567                 :          6 :         return true;
     568                 :            : 
     569                 :            :     case JSON_INTEGER:
     570                 :      36852 :         return a->u.integer == b->u.integer;
     571                 :            : 
     572                 :            :     case JSON_REAL:
     573                 :          0 :         return a->u.real == b->u.real;
     574                 :            : 
     575                 :            :     case JSON_N_TYPES:
     576                 :            :     default:
     577                 :          0 :         OVS_NOT_REACHED();
     578                 :            :     }
     579                 :            : }
     580                 :            : 
     581                 :            : /* Lexical analysis. */
     582                 :            : 
     583                 :            : static void
     584                 :     348068 : json_lex_keyword(struct json_parser *p)
     585                 :            : {
     586                 :            :     struct json_token token;
     587                 :            :     const char *s;
     588                 :            : 
     589                 :     348068 :     s = ds_cstr(&p->buffer);
     590         [ +  + ]:     348068 :     if (!strcmp(s, "false")) {
     591                 :      28922 :         token.type = T_FALSE;
     592         [ +  + ]:     319146 :     } else if (!strcmp(s, "true")) {
     593                 :     257907 :         token.type = T_TRUE;
     594         [ +  + ]:      61239 :     } else if (!strcmp(s, "null")) {
     595                 :      61230 :         token.type = T_NULL;
     596                 :            :     } else {
     597                 :          9 :         json_error(p, "invalid keyword '%s'", s);
     598                 :          9 :         return;
     599                 :            :     }
     600                 :     348059 :     json_parser_input(p, &token);
     601                 :            : }
     602                 :            : 
     603                 :            : static void
     604                 :    1712461 : json_lex_number(struct json_parser *p)
     605                 :            : {
     606                 :    1712461 :     const char *cp = ds_cstr(&p->buffer);
     607                 :    1712461 :     unsigned long long int significand = 0;
     608                 :            :     struct json_token token;
     609                 :    1712461 :     bool imprecise = false;
     610                 :    1712461 :     bool negative = false;
     611                 :    1712461 :     int pow10 = 0;
     612                 :            : 
     613                 :            :     /* Leading minus sign. */
     614         [ +  + ]:    1712461 :     if (*cp == '-') {
     615                 :       6851 :         negative = true;
     616                 :       6851 :         cp++;
     617                 :            :     }
     618                 :            : 
     619                 :            :     /* At least one integer digit, but 0 may not be used as a leading digit for
     620                 :            :      * a longer number. */
     621                 :    1712461 :     significand = 0;
     622         [ +  + ]:    1712461 :     if (*cp == '0') {
     623                 :    1210801 :         cp++;
     624         [ +  + ]:    1210801 :         if (isdigit((unsigned char) *cp)) {
     625                 :          2 :             json_error(p, "leading zeros not allowed");
     626                 :    1712218 :             return;
     627                 :            :         }
     628         [ +  - ]:     501660 :     } else if (isdigit((unsigned char) *cp)) {
     629                 :            :         do {
     630         [ +  + ]:    1530080 :             if (significand <= ULLONG_MAX / 10) {
     631                 :    1530073 :                 significand = significand * 10 + (*cp - '0');
     632                 :            :             } else {
     633                 :          7 :                 pow10++;
     634         [ -  + ]:          7 :                 if (*cp != '0') {
     635                 :          0 :                     imprecise = true;
     636                 :            :                 }
     637                 :            :             }
     638                 :    1530080 :             cp++;
     639         [ +  + ]:    1530080 :         } while (isdigit((unsigned char) *cp));
     640                 :            :     } else {
     641                 :          0 :         json_error(p, "'-' must be followed by digit");
     642                 :          0 :         return;
     643                 :            :     }
     644                 :            : 
     645                 :            :     /* Optional fraction. */
     646         [ +  + ]:    1712459 :     if (*cp == '.') {
     647                 :        380 :         cp++;
     648         [ +  + ]:        380 :         if (!isdigit((unsigned char) *cp)) {
     649                 :          2 :             json_error(p, "decimal point must be followed by digit");
     650                 :          2 :             return;
     651                 :            :         }
     652                 :            :         do {
     653         [ +  + ]:        607 :             if (significand <= ULLONG_MAX / 10) {
     654                 :        588 :                 significand = significand * 10 + (*cp - '0');
     655                 :        588 :                 pow10--;
     656         [ -  + ]:         19 :             } else if (*cp != '0') {
     657                 :          0 :                 imprecise = true;
     658                 :            :             }
     659                 :        607 :             cp++;
     660         [ +  + ]:        607 :         } while (isdigit((unsigned char) *cp));
     661                 :            :     }
     662                 :            : 
     663                 :            :     /* Optional exponent. */
     664 [ +  + ][ +  + ]:    1712457 :     if (*cp == 'e' || *cp == 'E') {
     665                 :         48 :         bool negative_exponent = false;
     666                 :            :         int exponent;
     667                 :            : 
     668                 :         48 :         cp++;
     669         [ +  + ]:         48 :         if (*cp == '+') {
     670                 :         10 :             cp++;
     671         [ +  + ]:         38 :         } else if (*cp == '-') {
     672                 :         14 :             negative_exponent = true;
     673                 :         14 :             cp++;
     674                 :            :         }
     675                 :            : 
     676         [ +  + ]:         48 :         if (!isdigit((unsigned char) *cp)) {
     677                 :          6 :             json_error(p, "exponent must contain at least one digit");
     678                 :          6 :             return;
     679                 :            :         }
     680                 :            : 
     681                 :         42 :         exponent = 0;
     682                 :            :         do {
     683         [ +  + ]:        102 :             if (exponent >= INT_MAX / 10) {
     684                 :          2 :                 json_error(p, "exponent outside valid range");
     685                 :          2 :                 return;
     686                 :            :             }
     687                 :        100 :             exponent = exponent * 10 + (*cp - '0');
     688                 :        100 :             cp++;
     689         [ +  + ]:        100 :         } while (isdigit((unsigned char) *cp));
     690                 :            : 
     691         [ +  + ]:         40 :         if (negative_exponent) {
     692                 :         12 :             pow10 -= exponent;
     693                 :            :         } else {
     694                 :         28 :             pow10 += exponent;
     695                 :            :         }
     696                 :            :     }
     697                 :            : 
     698         [ -  + ]:    1712449 :     if (*cp != '\0') {
     699                 :          0 :         json_error(p, "syntax error in number");
     700                 :          0 :         return;
     701                 :            :     }
     702                 :            : 
     703                 :            :     /* Figure out number.
     704                 :            :      *
     705                 :            :      * We suppress negative zeros as a matter of policy. */
     706         [ +  + ]:    1712449 :     if (!significand) {
     707                 :    1210715 :         token.type = T_INTEGER;
     708                 :    1210715 :         token.u.integer = 0;
     709                 :    1210715 :         json_parser_input(p, &token);
     710                 :    1210715 :         return;
     711                 :            :     }
     712                 :            : 
     713         [ +  - ]:     501734 :     if (!imprecise) {
     714 [ +  + ][ +  + ]:     501874 :         while (pow10 > 0 && significand < ULLONG_MAX / 10) {
     715                 :        140 :             significand *= 10;
     716                 :        140 :             pow10--;
     717                 :            :         }
     718 [ +  + ][ +  + ]:     501894 :         while (pow10 < 0 && significand % 10 == 0) {
     719                 :        160 :             significand /= 10;
     720                 :        160 :             pow10++;
     721                 :            :         }
     722         [ +  + ]:     501734 :         if (pow10 == 0
     723         [ +  - ]:     501489 :             && significand <= (negative
     724                 :            :                                ? (unsigned long long int) LLONG_MAX + 1
     725         [ +  + ]:     501489 :                                : LLONG_MAX)) {
     726                 :     501489 :             token.type = T_INTEGER;
     727         [ +  + ]:     501489 :             token.u.integer = negative ? -significand : significand;
     728                 :     501489 :             json_parser_input(p, &token);
     729                 :     501489 :             return;
     730                 :            :         }
     731                 :            :     }
     732                 :            : 
     733                 :        245 :     token.type = T_REAL;
     734         [ +  + ]:        245 :     if (!str_to_double(ds_cstr(&p->buffer), &token.u.real)) {
     735                 :          2 :         json_error(p, "number outside valid range");
     736                 :          2 :         return;
     737                 :            :     }
     738                 :            :     /* Suppress negative zero. */
     739         [ +  + ]:        243 :     if (token.u.real == 0) {
     740                 :          3 :         token.u.real = 0;
     741                 :            :     }
     742                 :        243 :     json_parser_input(p, &token);
     743                 :            : }
     744                 :            : 
     745                 :            : static const char *
     746                 :         19 : json_lex_4hex(const char *cp, const char *end, int *valuep)
     747                 :            : {
     748                 :            :     unsigned int value;
     749                 :            :     bool ok;
     750                 :            : 
     751         [ +  + ]:         19 :     if (cp + 4 > end) {
     752                 :          1 :         return "quoted string ends within \\u escape";
     753                 :            :     }
     754                 :            : 
     755                 :         18 :     value = hexits_value(cp, 4, &ok);
     756         [ +  + ]:         18 :     if (!ok) {
     757                 :          1 :         return "malformed \\u escape";
     758                 :            :     }
     759         [ +  + ]:         17 :     if (!value) {
     760                 :          1 :         return "null bytes not supported in quoted strings";
     761                 :            :     }
     762                 :         16 :     *valuep = value;
     763                 :         19 :     return NULL;
     764                 :            : }
     765                 :            : 
     766                 :            : static const char *
     767                 :         16 : json_lex_unicode(const char *cp, const char *end, struct ds *out)
     768                 :            : {
     769                 :            :     const char *error;
     770                 :            :     int c0, c1;
     771                 :            : 
     772                 :         16 :     error = json_lex_4hex(cp, end, &c0);
     773         [ +  + ]:         16 :     if (error) {
     774                 :          3 :         ds_clear(out);
     775                 :          3 :         ds_put_cstr(out, error);
     776                 :          3 :         return NULL;
     777                 :            :     }
     778                 :         13 :     cp += 4;
     779         [ +  + ]:         13 :     if (!uc_is_leading_surrogate(c0)) {
     780                 :          9 :         ds_put_utf8(out, c0);
     781                 :          9 :         return cp;
     782                 :            :     }
     783                 :            : 
     784 [ +  - ][ +  + ]:          4 :     if (cp + 2 > end || *cp++ != '\\' || *cp++ != 'u') {
                 [ -  + ]
     785                 :          1 :         ds_clear(out);
     786                 :          1 :         ds_put_cstr(out, "malformed escaped surrogate pair");
     787                 :          1 :         return NULL;
     788                 :            :     }
     789                 :            : 
     790                 :          3 :     error = json_lex_4hex(cp, end, &c1);
     791         [ -  + ]:          3 :     if (error) {
     792                 :          0 :         ds_clear(out);
     793                 :          0 :         ds_put_cstr(out, error);
     794                 :          0 :         return NULL;
     795                 :            :     }
     796                 :          3 :     cp += 4;
     797         [ +  + ]:          3 :     if (!uc_is_trailing_surrogate(c1)) {
     798                 :          1 :         ds_clear(out);
     799                 :          1 :         ds_put_cstr(out, "second half of escaped surrogate pair is not "
     800                 :            :                     "trailing surrogate");
     801                 :          1 :         return NULL;
     802                 :            :     }
     803                 :            : 
     804                 :          2 :     ds_put_utf8(out, utf16_decode_surrogate_pair(c0, c1));
     805                 :         16 :     return cp;
     806                 :            : }
     807                 :            : 
     808                 :            : bool
     809                 :     363499 : json_string_unescape(const char *in, size_t in_len, char **outp)
     810                 :            : {
     811                 :     363499 :     const char *end = in + in_len;
     812                 :     363499 :     bool ok = false;
     813                 :            :     struct ds out;
     814                 :            : 
     815                 :     363499 :     ds_init(&out);
     816                 :     363499 :     ds_reserve(&out, in_len);
     817         [ +  + ]:   71059940 :     while (in < end) {
     818         [ +  + ]:   70696449 :         if (*in == '"') {
     819                 :          1 :             ds_clear(&out);
     820                 :          1 :             ds_put_cstr(&out, "quoted string may not include unescaped \"");
     821                 :          1 :             goto exit;
     822                 :            :         }
     823         [ +  + ]:   70696448 :         if (*in != '\\') {
     824                 :   68802364 :             ds_put_char(&out, *in++);
     825                 :   68802364 :             continue;
     826                 :            :         }
     827                 :            : 
     828                 :    1894084 :         in++;
     829         [ +  + ]:    1894084 :         if (in >= end) {
     830                 :            :             /* The JSON parser will never trigger this message, because its
     831                 :            :              * lexer will never pass in a string that ends in a single
     832                 :            :              * backslash, but json_string_unescape() has other callers that
     833                 :            :              * are not as careful.*/
     834                 :          1 :             ds_clear(&out);
     835                 :          1 :             ds_put_cstr(&out, "quoted string may not end with backslash");
     836                 :          1 :             goto exit;
     837                 :            :         }
     838   [ +  +  +  +  :    1894083 :         switch (*in++) {
             +  +  +  + ]
     839                 :            :         case '"': case '\\': case '/':
     840                 :      20710 :             ds_put_char(&out, in[-1]);
     841                 :      20710 :             break;
     842                 :            : 
     843                 :            :         case 'b':
     844                 :          6 :             ds_put_char(&out, '\b');
     845                 :          6 :             break;
     846                 :            : 
     847                 :            :         case 'f':
     848                 :          5 :             ds_put_char(&out, '\f');
     849                 :          5 :             break;
     850                 :            : 
     851                 :            :         case 'n':
     852                 :      78970 :             ds_put_char(&out, '\n');
     853                 :      78970 :             break;
     854                 :            : 
     855                 :            :         case 'r':
     856                 :          5 :             ds_put_char(&out, '\r');
     857                 :          5 :             break;
     858                 :            : 
     859                 :            :         case 't':
     860                 :    1794370 :             ds_put_char(&out, '\t');
     861                 :    1794370 :             break;
     862                 :            : 
     863                 :            :         case 'u':
     864                 :         16 :             in = json_lex_unicode(in, end, &out);
     865         [ +  + ]:         16 :             if (!in) {
     866                 :          5 :                 goto exit;
     867                 :            :             }
     868                 :         11 :             break;
     869                 :            : 
     870                 :            :         default:
     871                 :          1 :             ds_clear(&out);
     872                 :          1 :             ds_put_format(&out, "bad escape \\%c", in[-1]);
     873                 :          1 :             goto exit;
     874                 :            :         }
     875                 :            :     }
     876                 :     363491 :     ok = true;
     877                 :            : 
     878                 :            : exit:
     879                 :     363499 :     *outp = ds_cstr(&out);
     880                 :     363499 :     return ok;
     881                 :            : }
     882                 :            : 
     883                 :            : void
     884                 :      30565 : json_string_escape(const char *in, struct ds *out)
     885                 :            : {
     886                 :      30565 :     struct json json = {
     887                 :            :         .type = JSON_STRING,
     888                 :            :         .u.string = CONST_CAST(char *, in),
     889                 :            :     };
     890                 :      30565 :     json_to_ds(&json, 0, out);
     891                 :      30565 : }
     892                 :            : 
     893                 :            : static void
     894                 :   13386107 : json_parser_input_string(struct json_parser *p, const char *s)
     895                 :            : {
     896                 :            :     struct json_token token;
     897                 :            : 
     898                 :   13386107 :     token.type = T_STRING;
     899                 :   13386107 :     token.u.string = s;
     900                 :   13386107 :     json_parser_input(p, &token);
     901                 :   13386107 : }
     902                 :            : 
     903                 :            : static void
     904                 :   13386113 : json_lex_string(struct json_parser *p)
     905                 :            : {
     906                 :   13386113 :     const char *raw = ds_cstr(&p->buffer);
     907         [ +  + ]:   13386113 :     if (!strchr(raw, '\\')) {
     908                 :   13373576 :         json_parser_input_string(p, raw);
     909                 :            :     } else {
     910                 :            :         char *cooked;
     911                 :            : 
     912         [ +  + ]:      12537 :         if (json_string_unescape(raw, strlen(raw), &cooked)) {
     913                 :      12531 :             json_parser_input_string(p, cooked);
     914                 :            :         } else {
     915                 :          6 :             json_error(p, "%s", cooked);
     916                 :            :         }
     917                 :            : 
     918                 :      12537 :         free(cooked);
     919                 :            :     }
     920                 :   13386113 : }
     921                 :            : 
     922                 :            : static bool
     923                 :  230784751 : json_lex_input(struct json_parser *p, unsigned char c)
     924                 :            : {
     925                 :            :     struct json_token token;
     926                 :            : 
     927   [ +  +  +  +  :  230784751 :     switch (p->lex_state) {
                   +  - ]
     928                 :            :     case JSON_LEX_START:
     929   [ +  +  +  +  :   48273494 :         switch (c) {
                   +  + ]
     930                 :            :         case ' ': case '\t': case '\n': case '\r':
     931                 :            :             /* Nothing to do. */
     932                 :    7380269 :             return true;
     933                 :            : 
     934                 :            :         case 'a': case 'b': case 'c': case 'd': case 'e':
     935                 :            :         case 'f': case 'g': case 'h': case 'i': case 'j':
     936                 :            :         case 'k': case 'l': case 'm': case 'n': case 'o':
     937                 :            :         case 'p': case 'q': case 'r': case 's': case 't':
     938                 :            :         case 'u': case 'v': case 'w': case 'x': case 'y':
     939                 :            :         case 'z':
     940                 :     348064 :             p->lex_state = JSON_LEX_KEYWORD;
     941                 :     348064 :             break;
     942                 :            : 
     943                 :            :         case '[': case '{': case ']': case '}': case ':': case ',':
     944                 :   25446588 :             token.type = c;
     945                 :   25446588 :             json_parser_input(p, &token);
     946                 :   25446588 :             return true;
     947                 :            : 
     948                 :            :         case '-':
     949                 :            :         case '0': case '1': case '2': case '3': case '4':
     950                 :            :         case '5': case '6': case '7': case '8': case '9':
     951                 :    1712454 :             p->lex_state = JSON_LEX_NUMBER;
     952                 :    1712454 :             break;
     953                 :            : 
     954                 :            :         case '"':
     955                 :   13386117 :             p->lex_state = JSON_LEX_STRING;
     956                 :   13386117 :             return true;
     957                 :            : 
     958                 :            :         default:
     959         [ +  + ]:          2 :             if (isprint(c)) {
     960                 :          1 :                 json_error(p, "invalid character '%c'", c);
     961                 :            :             } else {
     962                 :          1 :                 json_error(p, "invalid character U+%04x", c);
     963                 :            :             }
     964                 :          2 :             return true;
     965                 :            :         }
     966                 :    2060518 :         break;
     967                 :            : 
     968                 :            :     case JSON_LEX_KEYWORD:
     969         [ +  + ]:    1421178 :         if (!isalpha((unsigned char) c)) {
     970                 :     348068 :             json_lex_keyword(p);
     971                 :     348068 :             return false;
     972                 :            :         }
     973                 :    1073110 :         break;
     974                 :            : 
     975                 :            :     case JSON_LEX_NUMBER:
     976         [ +  + ]:    2748883 :         if (!strchr(".0123456789eE-+", c)) {
     977                 :    1712461 :             json_lex_number(p);
     978                 :    1712461 :             return false;
     979                 :            :         }
     980                 :    1036422 :         break;
     981                 :            : 
     982                 :            :     case JSON_LEX_STRING:
     983         [ +  + ]:  176447126 :         if (c == '\\') {
     984                 :    1894070 :             p->lex_state = JSON_LEX_ESCAPE;
     985         [ +  + ]:  174553056 :         } else if (c == '"') {
     986                 :   13386113 :             json_lex_string(p);
     987                 :   13386113 :             return true;
     988         [ +  + ]:  161166943 :         } else if (c < 0x20) {
     989                 :          2 :             json_error(p, "U+%04X must be escaped in quoted string", c);
     990                 :          2 :             return true;
     991                 :            :         }
     992                 :  163061011 :         break;
     993                 :            : 
     994                 :            :     case JSON_LEX_ESCAPE:
     995                 :    1894070 :         p->lex_state = JSON_LEX_STRING;
     996                 :    1894070 :         break;
     997                 :            : 
     998                 :            :     default:
     999                 :          0 :         abort();
    1000                 :            :     }
    1001                 :  169125131 :     ds_put_char(&p->buffer, c);
    1002                 :  230784751 :     return true;
    1003                 :            : }
    1004                 :            : 
    1005                 :            : /* Parsing. */
    1006                 :            : 
    1007                 :            : /* Parses 'string' as a JSON object or array and returns a newly allocated
    1008                 :            :  * 'struct json'.  The caller must free the returned structure with
    1009                 :            :  * json_destroy() when it is no longer needed.
    1010                 :            :  *
    1011                 :            :  * 'string' must be encoded in UTF-8.
    1012                 :            :  *
    1013                 :            :  * If 'string' is valid JSON, then the returned 'struct json' will be either an
    1014                 :            :  * object (JSON_OBJECT) or an array (JSON_ARRAY).
    1015                 :            :  *
    1016                 :            :  * If 'string' is not valid JSON, then the returned 'struct json' will be a
    1017                 :            :  * string (JSON_STRING) that describes the particular error encountered during
    1018                 :            :  * parsing.  (This is an acceptable means of error reporting because at its top
    1019                 :            :  * level JSON must be either an object or an array; a bare string is not
    1020                 :            :  * valid.) */
    1021                 :            : struct json *
    1022                 :       2087 : json_from_string(const char *string)
    1023                 :            : {
    1024                 :       2087 :     struct json_parser *p = json_parser_create(JSPF_TRAILER);
    1025                 :       2087 :     json_parser_feed(p, string, strlen(string));
    1026                 :       2087 :     return json_parser_finish(p);
    1027                 :            : }
    1028                 :            : 
    1029                 :            : /* Reads the file named 'file_name', parses its contents as a JSON object or
    1030                 :            :  * array, and returns a newly allocated 'struct json'.  The caller must free
    1031                 :            :  * the returned structure with json_destroy() when it is no longer needed.
    1032                 :            :  *
    1033                 :            :  * The file must be encoded in UTF-8.
    1034                 :            :  *
    1035                 :            :  * See json_from_string() for return value semantics.
    1036                 :            :  */
    1037                 :            : struct json *
    1038                 :       1263 : json_from_file(const char *file_name)
    1039                 :            : {
    1040                 :            :     struct json *json;
    1041                 :            :     FILE *stream;
    1042                 :            : 
    1043                 :       1263 :     stream = fopen(file_name, "r");
    1044         [ -  + ]:       1263 :     if (!stream) {
    1045                 :          0 :         return json_string_create_nocopy(
    1046                 :            :             xasprintf("error opening \"%s\": %s", file_name,
    1047                 :          0 :                       ovs_strerror(errno)));
    1048                 :            :     }
    1049                 :       1263 :     json = json_from_stream(stream);
    1050                 :       1263 :     fclose(stream);
    1051                 :            : 
    1052                 :       1263 :     return json;
    1053                 :            : }
    1054                 :            : 
    1055                 :            : /* Parses the contents of 'stream' as a JSON object or array, and returns a
    1056                 :            :  * newly allocated 'struct json'.  The caller must free the returned structure
    1057                 :            :  * with json_destroy() when it is no longer needed.
    1058                 :            :  *
    1059                 :            :  * The file must be encoded in UTF-8.
    1060                 :            :  *
    1061                 :            :  * See json_from_string() for return value semantics.
    1062                 :            :  */
    1063                 :            : struct json *
    1064                 :       2589 : json_from_stream(FILE *stream)
    1065                 :            : {
    1066                 :            :     struct json_parser *p;
    1067                 :            :     struct json *json;
    1068                 :            : 
    1069                 :       2589 :     p = json_parser_create(JSPF_TRAILER);
    1070                 :            :     for (;;) {
    1071                 :            :         char buffer[BUFSIZ];
    1072                 :            :         size_t n;
    1073                 :            : 
    1074                 :       6611 :         n = fread(buffer, 1, sizeof buffer, stream);
    1075 [ +  + ][ +  + ]:       6611 :         if (!n || json_parser_feed(p, buffer, n) != n) {
    1076                 :            :             break;
    1077                 :            :         }
    1078                 :       4022 :     }
    1079                 :       2589 :     json = json_parser_finish(p);
    1080                 :            : 
    1081         [ -  + ]:       2589 :     if (ferror(stream)) {
    1082                 :          0 :         json_destroy(json);
    1083                 :          0 :         json = json_string_create_nocopy(
    1084                 :          0 :             xasprintf("error reading JSON stream: %s", ovs_strerror(errno)));
    1085                 :            :     }
    1086                 :            : 
    1087                 :       2589 :     return json;
    1088                 :            : }
    1089                 :            : 
    1090                 :            : struct json_parser *
    1091                 :     101318 : json_parser_create(int flags)
    1092                 :            : {
    1093                 :     101318 :     struct json_parser *p = xzalloc(sizeof *p);
    1094                 :     101318 :     p->flags = flags;
    1095                 :     101318 :     return p;
    1096                 :            : }
    1097                 :            : 
    1098                 :            : size_t
    1099                 :     481638 : json_parser_feed(struct json_parser *p, const char *input, size_t n)
    1100                 :            : {
    1101                 :            :     size_t i;
    1102 [ +  + ][ +  + ]:  231266374 :     for (i = 0; !p->done && i < n; ) {
    1103         [ +  + ]:  230784736 :         if (json_lex_input(p, input[i])) {
    1104                 :  228724222 :             p->byte_number++;
    1105         [ +  + ]:  228724222 :             if (input[i] == '\n') {
    1106                 :     499323 :                 p->column_number = 0;
    1107                 :     499323 :                 p->line_number++;
    1108                 :            :             } else {
    1109                 :  228224899 :                 p->column_number++;
    1110                 :            :             }
    1111                 :  228724222 :             i++;
    1112                 :            :         }
    1113                 :            :     }
    1114                 :     481638 :     return i;
    1115                 :            : }
    1116                 :            : 
    1117                 :            : bool
    1118                 :     472543 : json_parser_is_done(const struct json_parser *p)
    1119                 :            : {
    1120                 :     472543 :     return p->done;
    1121                 :            : }
    1122                 :            : 
    1123                 :            : struct json *
    1124                 :     101317 : json_parser_finish(struct json_parser *p)
    1125                 :            : {
    1126                 :            :     struct json *json;
    1127                 :            : 
    1128   [ +  +  +  - ]:     101317 :     switch (p->lex_state) {
    1129                 :            :     case JSON_LEX_START:
    1130                 :     101292 :         break;
    1131                 :            : 
    1132                 :            :     case JSON_LEX_STRING:
    1133                 :            :     case JSON_LEX_ESCAPE:
    1134                 :         10 :         json_error(p, "unexpected end of input in quoted string");
    1135                 :         10 :         break;
    1136                 :            : 
    1137                 :            :     case JSON_LEX_NUMBER:
    1138                 :            :     case JSON_LEX_KEYWORD:
    1139                 :         15 :         json_lex_input(p, ' ');
    1140                 :         15 :         break;
    1141                 :            :     }
    1142                 :            : 
    1143         [ +  + ]:     101317 :     if (p->parse_state == JSON_PARSE_START) {
    1144                 :          9 :         json_error(p, "empty input stream");
    1145         [ +  + ]:     101308 :     } else if (p->parse_state != JSON_PARSE_END) {
    1146                 :         31 :         json_error(p, "unexpected end of input");
    1147                 :            :     }
    1148                 :            : 
    1149         [ +  + ]:     101317 :     if (!p->error) {
    1150         [ -  + ]:     101276 :         ovs_assert(p->height == 1);
    1151         [ -  + ]:     101276 :         ovs_assert(p->stack[0].json != NULL);
    1152                 :     101276 :         json = p->stack[--p->height].json;
    1153                 :            :     } else {
    1154                 :         41 :         json = json_string_create_nocopy(p->error);
    1155                 :         41 :         p->error = NULL;
    1156                 :            :     }
    1157                 :            : 
    1158                 :     101317 :     json_parser_abort(p);
    1159                 :            : 
    1160                 :     101317 :     return json;
    1161                 :            : }
    1162                 :            : 
    1163                 :            : void
    1164                 :     155910 : json_parser_abort(struct json_parser *p)
    1165                 :            : {
    1166         [ +  + ]:     155910 :     if (p) {
    1167                 :     101318 :         ds_destroy(&p->buffer);
    1168         [ +  + ]:     101318 :         if (p->height) {
    1169                 :         32 :             json_destroy(p->stack[0].json);
    1170                 :            :         }
    1171                 :     101318 :         free(p->stack);
    1172                 :     101318 :         free(p->member_name);
    1173                 :     101318 :         free(p->error);
    1174                 :     101318 :         free(p);
    1175                 :            :     }
    1176                 :     155910 : }
    1177                 :            : 
    1178                 :            : static struct json_parser_node *
    1179                 :   21412318 : json_parser_top(struct json_parser *p)
    1180                 :            : {
    1181                 :   21412318 :     return &p->stack[p->height - 1];
    1182                 :            : }
    1183                 :            : 
    1184                 :            : static void
    1185                 :   11476291 : json_parser_put_value(struct json_parser *p, struct json *value)
    1186                 :            : {
    1187                 :   11476291 :     struct json_parser_node *node = json_parser_top(p);
    1188         [ +  + ]:   11476291 :     if (node->json->type == JSON_OBJECT) {
    1189                 :    8889683 :         json_object_put(node->json, p->member_name, value);
    1190                 :    8889683 :         free(p->member_name);
    1191                 :    8889683 :         p->member_name = NULL;
    1192         [ +  - ]:    2586608 :     } else if (node->json->type == JSON_ARRAY) {
    1193                 :    2586608 :         json_array_add(node->json, value);
    1194                 :            :     } else {
    1195                 :          0 :         OVS_NOT_REACHED();
    1196                 :            :     }
    1197                 :   11476291 : }
    1198                 :            : 
    1199                 :            : static void
    1200                 :    5020683 : json_parser_push(struct json_parser *p,
    1201                 :            :                  struct json *new_json, enum json_parse_state new_state)
    1202                 :            : {
    1203         [ +  + ]:    5020683 :     if (p->height < JSON_MAX_HEIGHT) {
    1204                 :            :         struct json_parser_node *node;
    1205                 :            : 
    1206         [ +  + ]:    5020681 :         if (p->height >= p->allocated_height) {
    1207                 :     329286 :             p->stack = x2nrealloc(p->stack, &p->allocated_height,
    1208                 :            :                                   sizeof *p->stack);
    1209                 :            :         }
    1210                 :            : 
    1211         [ +  + ]:    5020681 :         if (p->height > 0) {
    1212                 :    4919373 :             json_parser_put_value(p, new_json);
    1213                 :            :         }
    1214                 :            : 
    1215                 :    5020681 :         node = &p->stack[p->height++];
    1216                 :    5020681 :         node->json = new_json;
    1217                 :    5020681 :         p->parse_state = new_state;
    1218                 :            :     } else {
    1219                 :          2 :         json_destroy(new_json);
    1220                 :          2 :         json_error(p, "input exceeds maximum nesting depth %d",
    1221                 :            :                    JSON_MAX_HEIGHT);
    1222                 :            :     }
    1223                 :    5020683 : }
    1224                 :            : 
    1225                 :            : static void
    1226                 :    3835700 : json_parser_push_object(struct json_parser *p)
    1227                 :            : {
    1228                 :    3835700 :     json_parser_push(p, json_object_create(), JSON_PARSE_OBJECT_INIT);
    1229                 :    3835700 : }
    1230                 :            : 
    1231                 :            : static void
    1232                 :    1184983 : json_parser_push_array(struct json_parser *p)
    1233                 :            : {
    1234                 :    1184983 :     json_parser_push(p, json_array_create_empty(), JSON_PARSE_ARRAY_INIT);
    1235                 :    1184983 : }
    1236                 :            : 
    1237                 :            : static void
    1238                 :   11476296 : json_parse_value(struct json_parser *p, struct json_token *token,
    1239                 :            :                  enum json_parse_state next_state)
    1240                 :            : {
    1241                 :            :     struct json *value;
    1242                 :            : 
    1243   [ +  +  +  +  :   11476296 :     switch (token->type) {
             +  +  +  +  
                      + ]
    1244                 :            :     case T_FALSE:
    1245                 :      28922 :         value = json_boolean_create(false);
    1246                 :      28922 :         break;
    1247                 :            : 
    1248                 :            :     case T_NULL:
    1249                 :      61227 :         value = json_null_create();
    1250                 :      61227 :         break;
    1251                 :            : 
    1252                 :            :     case T_TRUE:
    1253                 :     257907 :         value = json_boolean_create(true);
    1254                 :     257907 :         break;
    1255                 :            : 
    1256                 :            :     case '{':
    1257                 :    3736344 :         json_parser_push_object(p);
    1258                 :    3736344 :         return;
    1259                 :            : 
    1260                 :            :     case '[':
    1261                 :    1183031 :         json_parser_push_array(p);
    1262                 :    1183031 :         return;
    1263                 :            : 
    1264                 :            :     case T_INTEGER:
    1265                 :    1712200 :         value = json_integer_create(token->u.integer);
    1266                 :    1712200 :         break;
    1267                 :            : 
    1268                 :            :     case T_REAL:
    1269                 :        243 :         value = json_real_create(token->u.real);
    1270                 :        243 :         break;
    1271                 :            : 
    1272                 :            :     case T_STRING:
    1273                 :    4496419 :         value = json_string_create(token->u.string);
    1274                 :    4496419 :         break;
    1275                 :            : 
    1276                 :            :     case T_EOF:
    1277                 :            :     case '}':
    1278                 :            :     case ']':
    1279                 :            :     case ':':
    1280                 :            :     case ',':
    1281                 :            :     default:
    1282                 :          3 :         json_error(p, "syntax error expecting value");
    1283                 :          3 :         return;
    1284                 :            :     }
    1285                 :            : 
    1286                 :    6556918 :     json_parser_put_value(p, value);
    1287                 :    6556918 :     p->parse_state = next_state;
    1288                 :            : }
    1289                 :            : 
    1290                 :            : static void
    1291                 :    5018652 : json_parser_pop(struct json_parser *p)
    1292                 :            : {
    1293                 :            :     struct json_parser_node *node;
    1294                 :            : 
    1295                 :            :     /* Conserve memory. */
    1296                 :    5018652 :     node = json_parser_top(p);
    1297         [ +  + ]:    5018652 :     if (node->json->type == JSON_ARRAY) {
    1298                 :    1183959 :         json_array_trim(node->json);
    1299                 :            :     }
    1300                 :            : 
    1301                 :            :     /* Pop off the top-of-stack. */
    1302         [ +  + ]:    5018652 :     if (p->height == 1) {
    1303                 :     101277 :         p->parse_state = JSON_PARSE_END;
    1304         [ +  + ]:     101277 :         if (!(p->flags & JSPF_TRAILER)) {
    1305                 :     101277 :             p->done = true;
    1306                 :            :         }
    1307                 :            :     } else {
    1308                 :    4917375 :         p->height--;
    1309                 :    4917375 :         node = json_parser_top(p);
    1310         [ +  + ]:    4917375 :         if (node->json->type == JSON_ARRAY) {
    1311                 :     806870 :             p->parse_state = JSON_PARSE_ARRAY_NEXT;
    1312         [ +  - ]:    4110505 :         } else if (node->json->type == JSON_OBJECT) {
    1313                 :    4110505 :             p->parse_state = JSON_PARSE_OBJECT_NEXT;
    1314                 :            :         } else {
    1315                 :          0 :             OVS_NOT_REACHED();
    1316                 :            :         }
    1317                 :            :     }
    1318                 :    5018652 : }
    1319                 :            : 
    1320                 :            : static void
    1321                 :   40893201 : json_parser_input(struct json_parser *p, struct json_token *token)
    1322                 :            : {
    1323   [ +  +  +  +  :   40893201 :     switch (p->parse_state) {
          +  +  +  +  +  
                   +  - ]
    1324                 :            :     case JSON_PARSE_START:
    1325         [ +  + ]:     101312 :         if (token->type == '{') {
    1326                 :      99356 :             json_parser_push_object(p);
    1327         [ +  + ]:       1956 :         } else if (token->type == '[') {
    1328                 :       1952 :             json_parser_push_array(p);
    1329                 :            :         } else {
    1330                 :          4 :             json_error(p, "syntax error at beginning of input");
    1331                 :            :         }
    1332                 :     101312 :         break;
    1333                 :            : 
    1334                 :            :     case JSON_PARSE_END:
    1335                 :          1 :         json_error(p, "trailing garbage at end of input");
    1336                 :          1 :         break;
    1337                 :            : 
    1338                 :            :     case JSON_PARSE_OBJECT_INIT:
    1339         [ +  + ]:    3835699 :         if (token->type == '}') {
    1340                 :      43175 :             json_parser_pop(p);
    1341                 :      43175 :             break;
    1342                 :            :         }
    1343                 :            :         /* Fall through. */
    1344                 :            :     case JSON_PARSE_OBJECT_NAME:
    1345         [ +  + ]:    8889689 :         if (token->type == T_STRING) {
    1346                 :    8889686 :             p->member_name = xstrdup(token->u.string);
    1347                 :    8889686 :             p->parse_state = JSON_PARSE_OBJECT_COLON;
    1348                 :            :         } else {
    1349                 :          3 :             json_error(p, "syntax error parsing object expecting string");
    1350                 :            :         }
    1351                 :    8889689 :         break;
    1352                 :            : 
    1353                 :            :     case JSON_PARSE_OBJECT_COLON:
    1354         [ +  + ]:    8889686 :         if (token->type == ':') {
    1355                 :    8889685 :             p->parse_state = JSON_PARSE_OBJECT_VALUE;
    1356                 :            :         } else {
    1357                 :          1 :             json_error(p, "syntax error parsing object expecting ':'");
    1358                 :            :         }
    1359                 :    8889686 :         break;
    1360                 :            : 
    1361                 :            :     case JSON_PARSE_OBJECT_VALUE:
    1362                 :    8889685 :         json_parse_value(p, token, JSON_PARSE_OBJECT_NEXT);
    1363                 :    8889685 :         break;
    1364                 :            : 
    1365                 :            :     case JSON_PARSE_OBJECT_NEXT:
    1366         [ +  + ]:    8888684 :         if (token->type == ',') {
    1367                 :    5097165 :             p->parse_state = JSON_PARSE_OBJECT_NAME;
    1368         [ +  + ]:    3791519 :         } else if (token->type == '}') {
    1369                 :    3791518 :             json_parser_pop(p);
    1370                 :            :         } else {
    1371                 :          1 :             json_error(p, "syntax error expecting '}' or ','");
    1372                 :            :         }
    1373                 :    8888684 :         break;
    1374                 :            : 
    1375                 :            :     case JSON_PARSE_ARRAY_INIT:
    1376         [ +  + ]:    1184962 :         if (token->type == ']') {
    1377                 :      18749 :             json_parser_pop(p);
    1378                 :      18749 :             break;
    1379                 :            :         }
    1380                 :            :         /* Fall through. */
    1381                 :            :     case JSON_PARSE_ARRAY_VALUE:
    1382                 :    2586611 :         json_parse_value(p, token, JSON_PARSE_ARRAY_NEXT);
    1383                 :    2586611 :         break;
    1384                 :            : 
    1385                 :            :     case JSON_PARSE_ARRAY_NEXT:
    1386         [ +  + ]:    2585609 :         if (token->type == ',') {
    1387                 :    1420398 :             p->parse_state = JSON_PARSE_ARRAY_VALUE;
    1388         [ +  + ]:    1165211 :         } else if (token->type == ']') {
    1389                 :    1165210 :             json_parser_pop(p);
    1390                 :            :         } else {
    1391                 :          1 :             json_error(p, "syntax error expecting ']' or ','");
    1392                 :            :         }
    1393                 :    2585609 :         break;
    1394                 :            : 
    1395                 :            :     default:
    1396                 :          0 :         abort();
    1397                 :            :     }
    1398                 :            : 
    1399                 :   40893201 :     p->lex_state = JSON_LEX_START;
    1400                 :   40893201 :     ds_clear(&p->buffer);
    1401                 :   40893201 : }
    1402                 :            : 
    1403                 :            : static struct json *
    1404                 :   30754355 : json_create(enum json_type type)
    1405                 :            : {
    1406                 :   30754355 :     struct json *json = xmalloc(sizeof *json);
    1407                 :   30754355 :     json->type = type;
    1408                 :   30754355 :     return json;
    1409                 :            : }
    1410                 :            : 
    1411                 :            : static void
    1412                 :         99 : json_error(struct json_parser *p, const char *format, ...)
    1413                 :            : {
    1414         [ +  + ]:         99 :     if (!p->error) {
    1415                 :            :         struct ds msg;
    1416                 :            :         va_list args;
    1417                 :            : 
    1418                 :         41 :         ds_init(&msg);
    1419                 :         41 :         ds_put_format(&msg, "line %d, column %d, byte %d: ",
    1420                 :            :                       p->line_number, p->column_number, p->byte_number);
    1421                 :         41 :         va_start(args, format);
    1422                 :         41 :         ds_put_format_valist(&msg, format, args);
    1423                 :         41 :         va_end(args);
    1424                 :            : 
    1425                 :         41 :         p->error = ds_steal_cstr(&msg);
    1426                 :            : 
    1427                 :         41 :         p->done = true;
    1428                 :            :     }
    1429                 :         99 : }
    1430                 :            : 
    1431                 :            : #define SPACES_PER_LEVEL 2
    1432                 :            : 
    1433                 :            : struct json_serializer {
    1434                 :            :     struct ds *ds;
    1435                 :            :     int depth;
    1436                 :            :     int flags;
    1437                 :            : };
    1438                 :            : 
    1439                 :            : static void json_serialize(const struct json *, struct json_serializer *);
    1440                 :            : static void json_serialize_object(const struct shash *object,
    1441                 :            :                                   struct json_serializer *);
    1442                 :            : static void json_serialize_array(const struct json_array *,
    1443                 :            :                                  struct json_serializer *);
    1444                 :            : static void json_serialize_string(const char *, struct ds *);
    1445                 :            : 
    1446                 :            : /* Converts 'json' to a string in JSON format, encoded in UTF-8, and returns
    1447                 :            :  * that string.  The caller is responsible for freeing the returned string,
    1448                 :            :  * with free(), when it is no longer needed.
    1449                 :            :  *
    1450                 :            :  * If 'flags' contains JSSF_PRETTY, the output is pretty-printed with each
    1451                 :            :  * nesting level introducing an additional indentation.  Otherwise, the
    1452                 :            :  * returned string does not contain any new-line characters.
    1453                 :            :  *
    1454                 :            :  * If 'flags' contains JSSF_SORT, members of objects in the output are sorted
    1455                 :            :  * in bytewise lexicographic order for reproducibility.  Otherwise, members of
    1456                 :            :  * objects are output in an indeterminate order.
    1457                 :            :  *
    1458                 :            :  * The returned string is valid JSON only if 'json' represents an array or an
    1459                 :            :  * object, since a bare literal does not satisfy the JSON grammar. */
    1460                 :            : char *
    1461                 :      54211 : json_to_string(const struct json *json, int flags)
    1462                 :            : {
    1463                 :            :     struct ds ds;
    1464                 :            : 
    1465                 :      54211 :     ds_init(&ds);
    1466                 :      54211 :     json_to_ds(json, flags, &ds);
    1467                 :      54211 :     return ds_steal_cstr(&ds);
    1468                 :            : }
    1469                 :            : 
    1470                 :            : /* Same as json_to_string(), but the output is appended to 'ds'. */
    1471                 :            : void
    1472                 :     183945 : json_to_ds(const struct json *json, int flags, struct ds *ds)
    1473                 :            : {
    1474                 :            :     struct json_serializer s;
    1475                 :            : 
    1476                 :     183945 :     s.ds = ds;
    1477                 :     183945 :     s.depth = 0;
    1478                 :     183945 :     s.flags = flags;
    1479                 :     183945 :     json_serialize(json, &s);
    1480                 :     183945 : }
    1481                 :            : 
    1482                 :            : static void
    1483                 :   11403963 : json_serialize(const struct json *json, struct json_serializer *s)
    1484                 :            : {
    1485                 :   11403963 :     struct ds *ds = s->ds;
    1486                 :            : 
    1487   [ +  +  +  +  :   11403963 :     switch (json->type) {
             +  +  +  +  
                      - ]
    1488                 :            :     case JSON_NULL:
    1489                 :      64579 :         ds_put_cstr(ds, "null");
    1490                 :      64579 :         break;
    1491                 :            : 
    1492                 :            :     case JSON_FALSE:
    1493                 :      31264 :         ds_put_cstr(ds, "false");
    1494                 :      31264 :         break;
    1495                 :            : 
    1496                 :            :     case JSON_TRUE:
    1497                 :     228180 :         ds_put_cstr(ds, "true");
    1498                 :     228180 :         break;
    1499                 :            : 
    1500                 :            :     case JSON_OBJECT:
    1501                 :    3508730 :         json_serialize_object(json->u.object, s);
    1502                 :    3508730 :         break;
    1503                 :            : 
    1504                 :            :     case JSON_ARRAY:
    1505                 :    1479653 :         json_serialize_array(&json->u.array, s);
    1506                 :    1479653 :         break;
    1507                 :            : 
    1508                 :            :     case JSON_INTEGER:
    1509                 :    1548936 :         ds_put_format(ds, "%lld", json->u.integer);
    1510                 :    1548936 :         break;
    1511                 :            : 
    1512                 :            :     case JSON_REAL:
    1513                 :        737 :         ds_put_format(ds, "%.*g", DBL_DIG, json->u.real);
    1514                 :        737 :         break;
    1515                 :            : 
    1516                 :            :     case JSON_STRING:
    1517                 :    4541884 :         json_serialize_string(json->u.string, ds);
    1518                 :    4541884 :         break;
    1519                 :            : 
    1520                 :            :     case JSON_N_TYPES:
    1521                 :            :     default:
    1522                 :          0 :         OVS_NOT_REACHED();
    1523                 :            :     }
    1524                 :   11403963 : }
    1525                 :            : 
    1526                 :            : static void
    1527                 :   11263735 : indent_line(struct json_serializer *s)
    1528                 :            : {
    1529         [ -  + ]:   11263735 :     if (s->flags & JSSF_PRETTY) {
    1530                 :          0 :         ds_put_char(s->ds, '\n');
    1531                 :          0 :         ds_put_char_multiple(s->ds, ' ', SPACES_PER_LEVEL * s->depth);
    1532                 :            :     }
    1533                 :   11263735 : }
    1534                 :            : 
    1535                 :            : static void
    1536                 :    8240244 : json_serialize_object_member(size_t i, const struct shash_node *node,
    1537                 :            :                              struct json_serializer *s)
    1538                 :            : {
    1539                 :    8240244 :     struct ds *ds = s->ds;
    1540                 :            : 
    1541         [ +  + ]:    8240244 :     if (i) {
    1542                 :    4775231 :         ds_put_char(ds, ',');
    1543                 :    4775231 :         indent_line(s);
    1544                 :            :     }
    1545                 :            : 
    1546                 :    8240244 :     json_serialize_string(node->name, ds);
    1547                 :    8240244 :     ds_put_char(ds, ':');
    1548         [ -  + ]:    8240244 :     if (s->flags & JSSF_PRETTY) {
    1549                 :          0 :         ds_put_char(ds, ' ');
    1550                 :            :     }
    1551                 :    8240244 :     json_serialize(node->data, s);
    1552                 :    8240244 : }
    1553                 :            : 
    1554                 :            : static void
    1555                 :    3508730 : json_serialize_object(const struct shash *object, struct json_serializer *s)
    1556                 :            : {
    1557                 :    3508730 :     struct ds *ds = s->ds;
    1558                 :            : 
    1559                 :    3508730 :     ds_put_char(ds, '{');
    1560                 :            : 
    1561                 :    3508730 :     s->depth++;
    1562                 :    3508730 :     indent_line(s);
    1563                 :            : 
    1564         [ +  + ]:    3508730 :     if (s->flags & JSSF_SORT) {
    1565                 :            :         const struct shash_node **nodes;
    1566                 :            :         size_t n, i;
    1567                 :            : 
    1568                 :       3036 :         nodes = shash_sort(object);
    1569                 :       3036 :         n = shash_count(object);
    1570         [ +  + ]:       7982 :         for (i = 0; i < n; i++) {
    1571                 :       4946 :             json_serialize_object_member(i, nodes[i], s);
    1572                 :            :         }
    1573                 :       3036 :         free(nodes);
    1574                 :            :     } else {
    1575                 :            :         struct shash_node *node;
    1576                 :            :         size_t i;
    1577                 :            : 
    1578                 :    3505694 :         i = 0;
    1579 [ +  + ][ -  + ]:   11740992 :         SHASH_FOR_EACH (node, object) {
    1580                 :    8235298 :             json_serialize_object_member(i++, node, s);
    1581                 :            :         }
    1582                 :            :     }
    1583                 :            : 
    1584                 :    3508730 :     ds_put_char(ds, '}');
    1585                 :    3508730 :     s->depth--;
    1586                 :    3508730 : }
    1587                 :            : 
    1588                 :            : static void
    1589                 :    1479653 : json_serialize_array(const struct json_array *array, struct json_serializer *s)
    1590                 :            : {
    1591                 :    1479653 :     struct ds *ds = s->ds;
    1592                 :            :     size_t i;
    1593                 :            : 
    1594                 :    1479653 :     ds_put_char(ds, '[');
    1595                 :    1479653 :     s->depth++;
    1596                 :            : 
    1597         [ +  + ]:    1479653 :     if (array->n > 0) {
    1598                 :    1345923 :         indent_line(s);
    1599                 :            : 
    1600         [ +  + ]:    4325697 :         for (i = 0; i < array->n; i++) {
    1601         [ +  + ]:    2979774 :             if (i) {
    1602                 :    1633851 :                 ds_put_char(ds, ',');
    1603                 :    1633851 :                 indent_line(s);
    1604                 :            :             }
    1605                 :    2979774 :             json_serialize(array->elems[i], s);
    1606                 :            :         }
    1607                 :            :     }
    1608                 :            : 
    1609                 :    1479653 :     s->depth--;
    1610                 :    1479653 :     ds_put_char(ds, ']');
    1611                 :    1479653 : }
    1612                 :            : 
    1613                 :            : static void
    1614                 :   12782128 : json_serialize_string(const char *string, struct ds *ds)
    1615                 :            : {
    1616                 :            :     uint8_t c;
    1617                 :            : 
    1618                 :   12782128 :     ds_put_char(ds, '"');
    1619         [ +  + ]:  177263600 :     while ((c = *string++) != '\0') {
    1620   [ +  +  +  +  :  164481472 :         switch (c) {
             +  +  +  + ]
    1621                 :            :         case '"':
    1622                 :      22348 :             ds_put_cstr(ds, "\\\"");
    1623                 :      22348 :             break;
    1624                 :            : 
    1625                 :            :         case '\\':
    1626                 :        573 :             ds_put_cstr(ds, "\\\\");
    1627                 :        573 :             break;
    1628                 :            : 
    1629                 :            :         case '\b':
    1630                 :          7 :             ds_put_cstr(ds, "\\b");
    1631                 :          7 :             break;
    1632                 :            : 
    1633                 :            :         case '\f':
    1634                 :          6 :             ds_put_cstr(ds, "\\f");
    1635                 :          6 :             break;
    1636                 :            : 
    1637                 :            :         case '\n':
    1638                 :      75300 :             ds_put_cstr(ds, "\\n");
    1639                 :      75300 :             break;
    1640                 :            : 
    1641                 :            :         case '\r':
    1642                 :          6 :             ds_put_cstr(ds, "\\r");
    1643                 :          6 :             break;
    1644                 :            : 
    1645                 :            :         case '\t':
    1646                 :    1793935 :             ds_put_cstr(ds, "\\t");
    1647                 :    1793935 :             break;
    1648                 :            : 
    1649                 :            :         default:
    1650         [ +  - ]:  162589297 :             if (c >= 32) {
    1651                 :  162589297 :                 ds_put_char(ds, c);
    1652                 :            :             } else {
    1653                 :          0 :                 ds_put_format(ds, "\\u%04x", c);
    1654                 :            :             }
    1655                 :  162589297 :             break;
    1656                 :            :         }
    1657                 :            :     }
    1658                 :   12782128 :     ds_put_char(ds, '"');
    1659                 :   12782128 : }

Generated by: LCOV version 1.12