Reduce duplication

pull/10613/head
Craig Tiller 8 years ago
parent 423d6fd7ed
commit 255ea13aa3
  1. 7
      include/grpc/slice.h
  2. 41
      src/core/lib/slice/slice.c
  3. 41
      src/core/lib/slice/slice_buffer.c

@ -124,8 +124,11 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end);
Requires s intialized, split <= s.length */
GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split);
/* The same as grpc_slice_split_tail, but without altering refcounts */
GPRAPI grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *s, size_t split);
/* The same as grpc_slice_split_tail, but with an option to skip altering
* refcounts (grpc_slice_split_tail_maybe_ref(..., true) is equivalent to
* grpc_slice_split_tail(...)) */
GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *s, size_t split,
bool inc_refs);
/* Splits s into two: modifies s to be s[split:s.length], and returns a new
slice, sharing a refcount with s, that contains s[0:split].

@ -312,7 +312,8 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) {
return subset;
}
grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *source, size_t split,
bool incref) {
grpc_slice tail;
if (source->refcount == NULL) {
@ -334,43 +335,13 @@ grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
tail_length);
} else {
/* Build the result */
if (incref) {
tail.refcount = source->refcount->sub_refcount;
/* Bump the refcount */
tail.refcount->vtable->ref(tail.refcount);
/* Point into the source array */
tail.data.refcounted.bytes = source->data.refcounted.bytes + split;
tail.data.refcounted.length = tail_length;
}
source->refcount = source->refcount->sub_refcount;
source->data.refcounted.length = split;
}
return tail;
}
grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *source, size_t split) {
grpc_slice tail;
if (source->refcount == NULL) {
/* inlined data, copy it out */
GPR_ASSERT(source->data.inlined.length >= split);
tail.refcount = NULL;
tail.data.inlined.length = (uint8_t)(source->data.inlined.length - split);
memcpy(tail.data.inlined.bytes, source->data.inlined.bytes + split,
tail.data.inlined.length);
source->data.inlined.length = (uint8_t)split;
} else {
size_t tail_length = source->data.refcounted.length - split;
GPR_ASSERT(source->data.refcounted.length >= split);
if (tail_length < sizeof(tail.data.inlined.bytes)) {
/* Copy out the bytes - it'll be cheaper than refcounting */
tail.refcount = NULL;
tail.data.inlined.length = (uint8_t)tail_length;
memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split,
tail_length);
} else {
/* Build the result */
tail.refcount = &noop_refcount;
}
/* Point into the source array */
tail.data.refcounted.bytes = source->data.refcounted.bytes + split;
tail.data.refcounted.length = tail_length;
@ -382,6 +353,10 @@ grpc_slice grpc_slice_split_tail_no_ref(grpc_slice *source, size_t split) {
return tail;
}
grpc_slice grpc_slice_split_tail(grpc_slice *source, size_t split) {
return grpc_slice_split_tail_maybe_ref(source, split, true);
}
grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
grpc_slice head;

@ -253,8 +253,9 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer *src,
src->length = 0;
}
void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
grpc_slice_buffer *dst) {
static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer *src, size_t n,
grpc_slice_buffer *dst,
bool incref) {
GPR_ASSERT(src->length >= n);
if (src->length == n) {
grpc_slice_buffer_move_into(src, dst);
@ -274,7 +275,8 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
grpc_slice_buffer_add(dst, slice);
break;
} else { /* n < slice_len */
grpc_slice_buffer_undo_take_first(src, grpc_slice_split_tail(&slice, n));
grpc_slice_buffer_undo_take_first(
src, grpc_slice_split_tail_maybe_ref(&slice, n, incref));
GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
grpc_slice_buffer_add(dst, slice);
break;
@ -285,37 +287,14 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
GPR_ASSERT(src->count > 0);
}
void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, size_t n,
void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
grpc_slice_buffer *dst) {
GPR_ASSERT(src->length >= n);
if (src->length == n) {
grpc_slice_buffer_move_into(src, dst);
return;
slice_buffer_move_first_maybe_ref(src, n, dst, true);
}
size_t output_len = dst->length + n;
size_t new_input_len = src->length - n;
while (src->count > 0) {
grpc_slice slice = grpc_slice_buffer_take_first(src);
size_t slice_len = GRPC_SLICE_LENGTH(slice);
if (n > slice_len) {
grpc_slice_buffer_add(dst, slice);
n -= slice_len;
} else if (n == slice_len) {
grpc_slice_buffer_add(dst, slice);
break;
} else { /* n < slice_len */
grpc_slice_buffer_undo_take_first(
src, grpc_slice_split_tail_no_ref(&slice, n));
GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
grpc_slice_buffer_add(dst, slice);
break;
}
}
GPR_ASSERT(dst->length == output_len);
GPR_ASSERT(src->length == new_input_len);
GPR_ASSERT(src->count > 0);
void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, size_t n,
grpc_slice_buffer *dst) {
slice_buffer_move_first_maybe_ref(src, n, dst, false);
}
void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx,

Loading…
Cancel
Save