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