OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * |
| 3 * Copyright 2015, Google Inc. |
| 4 * All rights reserved. |
| 5 * |
| 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions are |
| 8 * met: |
| 9 * |
| 10 * * Redistributions of source code must retain the above copyright |
| 11 * notice, this list of conditions and the following disclaimer. |
| 12 * * Redistributions in binary form must reproduce the above |
| 13 * copyright notice, this list of conditions and the following disclaimer |
| 14 * in the documentation and/or other materials provided with the |
| 15 * distribution. |
| 16 * * Neither the name of Google Inc. nor the names of its |
| 17 * contributors may be used to endorse or promote products derived from |
| 18 * this software without specific prior written permission. |
| 19 * |
| 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 * |
| 32 */ |
| 33 |
| 34 #include "test/core/util/slice_splitter.h" |
| 35 |
| 36 #include <string.h> |
| 37 |
| 38 #include <grpc/support/alloc.h> |
| 39 #include <grpc/support/useful.h> |
| 40 |
| 41 const char *grpc_slice_split_mode_name(grpc_slice_split_mode mode) { |
| 42 switch (mode) { |
| 43 case GRPC_SLICE_SPLIT_IDENTITY: |
| 44 return "identity"; |
| 45 case GRPC_SLICE_SPLIT_MERGE_ALL: |
| 46 return "merge_all"; |
| 47 case GRPC_SLICE_SPLIT_ONE_BYTE: |
| 48 return "one_byte"; |
| 49 } |
| 50 return "error"; |
| 51 } |
| 52 |
| 53 void grpc_split_slices(grpc_slice_split_mode mode, gpr_slice *src_slices, |
| 54 size_t src_slice_count, gpr_slice **dst_slices, |
| 55 size_t *dst_slice_count) { |
| 56 size_t i, j; |
| 57 size_t length; |
| 58 |
| 59 switch (mode) { |
| 60 case GRPC_SLICE_SPLIT_IDENTITY: |
| 61 *dst_slice_count = src_slice_count; |
| 62 *dst_slices = gpr_malloc(sizeof(gpr_slice) * src_slice_count); |
| 63 for (i = 0; i < src_slice_count; i++) { |
| 64 (*dst_slices)[i] = src_slices[i]; |
| 65 gpr_slice_ref((*dst_slices)[i]); |
| 66 } |
| 67 break; |
| 68 case GRPC_SLICE_SPLIT_MERGE_ALL: |
| 69 *dst_slice_count = 1; |
| 70 length = 0; |
| 71 for (i = 0; i < src_slice_count; i++) { |
| 72 length += GPR_SLICE_LENGTH(src_slices[i]); |
| 73 } |
| 74 *dst_slices = gpr_malloc(sizeof(gpr_slice)); |
| 75 **dst_slices = gpr_slice_malloc(length); |
| 76 length = 0; |
| 77 for (i = 0; i < src_slice_count; i++) { |
| 78 memcpy(GPR_SLICE_START_PTR(**dst_slices) + length, |
| 79 GPR_SLICE_START_PTR(src_slices[i]), |
| 80 GPR_SLICE_LENGTH(src_slices[i])); |
| 81 length += GPR_SLICE_LENGTH(src_slices[i]); |
| 82 } |
| 83 break; |
| 84 case GRPC_SLICE_SPLIT_ONE_BYTE: |
| 85 length = 0; |
| 86 for (i = 0; i < src_slice_count; i++) { |
| 87 length += GPR_SLICE_LENGTH(src_slices[i]); |
| 88 } |
| 89 *dst_slice_count = length; |
| 90 *dst_slices = gpr_malloc(sizeof(gpr_slice) * length); |
| 91 length = 0; |
| 92 for (i = 0; i < src_slice_count; i++) { |
| 93 for (j = 0; j < GPR_SLICE_LENGTH(src_slices[i]); j++) { |
| 94 (*dst_slices)[length] = gpr_slice_sub(src_slices[i], j, j + 1); |
| 95 length++; |
| 96 } |
| 97 } |
| 98 break; |
| 99 } |
| 100 } |
| 101 |
| 102 void grpc_split_slices_to_buffer(grpc_slice_split_mode mode, |
| 103 gpr_slice *src_slices, size_t src_slice_count, |
| 104 gpr_slice_buffer *dst) { |
| 105 gpr_slice *slices; |
| 106 size_t nslices; |
| 107 size_t i; |
| 108 grpc_split_slices(mode, src_slices, src_slice_count, &slices, &nslices); |
| 109 for (i = 0; i < nslices; i++) { |
| 110 /* add indexed to avoid re-merging split slices */ |
| 111 gpr_slice_buffer_add_indexed(dst, slices[i]); |
| 112 } |
| 113 gpr_free(slices); |
| 114 } |
| 115 |
| 116 void grpc_split_slice_buffer(grpc_slice_split_mode mode, gpr_slice_buffer *src, |
| 117 gpr_slice_buffer *dst) { |
| 118 grpc_split_slices_to_buffer(mode, src->slices, src->count, dst); |
| 119 } |
| 120 |
| 121 gpr_slice grpc_slice_merge(gpr_slice *slices, size_t nslices) { |
| 122 uint8_t *out = NULL; |
| 123 size_t length = 0; |
| 124 size_t capacity = 0; |
| 125 size_t i; |
| 126 |
| 127 for (i = 0; i < nslices; i++) { |
| 128 if (GPR_SLICE_LENGTH(slices[i]) + length > capacity) { |
| 129 capacity = GPR_MAX(capacity * 2, GPR_SLICE_LENGTH(slices[i]) + length); |
| 130 out = gpr_realloc(out, capacity); |
| 131 } |
| 132 memcpy(out + length, GPR_SLICE_START_PTR(slices[i]), |
| 133 GPR_SLICE_LENGTH(slices[i])); |
| 134 length += GPR_SLICE_LENGTH(slices[i]); |
| 135 } |
| 136 |
| 137 return gpr_slice_new(out, length, gpr_free); |
| 138 } |
OLD | NEW |