Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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 |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
| 19 | #include <grpc/byte_buffer_reader.h> |
Craig Tiller | f40df23 | 2016-03-25 13:38:14 -0700 | [diff] [blame] | 20 | #include <string.h> |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 21 | |
Craig Tiller | f40df23 | 2016-03-25 13:38:14 -0700 | [diff] [blame] | 22 | #include <grpc/byte_buffer.h> |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 23 | #include <grpc/compression.h> |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 24 | #include <grpc/grpc.h> |
Craig Tiller | 28b7242 | 2016-10-26 21:15:29 -0700 | [diff] [blame] | 25 | #include <grpc/slice_buffer.h> |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 26 | #include <grpc/support/alloc.h> |
| 27 | #include <grpc/support/log.h> |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 28 | |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 29 | #include "src/core/lib/compression/message_compress.h" |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 30 | #include "src/core/lib/slice/slice_internal.h" |
David Garcia Quintas | 25d02d5 | 2015-06-04 17:40:54 -0700 | [diff] [blame] | 31 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 32 | static int is_compressed(grpc_byte_buffer* buffer) { |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 33 | 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 Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 43 | int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader, |
| 44 | grpc_byte_buffer* buffer) { |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 45 | grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 46 | grpc_slice_buffer decompressed_slices_buffer; |
David Garcia Quintas | 25d02d5 | 2015-06-04 17:40:54 -0700 | [diff] [blame] | 47 | reader->buffer_in = buffer; |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 48 | switch (reader->buffer_in->type) { |
| 49 | case GRPC_BB_RAW: |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 50 | grpc_slice_buffer_init(&decompressed_slices_buffer); |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 51 | if (is_compressed(reader->buffer_in)) { |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 52 | if (grpc_msg_decompress(&exec_ctx, |
| 53 | reader->buffer_in->data.raw.compression, |
David Garcia Quintas | 303d308 | 2016-05-05 18:25:34 -0700 | [diff] [blame] | 54 | &reader->buffer_in->data.raw.slice_buffer, |
David Garcia Quintas | 0b405d5 | 2016-05-09 15:58:22 -0700 | [diff] [blame] | 55 | &decompressed_slices_buffer) == 0) { |
David Garcia Quintas | 303d308 | 2016-05-05 18:25:34 -0700 | [diff] [blame] | 56 | gpr_log(GPR_ERROR, |
| 57 | "Unexpected error decompressing data for algorithm with enum " |
David Garcia Quintas | ecbe2d5 | 2016-07-02 09:50:17 -0700 | [diff] [blame] | 58 | "value '%d'.", |
David Garcia Quintas | 303d308 | 2016-05-05 18:25:34 -0700 | [diff] [blame] | 59 | reader->buffer_in->data.raw.compression); |
David Garcia Quintas | 6721d4f | 2016-06-30 17:17:23 -0700 | [diff] [blame] | 60 | memset(reader, 0, sizeof(*reader)); |
David Garcia Quintas | 0910e4c | 2016-07-01 11:25:01 -0700 | [diff] [blame] | 61 | return 0; |
David Garcia Quintas | 303d308 | 2016-05-05 18:25:34 -0700 | [diff] [blame] | 62 | } else { /* all fine */ |
| 63 | reader->buffer_out = |
| 64 | grpc_raw_byte_buffer_create(decompressed_slices_buffer.slices, |
| 65 | decompressed_slices_buffer.count); |
| 66 | } |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 67 | grpc_slice_buffer_destroy_internal(&exec_ctx, |
| 68 | &decompressed_slices_buffer); |
Craig Tiller | 9a57633 | 2015-06-17 10:21:49 -0700 | [diff] [blame] | 69 | } else { /* not compressed, use the input buffer as output */ |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 70 | reader->buffer_out = reader->buffer_in; |
| 71 | } |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 72 | reader->current.index = 0; |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 73 | break; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 74 | } |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 75 | grpc_exec_ctx_finish(&exec_ctx); |
David Garcia Quintas | 6721d4f | 2016-06-30 17:17:23 -0700 | [diff] [blame] | 76 | return 1; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 77 | } |
| 78 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 79 | void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) { |
David Garcia Quintas | 25d02d5 | 2015-06-04 17:40:54 -0700 | [diff] [blame] | 80 | switch (reader->buffer_in->type) { |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 81 | 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 Quintas | 25d02d5 | 2015-06-04 17:40:54 -0700 | [diff] [blame] | 86 | break; |
David Garcia Quintas | 25d02d5 | 2015-06-04 17:40:54 -0700 | [diff] [blame] | 87 | } |
David Garcia Quintas | 02c677c | 2015-06-02 14:40:07 -0700 | [diff] [blame] | 88 | } |
| 89 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 90 | int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, |
| 91 | grpc_slice* slice) { |
David Garcia Quintas | 25d02d5 | 2015-06-04 17:40:54 -0700 | [diff] [blame] | 92 | switch (reader->buffer_in->type) { |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 93 | case GRPC_BB_RAW: { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 94 | grpc_slice_buffer* slice_buffer; |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 95 | slice_buffer = &reader->buffer_out->data.raw.slice_buffer; |
| 96 | if (reader->current.index < slice_buffer->count) { |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 97 | *slice = grpc_slice_ref_internal( |
| 98 | slice_buffer->slices[reader->current.index]); |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 99 | reader->current.index += 1; |
| 100 | return 1; |
| 101 | } |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 102 | break; |
David Garcia Quintas | 59f905d | 2015-06-08 16:31:19 -0700 | [diff] [blame] | 103 | } |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 104 | } |
| 105 | return 0; |
| 106 | } |
David Garcia Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 107 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 108 | grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader) { |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 109 | grpc_slice in_slice; |
David Garcia Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 110 | size_t bytes_read = 0; |
| 111 | const size_t input_size = grpc_byte_buffer_length(reader->buffer_out); |
Craig Tiller | 423d6fd | 2017-04-12 13:15:45 -0700 | [diff] [blame] | 112 | grpc_slice out_slice = GRPC_SLICE_MALLOC(input_size); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 113 | uint8_t* const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */ |
David Garcia Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 114 | |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 115 | grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
David Garcia Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 116 | while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) { |
Craig Tiller | 618e67d | 2016-10-26 21:08:10 -0700 | [diff] [blame] | 117 | 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 Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 119 | bytes_read += slice_length; |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 120 | grpc_slice_unref_internal(&exec_ctx, in_slice); |
David Garcia Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 121 | GPR_ASSERT(bytes_read <= input_size); |
| 122 | } |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 123 | grpc_exec_ctx_finish(&exec_ctx); |
David Garcia Quintas | 6eb3925 | 2015-10-30 17:01:05 -0700 | [diff] [blame] | 124 | return out_slice; |
| 125 | } |