1 /*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <grpc/support/port_platform.h>
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <grpc/compression.h>
25
26 #include "src/core/lib/compression/algorithm_metadata.h"
27 #include "src/core/lib/compression/compression_internal.h"
28 #include "src/core/lib/gpr/useful.h"
29 #include "src/core/lib/surface/api_trace.h"
30 #include "src/core/lib/transport/static_metadata.h"
31
grpc_compression_algorithm_is_message(grpc_compression_algorithm algorithm)32 int grpc_compression_algorithm_is_message(
33 grpc_compression_algorithm algorithm) {
34 return (algorithm >= GRPC_COMPRESS_DEFLATE && algorithm <= GRPC_COMPRESS_GZIP)
35 ? 1
36 : 0;
37 }
38
grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm)39 int grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm) {
40 return (algorithm == GRPC_COMPRESS_STREAM_GZIP) ? 1 : 0;
41 }
42
grpc_compression_algorithm_parse(grpc_slice name,grpc_compression_algorithm * algorithm)43 int grpc_compression_algorithm_parse(grpc_slice name,
44 grpc_compression_algorithm* algorithm) {
45 if (grpc_slice_eq(name, GRPC_MDSTR_IDENTITY)) {
46 *algorithm = GRPC_COMPRESS_NONE;
47 return 1;
48 } else if (grpc_slice_eq(name, GRPC_MDSTR_DEFLATE)) {
49 *algorithm = GRPC_COMPRESS_DEFLATE;
50 return 1;
51 } else if (grpc_slice_eq(name, GRPC_MDSTR_GZIP)) {
52 *algorithm = GRPC_COMPRESS_GZIP;
53 return 1;
54 } else if (grpc_slice_eq(name, GRPC_MDSTR_STREAM_SLASH_GZIP)) {
55 *algorithm = GRPC_COMPRESS_STREAM_GZIP;
56 return 1;
57 } else {
58 return 0;
59 }
60 return 0;
61 }
62
grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,const char ** name)63 int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
64 const char** name) {
65 GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
66 ((int)algorithm, name));
67 switch (algorithm) {
68 case GRPC_COMPRESS_NONE:
69 *name = "identity";
70 return 1;
71 case GRPC_COMPRESS_DEFLATE:
72 *name = "deflate";
73 return 1;
74 case GRPC_COMPRESS_GZIP:
75 *name = "gzip";
76 return 1;
77 case GRPC_COMPRESS_STREAM_GZIP:
78 *name = "stream/gzip";
79 return 1;
80 case GRPC_COMPRESS_ALGORITHMS_COUNT:
81 return 0;
82 }
83 return 0;
84 }
85
grpc_compression_algorithm_for_level(grpc_compression_level level,uint32_t accepted_encodings)86 grpc_compression_algorithm grpc_compression_algorithm_for_level(
87 grpc_compression_level level, uint32_t accepted_encodings) {
88 grpc_compression_algorithm algo;
89 if (level == GRPC_COMPRESS_LEVEL_NONE) {
90 return GRPC_COMPRESS_NONE;
91 } else if (level <= GRPC_COMPRESS_LEVEL_HIGH) {
92 // TODO(mxyan): Design algorithm to select from all algorithms, including
93 // stream compression algorithm
94 if (!grpc_compression_algorithm_from_message_stream_compression_algorithm(
95 &algo,
96 grpc_message_compression_algorithm_for_level(
97 level,
98 grpc_compression_bitset_to_message_bitset(accepted_encodings)),
99 static_cast<grpc_stream_compression_algorithm>(0))) {
100 gpr_log(GPR_ERROR, "Parse compression level error");
101 return GRPC_COMPRESS_NONE;
102 }
103 return algo;
104 } else {
105 gpr_log(GPR_ERROR, "Unknown compression level: %d", level);
106 return GRPC_COMPRESS_NONE;
107 }
108 }
109
grpc_compression_options_init(grpc_compression_options * opts)110 void grpc_compression_options_init(grpc_compression_options* opts) {
111 memset(opts, 0, sizeof(*opts));
112 /* all enabled by default */
113 opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
114 }
115
grpc_compression_options_enable_algorithm(grpc_compression_options * opts,grpc_compression_algorithm algorithm)116 void grpc_compression_options_enable_algorithm(
117 grpc_compression_options* opts, grpc_compression_algorithm algorithm) {
118 GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm);
119 }
120
grpc_compression_options_disable_algorithm(grpc_compression_options * opts,grpc_compression_algorithm algorithm)121 void grpc_compression_options_disable_algorithm(
122 grpc_compression_options* opts, grpc_compression_algorithm algorithm) {
123 GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm);
124 }
125
grpc_compression_options_is_algorithm_enabled(const grpc_compression_options * opts,grpc_compression_algorithm algorithm)126 int grpc_compression_options_is_algorithm_enabled(
127 const grpc_compression_options* opts,
128 grpc_compression_algorithm algorithm) {
129 return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
130 }
131
grpc_compression_algorithm_slice(grpc_compression_algorithm algorithm)132 grpc_slice grpc_compression_algorithm_slice(
133 grpc_compression_algorithm algorithm) {
134 switch (algorithm) {
135 case GRPC_COMPRESS_NONE:
136 return GRPC_MDSTR_IDENTITY;
137 case GRPC_COMPRESS_DEFLATE:
138 return GRPC_MDSTR_DEFLATE;
139 case GRPC_COMPRESS_GZIP:
140 return GRPC_MDSTR_GZIP;
141 case GRPC_COMPRESS_STREAM_GZIP:
142 return GRPC_MDSTR_STREAM_SLASH_GZIP;
143 case GRPC_COMPRESS_ALGORITHMS_COUNT:
144 return grpc_empty_slice();
145 }
146 return grpc_empty_slice();
147 }
148
grpc_compression_algorithm_from_slice(grpc_slice str)149 grpc_compression_algorithm grpc_compression_algorithm_from_slice(
150 grpc_slice str) {
151 if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_COMPRESS_NONE;
152 if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) return GRPC_COMPRESS_DEFLATE;
153 if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_COMPRESS_GZIP;
154 if (grpc_slice_eq(str, GRPC_MDSTR_STREAM_SLASH_GZIP))
155 return GRPC_COMPRESS_STREAM_GZIP;
156 return GRPC_COMPRESS_ALGORITHMS_COUNT;
157 }
158
grpc_compression_encoding_mdelem(grpc_compression_algorithm algorithm)159 grpc_mdelem grpc_compression_encoding_mdelem(
160 grpc_compression_algorithm algorithm) {
161 switch (algorithm) {
162 case GRPC_COMPRESS_NONE:
163 return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
164 case GRPC_COMPRESS_DEFLATE:
165 return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
166 case GRPC_COMPRESS_GZIP:
167 return GRPC_MDELEM_GRPC_ENCODING_GZIP;
168 case GRPC_COMPRESS_STREAM_GZIP:
169 return GRPC_MDELEM_GRPC_ENCODING_GZIP;
170 default:
171 break;
172 }
173 return GRPC_MDNULL;
174 }
175