blob: 001227a2aa0188669e38043d54ea618beecbb234 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080016 *
17 */
18
19#include <grpc/byte_buffer_reader.h>
Craig Tillerf40df232016-03-25 13:38:14 -070020#include <string.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080021
Craig Tillerf40df232016-03-25 13:38:14 -070022#include <grpc/byte_buffer.h>
David Garcia Quintas59f905d2015-06-08 16:31:19 -070023#include <grpc/compression.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080024#include <grpc/grpc.h>
Craig Tiller28b72422016-10-26 21:15:29 -070025#include <grpc/slice_buffer.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080026#include <grpc/support/alloc.h>
27#include <grpc/support/log.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080028
Craig Tiller9533d042016-03-25 17:11:06 -070029#include "src/core/lib/compression/message_compress.h"
Craig Tillera59c16c2016-10-31 07:25:01 -070030#include "src/core/lib/slice/slice_internal.h"
David Garcia Quintas25d02d52015-06-04 17:40:54 -070031
Craig Tillerbaa14a92017-11-03 09:09:36 -070032static int is_compressed(grpc_byte_buffer* buffer) {
David Garcia Quintas59f905d2015-06-08 16:31:19 -070033 switch (buffer->type) {
34 case GRPC_BB_RAW:
35 if (buffer->data.raw.compression == GRPC_COMPRESS_NONE) {
36 return 0 /* GPR_FALSE */;
37 }
38 break;
39 }
40 return 1 /* GPR_TRUE */;
41}
42
Craig Tillerbaa14a92017-11-03 09:09:36 -070043int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
44 grpc_byte_buffer* buffer) {
Craig Tillera59c16c2016-10-31 07:25:01 -070045 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerd41a4a72016-10-26 16:16:06 -070046 grpc_slice_buffer decompressed_slices_buffer;
David Garcia Quintas25d02d52015-06-04 17:40:54 -070047 reader->buffer_in = buffer;
David Garcia Quintas59f905d2015-06-08 16:31:19 -070048 switch (reader->buffer_in->type) {
49 case GRPC_BB_RAW:
Craig Tillerd41a4a72016-10-26 16:16:06 -070050 grpc_slice_buffer_init(&decompressed_slices_buffer);
David Garcia Quintas59f905d2015-06-08 16:31:19 -070051 if (is_compressed(reader->buffer_in)) {
Craig Tillera59c16c2016-10-31 07:25:01 -070052 if (grpc_msg_decompress(&exec_ctx,
53 reader->buffer_in->data.raw.compression,
David Garcia Quintas303d3082016-05-05 18:25:34 -070054 &reader->buffer_in->data.raw.slice_buffer,
David Garcia Quintas0b405d52016-05-09 15:58:22 -070055 &decompressed_slices_buffer) == 0) {
David Garcia Quintas303d3082016-05-05 18:25:34 -070056 gpr_log(GPR_ERROR,
57 "Unexpected error decompressing data for algorithm with enum "
David Garcia Quintasecbe2d52016-07-02 09:50:17 -070058 "value '%d'.",
David Garcia Quintas303d3082016-05-05 18:25:34 -070059 reader->buffer_in->data.raw.compression);
David Garcia Quintas6721d4f2016-06-30 17:17:23 -070060 memset(reader, 0, sizeof(*reader));
David Garcia Quintas0910e4c2016-07-01 11:25:01 -070061 return 0;
David Garcia Quintas303d3082016-05-05 18:25:34 -070062 } else { /* all fine */
63 reader->buffer_out =
64 grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices,
65 decompressed_slices_buffer.count);
66 }
Craig Tillera59c16c2016-10-31 07:25:01 -070067 grpc_slice_buffer_destroy_internal(&exec_ctx,
68 &decompressed_slices_buffer);
Craig Tiller9a576332015-06-17 10:21:49 -070069 } else { /* not compressed, use the input buffer as output */
David Garcia Quintas59f905d2015-06-08 16:31:19 -070070 reader->buffer_out = reader->buffer_in;
71 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080072 reader->current.index = 0;
David Garcia Quintas59f905d2015-06-08 16:31:19 -070073 break;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080074 }
Craig Tillera59c16c2016-10-31 07:25:01 -070075 grpc_exec_ctx_finish(&exec_ctx);
David Garcia Quintas6721d4f2016-06-30 17:17:23 -070076 return 1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080077}
78
Craig Tillerbaa14a92017-11-03 09:09:36 -070079void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) {
David Garcia Quintas25d02d52015-06-04 17:40:54 -070080 switch (reader->buffer_in->type) {
David Garcia Quintas59f905d2015-06-08 16:31:19 -070081 case GRPC_BB_RAW:
82 /* keeping the same if-else structure as in the init function */
83 if (is_compressed(reader->buffer_in)) {
84 grpc_byte_buffer_destroy(reader->buffer_out);
85 }
David Garcia Quintas25d02d52015-06-04 17:40:54 -070086 break;
David Garcia Quintas25d02d52015-06-04 17:40:54 -070087 }
David Garcia Quintas02c677c2015-06-02 14:40:07 -070088}
89
Craig Tillerbaa14a92017-11-03 09:09:36 -070090int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
91 grpc_slice* slice) {
David Garcia Quintas25d02d52015-06-04 17:40:54 -070092 switch (reader->buffer_in->type) {
David Garcia Quintas59f905d2015-06-08 16:31:19 -070093 case GRPC_BB_RAW: {
Craig Tillerbaa14a92017-11-03 09:09:36 -070094 grpc_slice_buffer* slice_buffer;
David Garcia Quintas59f905d2015-06-08 16:31:19 -070095 slice_buffer = &reader->buffer_out->data.raw.slice_buffer;
96 if (reader->current.index < slice_buffer->count) {
Craig Tillera59c16c2016-10-31 07:25:01 -070097 *slice = grpc_slice_ref_internal(
98 slice_buffer->slices[reader->current.index]);
David Garcia Quintas59f905d2015-06-08 16:31:19 -070099 reader->current.index += 1;
100 return 1;
101 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800102 break;
David Garcia Quintas59f905d2015-06-08 16:31:19 -0700103 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800104 }
105 return 0;
106}
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700107
Craig Tillerbaa14a92017-11-03 09:09:36 -0700108grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader) {
Craig Tillerd41a4a72016-10-26 16:16:06 -0700109 grpc_slice in_slice;
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700110 size_t bytes_read = 0;
111 const size_t input_size = grpc_byte_buffer_length(reader->buffer_out);
Craig Tiller423d6fd2017-04-12 13:15:45 -0700112 grpc_slice out_slice = GRPC_SLICE_MALLOC(input_size);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700113 uint8_t* const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700114
Craig Tillera59c16c2016-10-31 07:25:01 -0700115 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700116 while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) {
Craig Tiller618e67d2016-10-26 21:08:10 -0700117 const size_t slice_length = GRPC_SLICE_LENGTH(in_slice);
118 memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length);
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700119 bytes_read += slice_length;
Craig Tillera59c16c2016-10-31 07:25:01 -0700120 grpc_slice_unref_internal(&exec_ctx, in_slice);
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700121 GPR_ASSERT(bytes_read <= input_size);
122 }
Craig Tillera59c16c2016-10-31 07:25:01 -0700123 grpc_exec_ctx_finish(&exec_ctx);
David Garcia Quintas6eb39252015-10-30 17:01:05 -0700124 return out_slice;
125}