|
|
|
@ -54,9 +54,7 @@ static grpc_arg copy_arg(const grpc_arg *src) { |
|
|
|
|
break; |
|
|
|
|
case GRPC_ARG_POINTER: |
|
|
|
|
dst.value.pointer = src->value.pointer; |
|
|
|
|
dst.value.pointer.p = src->value.pointer.copy |
|
|
|
|
? src->value.pointer.copy(src->value.pointer.p) |
|
|
|
|
: src->value.pointer.p; |
|
|
|
|
dst.value.pointer.p = src->value.pointer.vtable->copy(src->value.pointer.p); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
return dst; |
|
|
|
@ -93,6 +91,60 @@ grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, |
|
|
|
|
return grpc_channel_args_copy_and_add(a, b->args, b->num_args); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int cmp_arg(const grpc_arg *a, const grpc_arg *b) { |
|
|
|
|
int c = a->type - b->type; |
|
|
|
|
if (c != 0) return c; |
|
|
|
|
c = strcmp(a->key, b->key); |
|
|
|
|
if (c != 0) return c; |
|
|
|
|
switch (a->type) { |
|
|
|
|
case GRPC_ARG_STRING: |
|
|
|
|
c = strcmp(a->value.string, b->value.string); |
|
|
|
|
break; |
|
|
|
|
case GRPC_ARG_INTEGER: |
|
|
|
|
c = GPR_ICMP(a->value.integer, b->value.integer); |
|
|
|
|
break; |
|
|
|
|
case GRPC_ARG_POINTER: |
|
|
|
|
c = GPR_ICMP(a->value.pointer.p,
|
|
|
|
|
b->value.pointer.p); |
|
|
|
|
if (c != 0) { |
|
|
|
|
c = GPR_ICMP(a->value.pointer.vtable,
|
|
|
|
|
b->value.pointer.vtable); |
|
|
|
|
if (c == 0) { |
|
|
|
|
c = a->value.pointer.vtable->cmp(a->value.pointer.p, |
|
|
|
|
b->value.pointer.p); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int cmp_key_stable(const void *ap, const void *bp) { |
|
|
|
|
const grpc_arg *const *a = ap; |
|
|
|
|
const grpc_arg *const *b = bp; |
|
|
|
|
int c = strcmp((*a)->key, (*b)->key); |
|
|
|
|
if (c == 0) c = GPR_ICMP(*a, *b); |
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) { |
|
|
|
|
grpc_arg **args = gpr_malloc(sizeof(grpc_arg*) * a->num_args); |
|
|
|
|
for (size_t i = 0; i < a->num_args; i++) { |
|
|
|
|
args[i] = &a->args[i]; |
|
|
|
|
} |
|
|
|
|
qsort(args, a->num_args, sizeof(grpc_arg*), cmp_key_stable); |
|
|
|
|
|
|
|
|
|
grpc_channel_args *b = gpr_malloc(sizeof(grpc_channel_args)); |
|
|
|
|
b->num_args = a->num_args; |
|
|
|
|
b->args = gpr_malloc(sizeof(grpc_arg) * b->num_args); |
|
|
|
|
for (size_t i = 0; i < a->num_args; i++) { |
|
|
|
|
b->args[i] = copy_arg(args[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_free(args); |
|
|
|
|
return b; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_channel_args_destroy(grpc_channel_args *a) { |
|
|
|
|
size_t i; |
|
|
|
|
for (i = 0; i < a->num_args; i++) { |
|
|
|
@ -103,9 +155,7 @@ void grpc_channel_args_destroy(grpc_channel_args *a) { |
|
|
|
|
case GRPC_ARG_INTEGER: |
|
|
|
|
break; |
|
|
|
|
case GRPC_ARG_POINTER: |
|
|
|
|
if (a->args[i].value.pointer.destroy) { |
|
|
|
|
a->args[i].value.pointer.destroy(a->args[i].value.pointer.p); |
|
|
|
|
} |
|
|
|
|
a->args[i].value.pointer.vtable->destroy(a->args[i].value.pointer.p); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
gpr_free(a->args[i].key); |
|
|
|
@ -207,3 +257,14 @@ int grpc_channel_args_compression_algorithm_get_states( |
|
|
|
|
return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int grpc_channel_args_compare(const grpc_channel_args *a,
|
|
|
|
|
const grpc_channel_args *b) { |
|
|
|
|
int c = GPR_ICMP(a->num_args, b->num_args); |
|
|
|
|
if (c != 0) return c; |
|
|
|
|
for (size_t i = 0; i < a->num_args; i++) { |
|
|
|
|
c = cmp_arg(&a->args[i], &b->args[i]); |
|
|
|
|
if (c != 0) return c; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|