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/byte_buffer.h>
20 #include <grpc/byte_buffer_reader.h>
21 #include <grpc/grpc.h>
22 #include <grpc/slice.h>
23 #include <grpc/support/port_platform.h>
24 #include <stdint.h>
25 #include <string.h>
26
27 #include "absl/log/check.h"
28 #include "src/core/lib/iomgr/exec_ctx.h"
29 #include "src/core/lib/slice/slice.h"
30
grpc_byte_buffer_reader_init(grpc_byte_buffer_reader * reader,grpc_byte_buffer * buffer)31 int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
32 grpc_byte_buffer* buffer) {
33 reader->buffer_in = buffer;
34 switch (reader->buffer_in->type) {
35 case GRPC_BB_RAW:
36 reader->buffer_out = reader->buffer_in;
37 reader->current.index = 0;
38 break;
39 }
40 return 1;
41 }
42
grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader * reader)43 void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) {
44 reader->buffer_out = nullptr;
45 }
46
grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader * reader,grpc_slice ** slice)47 int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader,
48 grpc_slice** slice) {
49 switch (reader->buffer_in->type) {
50 case GRPC_BB_RAW: {
51 grpc_slice_buffer* slice_buffer;
52 slice_buffer = &reader->buffer_out->data.raw.slice_buffer;
53 if (reader->current.index < slice_buffer->count) {
54 *slice = &slice_buffer->slices[reader->current.index];
55 reader->current.index += 1;
56 return 1;
57 }
58 break;
59 }
60 }
61 return 0;
62 }
63
grpc_byte_buffer_reader_next(grpc_byte_buffer_reader * reader,grpc_slice * slice)64 int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
65 grpc_slice* slice) {
66 switch (reader->buffer_in->type) {
67 case GRPC_BB_RAW: {
68 grpc_slice_buffer* slice_buffer;
69 slice_buffer = &reader->buffer_out->data.raw.slice_buffer;
70 if (reader->current.index < slice_buffer->count) {
71 *slice =
72 grpc_core::CSliceRef(slice_buffer->slices[reader->current.index]);
73 reader->current.index += 1;
74 return 1;
75 }
76 break;
77 }
78 }
79 return 0;
80 }
81
grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader * reader)82 grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader) {
83 grpc_slice in_slice;
84 size_t bytes_read = 0;
85 const size_t input_size = grpc_byte_buffer_length(reader->buffer_out);
86 grpc_slice out_slice = GRPC_SLICE_MALLOC(input_size);
87 uint8_t* const outbuf = GRPC_SLICE_START_PTR(out_slice); // just an alias
88
89 grpc_core::ExecCtx exec_ctx;
90 while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) {
91 const size_t slice_length = GRPC_SLICE_LENGTH(in_slice);
92 memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length);
93 bytes_read += slice_length;
94 grpc_core::CSliceUnref(in_slice);
95 CHECK(bytes_read <= input_size);
96 }
97
98 return out_slice;
99 }
100