Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <grpc/grpc.h>
35 : #include "src/core/channel/channel_args.h"
36 : #include "src/core/support/string.h"
37 :
38 : #include <grpc/support/alloc.h>
39 : #include <grpc/support/string_util.h>
40 : #include <grpc/support/useful.h>
41 :
42 : #include <string.h>
43 :
44 20940 : static grpc_arg copy_arg(const grpc_arg *src) {
45 : grpc_arg dst;
46 20940 : dst.type = src->type;
47 20940 : dst.key = gpr_strdup(src->key);
48 20940 : switch (dst.type) {
49 : case GRPC_ARG_STRING:
50 9379 : dst.value.string = gpr_strdup(src->value.string);
51 9379 : break;
52 : case GRPC_ARG_INTEGER:
53 6653 : dst.value.integer = src->value.integer;
54 6653 : break;
55 : case GRPC_ARG_POINTER:
56 4908 : dst.value.pointer = src->value.pointer;
57 9816 : dst.value.pointer.p = src->value.pointer.copy
58 4908 : ? src->value.pointer.copy(src->value.pointer.p)
59 9816 : : src->value.pointer.p;
60 4908 : break;
61 : }
62 20940 : return dst;
63 : }
64 :
65 17188 : grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src,
66 : const grpc_arg *to_add,
67 : size_t num_to_add) {
68 17188 : grpc_channel_args *dst = gpr_malloc(sizeof(grpc_channel_args));
69 : size_t i;
70 17188 : size_t src_num_args = (src == NULL) ? 0 : src->num_args;
71 17188 : if (!src && !to_add) {
72 4990 : dst->num_args = 0;
73 4990 : dst->args = NULL;
74 4990 : return dst;
75 : }
76 12198 : dst->num_args = src_num_args + num_to_add;
77 12198 : dst->args = gpr_malloc(sizeof(grpc_arg) * dst->num_args);
78 24461 : for (i = 0; i < src_num_args; i++) {
79 12263 : dst->args[i] = copy_arg(&src->args[i]);
80 : }
81 20594 : for (i = 0; i < num_to_add; i++) {
82 8677 : dst->args[i + src_num_args] = copy_arg(&to_add[i]);
83 : }
84 11917 : return dst;
85 : }
86 :
87 10196 : grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src) {
88 10196 : return grpc_channel_args_copy_and_add(src, NULL, 0);
89 : }
90 :
91 3889 : grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a,
92 : const grpc_channel_args *b) {
93 3889 : return grpc_channel_args_copy_and_add(a, b->args, b->num_args);
94 : }
95 :
96 17050 : void grpc_channel_args_destroy(grpc_channel_args *a) {
97 : size_t i;
98 37754 : for (i = 0; i < a->num_args; i++) {
99 20704 : switch (a->args[i].type) {
100 : case GRPC_ARG_STRING:
101 9182 : gpr_free(a->args[i].value.string);
102 9182 : break;
103 : case GRPC_ARG_INTEGER:
104 6651 : break;
105 : case GRPC_ARG_POINTER:
106 4869 : if (a->args[i].value.pointer.destroy) {
107 4869 : a->args[i].value.pointer.destroy(a->args[i].value.pointer.p);
108 : }
109 4763 : break;
110 : }
111 20704 : gpr_free(a->args[i].key);
112 : }
113 17050 : gpr_free(a->args);
114 17050 : gpr_free(a);
115 17050 : }
116 :
117 2792 : int grpc_channel_args_is_census_enabled(const grpc_channel_args *a) {
118 : size_t i;
119 2792 : if (a == NULL) return 0;
120 3270 : for (i = 0; i < a->num_args; i++) {
121 1841 : if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_CENSUS)) {
122 19 : return a->args[i].value.integer != 0;
123 : }
124 : }
125 1429 : return 0;
126 : }
127 :
128 5734 : grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
129 : const grpc_channel_args *a) {
130 : size_t i;
131 5734 : if (a == NULL) return 0;
132 8755 : for (i = 0; i < a->num_args; ++i) {
133 7547 : if (a->args[i].type == GRPC_ARG_INTEGER &&
134 2103 : !strcmp(GRPC_COMPRESSION_ALGORITHM_ARG, a->args[i].key)) {
135 660 : return (grpc_compression_algorithm)a->args[i].value.integer;
136 : break;
137 : }
138 : }
139 3311 : return GRPC_COMPRESS_NONE;
140 : }
141 :
142 759 : grpc_channel_args *grpc_channel_args_set_compression_algorithm(
143 : grpc_channel_args *a, grpc_compression_algorithm algorithm) {
144 : grpc_arg tmp;
145 759 : tmp.type = GRPC_ARG_INTEGER;
146 759 : tmp.key = GRPC_COMPRESSION_ALGORITHM_ARG;
147 759 : tmp.value.integer = algorithm;
148 759 : return grpc_channel_args_copy_and_add(a, &tmp, 1);
149 : }
150 :
151 : /** Returns 1 if the argument for compression algorithm's enabled states bitset
152 : * was found in \a a, returning the arg's value in \a states. Otherwise, returns
153 : * 0. */
154 5740 : static int find_compression_algorithm_states_bitset(const grpc_channel_args *a,
155 : int **states_arg) {
156 5740 : if (a != NULL) {
157 : size_t i;
158 9310 : for (i = 0; i < a->num_args; ++i) {
159 7627 : if (a->args[i].type == GRPC_ARG_INTEGER &&
160 2131 : !strcmp(GRPC_COMPRESSION_ALGORITHM_STATE_ARG, a->args[i].key)) {
161 163 : *states_arg = &a->args[i].value.integer;
162 163 : return 1; /* GPR_TRUE */
163 : }
164 : }
165 : }
166 5478 : return 0; /* GPR_FALSE */
167 : }
168 :
169 3 : grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
170 : grpc_channel_args **a, grpc_compression_algorithm algorithm, int state) {
171 : int *states_arg;
172 3 : grpc_channel_args *result = *a;
173 3 : const int states_arg_found =
174 3 : find_compression_algorithm_states_bitset(*a, &states_arg);
175 :
176 3 : if (states_arg_found) {
177 2 : if (state != 0) {
178 1 : GPR_BITSET((unsigned *)states_arg, algorithm);
179 : } else {
180 1 : GPR_BITCLEAR((unsigned *)states_arg, algorithm);
181 : }
182 : } else {
183 : /* create a new arg */
184 : grpc_arg tmp;
185 1 : tmp.type = GRPC_ARG_INTEGER;
186 1 : tmp.key = GRPC_COMPRESSION_ALGORITHM_STATE_ARG;
187 : /* all enabled by default */
188 1 : tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
189 1 : if (state != 0) {
190 0 : GPR_BITSET((unsigned *)&tmp.value.integer, algorithm);
191 : } else {
192 1 : GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
193 : }
194 1 : result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
195 1 : grpc_channel_args_destroy(*a);
196 1 : *a = result;
197 : }
198 3 : return result;
199 : }
200 :
201 5737 : int grpc_channel_args_compression_algorithm_get_states(
202 : const grpc_channel_args *a) {
203 : int *states_arg;
204 5737 : if (find_compression_algorithm_states_bitset(a, &states_arg)) {
205 161 : return *states_arg;
206 : } else {
207 5477 : return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */
208 : }
209 : }
|