Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Side by Side Diff: third_party/grpc/src/core/compression/message_compress.c

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "src/core/compression/message_compress.h"
35
36 #include <string.h>
37
38 #include <grpc/support/alloc.h>
39 #include <grpc/support/log.h>
40
41 #include <zlib.h>
42
43 #define OUTPUT_BLOCK_SIZE 1024
44
45 static int zlib_body(z_stream* zs, gpr_slice_buffer* input,
46 gpr_slice_buffer* output,
47 int (*flate)(z_stream* zs, int flush)) {
48 int r;
49 int flush;
50 size_t i;
51 gpr_slice outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE);
52 const uInt uint_max = ~(uInt)0;
53
54 GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max);
55 zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf);
56 zs->next_out = GPR_SLICE_START_PTR(outbuf);
57 flush = Z_NO_FLUSH;
58 for (i = 0; i < input->count; i++) {
59 if (i == input->count - 1) flush = Z_FINISH;
60 GPR_ASSERT(GPR_SLICE_LENGTH(input->slices[i]) <= uint_max);
61 zs->avail_in = (uInt)GPR_SLICE_LENGTH(input->slices[i]);
62 zs->next_in = GPR_SLICE_START_PTR(input->slices[i]);
63 do {
64 if (zs->avail_out == 0) {
65 gpr_slice_buffer_add_indexed(output, outbuf);
66 outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE);
67 GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max);
68 zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf);
69 zs->next_out = GPR_SLICE_START_PTR(outbuf);
70 }
71 r = flate(zs, flush);
72 if (r < 0 && r != Z_BUF_ERROR /* not fatal */) {
73 gpr_log(GPR_INFO, "zlib error (%d)", r);
74 goto error;
75 }
76 } while (zs->avail_out == 0);
77 if (zs->avail_in) {
78 gpr_log(GPR_INFO, "zlib: not all input consumed");
79 goto error;
80 }
81 }
82
83 GPR_ASSERT(outbuf.refcount);
84 outbuf.data.refcounted.length -= zs->avail_out;
85 gpr_slice_buffer_add_indexed(output, outbuf);
86
87 return 1;
88
89 error:
90 gpr_slice_unref(outbuf);
91 return 0;
92 }
93
94 static void* zalloc_gpr(void* opaque, unsigned int items, unsigned int size) {
95 return gpr_malloc(items * size);
96 }
97
98 static void zfree_gpr(void* opaque, void* address) { gpr_free(address); }
99
100 static int zlib_compress(gpr_slice_buffer* input, gpr_slice_buffer* output,
101 int gzip) {
102 z_stream zs;
103 int r;
104 size_t i;
105 size_t count_before = output->count;
106 size_t length_before = output->length;
107 memset(&zs, 0, sizeof(zs));
108 zs.zalloc = zalloc_gpr;
109 zs.zfree = zfree_gpr;
110 r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0),
111 8, Z_DEFAULT_STRATEGY);
112 GPR_ASSERT(r == Z_OK);
113 r = zlib_body(&zs, input, output, deflate) && output->length < input->length;
114 if (!r) {
115 for (i = count_before; i < output->count; i++) {
116 gpr_slice_unref(output->slices[i]);
117 }
118 output->count = count_before;
119 output->length = length_before;
120 }
121 deflateEnd(&zs);
122 return r;
123 }
124
125 static int zlib_decompress(gpr_slice_buffer* input, gpr_slice_buffer* output,
126 int gzip) {
127 z_stream zs;
128 int r;
129 size_t i;
130 size_t count_before = output->count;
131 size_t length_before = output->length;
132 memset(&zs, 0, sizeof(zs));
133 zs.zalloc = zalloc_gpr;
134 zs.zfree = zfree_gpr;
135 r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
136 GPR_ASSERT(r == Z_OK);
137 r = zlib_body(&zs, input, output, inflate);
138 if (!r) {
139 for (i = count_before; i < output->count; i++) {
140 gpr_slice_unref(output->slices[i]);
141 }
142 output->count = count_before;
143 output->length = length_before;
144 }
145 inflateEnd(&zs);
146 return r;
147 }
148
149 static int copy(gpr_slice_buffer* input, gpr_slice_buffer* output) {
150 size_t i;
151 for (i = 0; i < input->count; i++) {
152 gpr_slice_buffer_add(output, gpr_slice_ref(input->slices[i]));
153 }
154 return 1;
155 }
156
157 static int compress_inner(grpc_compression_algorithm algorithm,
158 gpr_slice_buffer* input, gpr_slice_buffer* output) {
159 switch (algorithm) {
160 case GRPC_COMPRESS_NONE:
161 /* the fallback path always needs to be send uncompressed: we simply
162 rely on that here */
163 return 0;
164 case GRPC_COMPRESS_DEFLATE:
165 return zlib_compress(input, output, 0);
166 case GRPC_COMPRESS_GZIP:
167 return zlib_compress(input, output, 1);
168 case GRPC_COMPRESS_ALGORITHMS_COUNT:
169 break;
170 }
171 gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
172 return 0;
173 }
174
175 int grpc_msg_compress(grpc_compression_algorithm algorithm,
176 gpr_slice_buffer* input, gpr_slice_buffer* output) {
177 if (!compress_inner(algorithm, input, output)) {
178 copy(input, output);
179 return 0;
180 }
181 return 1;
182 }
183
184 int grpc_msg_decompress(grpc_compression_algorithm algorithm,
185 gpr_slice_buffer* input, gpr_slice_buffer* output) {
186 switch (algorithm) {
187 case GRPC_COMPRESS_NONE:
188 return copy(input, output);
189 case GRPC_COMPRESS_DEFLATE:
190 return zlib_decompress(input, output, 0);
191 case GRPC_COMPRESS_GZIP:
192 return zlib_decompress(input, output, 1);
193 case GRPC_COMPRESS_ALGORITHMS_COUNT:
194 break;
195 }
196 gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
197 return 0;
198 }
OLDNEW
« no previous file with comments | « third_party/grpc/src/core/compression/message_compress.h ('k') | third_party/grpc/src/core/debug/trace.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698