aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/json
diff options
context:
space:
mode:
authorGravatar Mark D. Roth <roth@google.com>2016-11-03 07:58:25 -0700
committerGravatar Mark D. Roth <roth@google.com>2016-11-03 07:58:25 -0700
commit896d92568b1b615a19dec26035596de244cbf535 (patch)
treee31678532ba5fdb10bddff66e6ee62deb7008920 /src/core/lib/json
parente528993d972396003459a7750db2158cd5a696a7 (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.c59
-rw-r--r--src/core/lib/json/json.h19
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 */