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