lib/netdev-dpdk: increase ring name length for dpdkr ports
[cascardo/ovs.git] / lib / json.c
index af385c6..dd85213 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2014, 2015 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -117,7 +117,7 @@ static struct json *json_create(enum json_type type);
 static void json_parser_input(struct json_parser *, struct json_token *);
 
 static void json_error(struct json_parser *p, const char *format, ...)
-    PRINTF_FORMAT(2, 3);
+    OVS_PRINTF_FORMAT(2, 3);
 \f
 const char *
 json_type_to_string(enum json_type type)
@@ -355,7 +355,7 @@ json_destroy(struct json *json)
             break;
 
         case JSON_N_TYPES:
-            NOT_REACHED();
+            OVS_NOT_REACHED();
         }
         free(json);
     }
@@ -417,7 +417,7 @@ json_clone(const struct json *json)
 
     case JSON_N_TYPES:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -461,6 +461,7 @@ json_hash_object(const struct shash *object, size_t basis)
         basis = hash_string(node->name, basis);
         basis = json_hash(node->data, basis);
     }
+    free(nodes);
     return basis;
 }
 
@@ -502,7 +503,7 @@ json_hash(const struct json *json, size_t basis)
 
     case JSON_N_TYPES:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -573,7 +574,7 @@ json_equal(const struct json *a, const struct json *b)
 
     case JSON_N_TYPES:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 \f
@@ -745,13 +746,14 @@ static const char *
 json_lex_4hex(const char *cp, const char *end, int *valuep)
 {
     unsigned int value;
+    bool ok;
 
     if (cp + 4 > end) {
         return "quoted string ends within \\u escape";
     }
 
-    value = hexits_value(cp, 4, NULL);
-    if (value == UINT_MAX) {
+    value = hexits_value(cp, 4, &ok);
+    if (!ok) {
         return "malformed \\u escape";
     }
     if (!value) {
@@ -812,10 +814,6 @@ json_string_unescape(const char *in, size_t in_len, char **outp)
 
     ds_init(&out);
     ds_reserve(&out, in_len);
-    if (in_len > 0 && in[in_len - 1] == '\\') {
-        ds_put_cstr(&out, "quoted string may not end with backslash");
-        goto exit;
-    }
     while (in < end) {
         if (*in == '"') {
             ds_clear(&out);
@@ -828,6 +826,15 @@ json_string_unescape(const char *in, size_t in_len, char **outp)
         }
 
         in++;
+        if (in >= end) {
+            /* The JSON parser will never trigger this message, because its
+             * lexer will never pass in a string that ends in a single
+             * backslash, but json_string_unescape() has other callers that
+             * are not as careful.*/
+            ds_clear(&out);
+            ds_put_cstr(&out, "quoted string may not end with backslash");
+            goto exit;
+        }
         switch (*in++) {
         case '"': case '\\': case '/':
             ds_put_char(&out, in[-1]);
@@ -873,6 +880,16 @@ exit:
     return ok;
 }
 
+void
+json_string_escape(const char *in, struct ds *out)
+{
+    struct json json = {
+        .type = JSON_STRING,
+        .u.string = CONST_CAST(char *, in),
+    };
+    json_to_ds(&json, 0, out);
+}
+
 static void
 json_parser_input_string(struct json_parser *p, const char *s)
 {
@@ -1026,7 +1043,8 @@ json_from_file(const char *file_name)
     stream = fopen(file_name, "r");
     if (!stream) {
         return json_string_create_nocopy(
-            xasprintf("error opening \"%s\": %s", file_name, strerror(errno)));
+            xasprintf("error opening \"%s\": %s", file_name,
+                      ovs_strerror(errno)));
     }
     json = json_from_stream(stream);
     fclose(stream);
@@ -1063,7 +1081,7 @@ json_from_stream(FILE *stream)
     if (ferror(stream)) {
         json_destroy(json);
         json = json_string_create_nocopy(
-            xasprintf("error reading JSON stream: %s", strerror(errno)));
+            xasprintf("error reading JSON stream: %s", ovs_strerror(errno)));
     }
 
     return json;
@@ -1174,7 +1192,7 @@ json_parser_put_value(struct json_parser *p, struct json *value)
     } else if (node->json->type == JSON_ARRAY) {
         json_array_add(node->json, value);
     } else {
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1294,7 +1312,7 @@ json_parser_pop(struct json_parser *p)
         } else if (node->json->type == JSON_OBJECT) {
             p->parse_state = JSON_PARSE_OBJECT_NEXT;
         } else {
-            NOT_REACHED();
+            OVS_NOT_REACHED();
         }
     }
 }
@@ -1501,7 +1519,7 @@ json_serialize(const struct json *json, struct json_serializer *s)
 
     case JSON_N_TYPES:
     default:
-        NOT_REACHED();
+        OVS_NOT_REACHED();
     }
 }
 
@@ -1639,116 +1657,3 @@ json_serialize_string(const char *string, struct ds *ds)
     }
     ds_put_char(ds, '"');
 }
-\f
-static size_t
-json_string_serialized_length(const char *string)
-{
-    size_t length;
-    uint8_t c;
-
-    length = strlen("\"\"");
-
-    while ((c = *string++) != '\0') {
-        switch (c) {
-        case '"':
-        case '\\':
-        case '\b':
-        case '\f':
-        case '\n':
-        case '\r':
-        case '\t':
-            length += 2;
-            break;
-
-        default:
-            if (c >= 32) {
-                length++;
-            } else {
-                /* \uXXXX */
-                length += 6;
-            }
-            break;
-        }
-    }
-
-    return length;
-}
-
-static size_t
-json_object_serialized_length(const struct shash *object)
-{
-    size_t length = strlen("{}");
-
-    if (!shash_is_empty(object)) {
-        struct shash_node *node;
-
-        /* Commas and colons. */
-        length += 2 * shash_count(object) - 1;
-
-        SHASH_FOR_EACH (node, object) {
-            const struct json *value = node->data;
-
-            length += json_string_serialized_length(node->name);
-            length += json_serialized_length(value);
-        }
-    }
-
-    return length;
-}
-
-static size_t
-json_array_serialized_length(const struct json_array *array)
-{
-    size_t length = strlen("[]");
-
-    if (array->n) {
-        size_t i;
-
-        /* Commas. */
-        length += array->n - 1;
-
-        for (i = 0; i < array->n; i++) {
-            length += json_serialized_length(array->elems[i]);
-        }
-    }
-
-    return length;
-}
-
-/* Returns strlen(json_to_string(json, 0)), that is, the number of bytes in the
- * JSON output by json_to_string() for 'json' when JSSF_PRETTY is not
- * requested.  (JSSF_SORT does not affect the length of json_to_string()'s
- * output.) */
-size_t
-json_serialized_length(const struct json *json)
-{
-    switch (json->type) {
-    case JSON_NULL:
-        return strlen("null");
-
-    case JSON_FALSE:
-        return strlen("false");
-
-    case JSON_TRUE:
-        return strlen("true");
-
-    case JSON_OBJECT:
-        return json_object_serialized_length(json->u.object);
-
-    case JSON_ARRAY:
-        return json_array_serialized_length(&json->u.array);
-
-    case JSON_INTEGER:
-        return snprintf(NULL, 0, "%lld", json->u.integer);
-
-    case JSON_REAL:
-        return snprintf(NULL, 0, "%.*g", DBL_DIG, json->u.real);
-
-    case JSON_STRING:
-        return json_string_serialized_length(json->u.string);
-
-    case JSON_N_TYPES:
-    default:
-        NOT_REACHED();
-    }
-}