static int zlib_body(z_stream* zs, grpc_slice_buffer* input, grpc_slice_buffer* output, int (*flate)(z_stream* zs, int flush)) { int r; int flush; size_t i; grpc_slice outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE); const uInt uint_max = ~(uInt)0; GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf); zs->next_out = GRPC_SLICE_START_PTR(outbuf); flush = Z_NO_FLUSH; for (i = 0; i < input->count; i++) { if (i == input->count - 1) flush = Z_FINISH; GPR_ASSERT(GRPC_SLICE_LENGTH(input->slices[i]) <= uint_max); zs->avail_in = (uInt)GRPC_SLICE_LENGTH(input->slices[i]); zs->next_in = GRPC_SLICE_START_PTR(input->slices[i]); do { if (zs->avail_out == 0) { grpc_slice_buffer_add_indexed(output, outbuf); outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE); GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf); zs->next_out = GRPC_SLICE_START_PTR(outbuf); } r = flate(zs, flush); if (r < 0 && r != Z_BUF_ERROR /* not fatal */) { gpr_log(GPR_INFO, "zlib error (%d)", r); goto error; } } while (zs->avail_out == 0); if (zs->avail_in) { gpr_log(GPR_INFO, "zlib: not all input consumed"); goto error; } } GPR_ASSERT(outbuf.refcount); outbuf.data.refcounted.length -= zs->avail_out; grpc_slice_buffer_add_indexed(output, outbuf); return 1; error: grpc_slice_unref(outbuf); return 0; }
void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst) { const size_t sep_len = strlen(sep); size_t begin, end; GPR_ASSERT(sep_len > 0); if (slice_find_separator_offset(str, sep, 0, &begin, &end) != 0) { do { grpc_slice_buffer_add_indexed(dst, grpc_slice_sub(str, begin, end)); } while (slice_find_separator_offset(str, sep, end + sep_len, &begin, &end) != 0); grpc_slice_buffer_add_indexed( dst, grpc_slice_sub(str, end + sep_len, GRPC_SLICE_LENGTH(str))); } else { /* no sep found, add whole input */ grpc_slice_buffer_add_indexed(dst, grpc_slice_ref(str)); } }
static void ru_allocated_slices(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_resource_user_slice_allocator *slice_allocator = arg; if (error == GRPC_ERROR_NONE) { for (size_t i = 0; i < slice_allocator->count; i++) { grpc_slice_buffer_add_indexed( slice_allocator->dest, ru_slice_create(slice_allocator->resource_user, slice_allocator->length)); } } grpc_closure_run(exec_ctx, &slice_allocator->on_done, GRPC_ERROR_REF(error)); }
void grpc_split_slices_to_buffer(grpc_slice_split_mode mode, grpc_slice *src_slices, size_t src_slice_count, grpc_slice_buffer *dst) { grpc_slice *slices; size_t nslices; size_t i; grpc_split_slices(mode, src_slices, src_slice_count, &slices, &nslices); for (i = 0; i < nslices; i++) { /* add indexed to avoid re-merging split slices */ grpc_slice_buffer_add_indexed(dst, slices[i]); } gpr_free(slices); }
/* begin a new frame: reserve off header space, remember how many bytes we'd output before beginning */ static void begin_frame(framer_state *st) { st->header_idx = grpc_slice_buffer_add_indexed(st->output, grpc_slice_malloc(9)); st->output_length_at_start_of_frame = st->output->length; }