xref: /aosp_15_r20/external/grpc-grpc/test/core/util/slice_splitter.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 "test/core/util/slice_splitter.h"
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 #include <algorithm>
25 
26 #include <grpc/slice_buffer.h>
27 #include <grpc/support/alloc.h>
28 
grpc_slice_split_mode_name(grpc_slice_split_mode mode)29 const char* grpc_slice_split_mode_name(grpc_slice_split_mode mode) {
30   switch (mode) {
31     case GRPC_SLICE_SPLIT_IDENTITY:
32       return "identity";
33     case GRPC_SLICE_SPLIT_MERGE_ALL:
34       return "merge_all";
35     case GRPC_SLICE_SPLIT_ONE_BYTE:
36       return "one_byte";
37   }
38   return "error";
39 }
40 
grpc_split_slices(grpc_slice_split_mode mode,grpc_slice * src_slices,size_t src_slice_count,grpc_slice ** dst_slices,size_t * dst_slice_count)41 void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice* src_slices,
42                        size_t src_slice_count, grpc_slice** dst_slices,
43                        size_t* dst_slice_count) {
44   size_t i, j;
45   size_t length;
46 
47   switch (mode) {
48     case GRPC_SLICE_SPLIT_IDENTITY:
49       *dst_slice_count = src_slice_count;
50       *dst_slices = static_cast<grpc_slice*>(
51           gpr_malloc(sizeof(grpc_slice) * src_slice_count));
52       for (i = 0; i < src_slice_count; i++) {
53         (*dst_slices)[i] = src_slices[i];
54         grpc_slice_ref((*dst_slices)[i]);
55       }
56       break;
57     case GRPC_SLICE_SPLIT_MERGE_ALL:
58       *dst_slice_count = 1;
59       length = 0;
60       for (i = 0; i < src_slice_count; i++) {
61         length += GRPC_SLICE_LENGTH(src_slices[i]);
62       }
63       *dst_slices = static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice)));
64       **dst_slices = grpc_slice_malloc(length);
65       length = 0;
66       for (i = 0; i < src_slice_count; i++) {
67         memcpy(GRPC_SLICE_START_PTR(**dst_slices) + length,
68                GRPC_SLICE_START_PTR(src_slices[i]),
69                GRPC_SLICE_LENGTH(src_slices[i]));
70         length += GRPC_SLICE_LENGTH(src_slices[i]);
71       }
72       break;
73     case GRPC_SLICE_SPLIT_ONE_BYTE:
74       length = 0;
75       for (i = 0; i < src_slice_count; i++) {
76         length += GRPC_SLICE_LENGTH(src_slices[i]);
77       }
78       *dst_slice_count = length;
79       *dst_slices =
80           static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice) * length));
81       length = 0;
82       for (i = 0; i < src_slice_count; i++) {
83         for (j = 0; j < GRPC_SLICE_LENGTH(src_slices[i]); j++) {
84           (*dst_slices)[length] = grpc_slice_sub(src_slices[i], j, j + 1);
85           length++;
86         }
87       }
88       break;
89   }
90 }
91 
grpc_split_slices_to_buffer(grpc_slice_split_mode mode,grpc_slice * src_slices,size_t src_slice_count,grpc_slice_buffer * dst)92 void grpc_split_slices_to_buffer(grpc_slice_split_mode mode,
93                                  grpc_slice* src_slices, size_t src_slice_count,
94                                  grpc_slice_buffer* dst) {
95   grpc_slice* slices;
96   size_t nslices;
97   size_t i;
98   grpc_split_slices(mode, src_slices, src_slice_count, &slices, &nslices);
99   for (i = 0; i < nslices; i++) {
100     // add indexed to avoid re-merging split slices
101     grpc_slice_buffer_add_indexed(dst, slices[i]);
102   }
103   gpr_free(slices);
104 }
105 
grpc_split_slice_buffer(grpc_slice_split_mode mode,grpc_slice_buffer * src,grpc_slice_buffer * dst)106 void grpc_split_slice_buffer(grpc_slice_split_mode mode, grpc_slice_buffer* src,
107                              grpc_slice_buffer* dst) {
108   grpc_split_slices_to_buffer(mode, src->slices, src->count, dst);
109 }
110 
grpc_slice_merge(grpc_slice * slices,size_t nslices)111 grpc_slice grpc_slice_merge(grpc_slice* slices, size_t nslices) {
112   uint8_t* out = nullptr;
113   size_t length = 0;
114   size_t capacity = 0;
115   size_t i;
116 
117   for (i = 0; i < nslices; i++) {
118     if (GRPC_SLICE_LENGTH(slices[i]) + length > capacity) {
119       capacity = std::max(capacity * 2, GRPC_SLICE_LENGTH(slices[i]) + length);
120       out = static_cast<uint8_t*>(gpr_realloc(out, capacity));
121     }
122     memcpy(out + length, GRPC_SLICE_START_PTR(slices[i]),
123            GRPC_SLICE_LENGTH(slices[i]));
124     length += GRPC_SLICE_LENGTH(slices[i]);
125   }
126 
127   return grpc_slice_new(out, length, gpr_free);
128 }
129