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