diff options
author | Mark D. Roth <roth@google.com> | 2016-11-03 07:58:25 -0700 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2016-11-03 07:58:25 -0700 |
commit | 896d92568b1b615a19dec26035596de244cbf535 (patch) | |
tree | e31678532ba5fdb10bddff66e6ee62deb7008920 /src/core/lib/json | |
parent | e528993d972396003459a7750db2158cd5a696a7 (diff) |
Add grpc_json_tree to handle refcounting for channel arg.
Diffstat (limited to 'src/core/lib/json')
-rw-r--r-- | src/core/lib/json/json.c | 59 | ||||
-rw-r--r-- | src/core/lib/json/json.h | 19 |
2 files changed, 78 insertions, 0 deletions
diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c index 5b583a1f2e..c1a99df6c3 100644 --- a/src/core/lib/json/json.c +++ b/src/core/lib/json/json.c @@ -34,6 +34,8 @@ #include <string.h> #include <grpc/support/alloc.h> +#include <grpc/support/string_util.h> +#include <grpc/support/sync.h> #include "src/core/lib/json/json.h" @@ -62,3 +64,60 @@ void grpc_json_destroy(grpc_json *json) { gpr_free(json); } + +int grpc_json_cmp(const grpc_json* json1, const grpc_json* json2) { + if (json1 == NULL) { + if (json2 != NULL) return 1; + return 0; // Both NULL. + } else { + if (json2 == NULL) return -1; + } + // Compare type. + if (json1->type > json2->type) return 1; + if (json1->type < json2->type) return -1; + // Compare key. + if (json1->key == NULL) { + if (json2->key != NULL) return -1; + } else { + if (json2->key == NULL) return 1; + int retval = strcmp(json1->key, json2->key); + if (retval != 0) return retval; + } + // Compare value. + if (json1->value == NULL) { + if (json2->value != NULL) return -1; + } else { + if (json2->value == NULL) return 1; + int retval = strcmp(json1->value, json2->value); + if (retval != 0) return retval; + } + // Recursively compare the next pointer. + int retval = grpc_json_cmp(json1->next, json2->next); + if (retval != 0) return retval; + // Recursively compare the child pointer. + retval = grpc_json_cmp(json1->child, json2->child); + if (retval != 0) return retval; + // Both are the same. + return 0; +} + +grpc_json_tree* grpc_json_tree_create(const char* json_string) { + grpc_json_tree* tree = gpr_malloc(sizeof(*tree)); + tree->string = gpr_strdup(json_string); + tree->root = grpc_json_parse_string(tree->string); + gpr_ref_init(&tree->refs, 1); + return tree; +} + +grpc_json_tree* grpc_json_tree_ref(grpc_json_tree* tree) { + gpr_ref(&tree->refs); + return tree; +} + +void grpc_json_tree_unref(grpc_json_tree* tree) { + if (gpr_unref(&tree->refs)) { + grpc_json_destroy(tree->root); + gpr_free(tree->string); + gpr_free(tree); + } +} diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h index 681df4bb77..e18ace7547 100644 --- a/src/core/lib/json/json.h +++ b/src/core/lib/json/json.h @@ -36,6 +36,8 @@ #include <stdlib.h> +#include <grpc/support/sync.h> + #include "src/core/lib/json/json_common.h" /* A tree-like structure to hold json values. The key and value pointers @@ -85,4 +87,21 @@ char *grpc_json_dump_to_string(grpc_json *json, int indent); grpc_json *grpc_json_create(grpc_json_type type); void grpc_json_destroy(grpc_json *json); +/* Compares two JSON trees. */ +int grpc_json_cmp(const grpc_json* json1, const grpc_json* json2); + +/* A wrapper that contains the string used for underlying allocation and + is refcounted. */ +typedef struct { + grpc_json* root; + char* string; + gpr_refcount refs; +} grpc_json_tree; + +/* Creates a copy of \a json_string. */ +grpc_json_tree* grpc_json_tree_create(const char* json_string); + +grpc_json_tree* grpc_json_tree_ref(grpc_json_tree* tree); +void grpc_json_tree_unref(grpc_json_tree* tree); + #endif /* GRPC_CORE_LIB_JSON_JSON_H */ |