fix for working with compressed data. Fixes #6746.

Using correct API that gives length of uncompressed data so correct amount of memory is allocated.
pull/7120/head
Makarand Dharmapurikar 9 years ago
parent fe466b0e17
commit d99a925d52
  1. 30
      src/objective-c/GRPCClient/private/NSData+GRPC.m

@ -39,17 +39,19 @@
// TODO(jcanizales): Move these two incantations to the C library. // TODO(jcanizales): Move these two incantations to the C library.
static void CopyByteBufferToCharArray(grpc_byte_buffer *buffer, char *array) { static void MallocAndCopyByteBufferToCharArray(grpc_byte_buffer *buffer,
size_t offset = 0; size_t *length, char **array) {
grpc_byte_buffer_reader reader; grpc_byte_buffer_reader reader;
grpc_byte_buffer_reader_init(&reader, buffer); grpc_byte_buffer_reader_init(&reader, buffer);
gpr_slice next; gpr_slice slice = grpc_byte_buffer_reader_readall(&reader);
while (grpc_byte_buffer_reader_next(&reader, &next) != 0){ size_t uncompressed_length = GPR_SLICE_LENGTH(slice);
memcpy(array + offset, GPR_SLICE_START_PTR(next), char *result = malloc(uncompressed_length);
(size_t)GPR_SLICE_LENGTH(next)); if (result) {
offset += GPR_SLICE_LENGTH(next); memcpy(result, GPR_SLICE_START_PTR(slice), uncompressed_length);
gpr_slice_unref(next);
} }
gpr_slice_unref(slice);
*array = result;
*length = uncompressed_length;
} }
static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
@ -65,8 +67,9 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
if (buffer == NULL) { if (buffer == NULL) {
return nil; return nil;
} }
NSUInteger length = grpc_byte_buffer_length(buffer); char *array;
char *array = malloc(length * sizeof(*array)); NSUInteger length;
MallocAndCopyByteBufferToCharArray(buffer, &length, &array);
if (!array) { if (!array) {
// TODO(jcanizales): grpc_byte_buffer is reference-counted, so we can // TODO(jcanizales): grpc_byte_buffer is reference-counted, so we can
// prevent this memory problem by implementing a subclass of NSData // prevent this memory problem by implementing a subclass of NSData
@ -74,7 +77,6 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
// can be implemented using a grpc_byte_buffer_reader. // can be implemented using a grpc_byte_buffer_reader.
return nil; return nil;
} }
CopyByteBufferToCharArray(buffer, array);
return [self dataWithBytesNoCopy:array length:length freeWhenDone:YES]; return [self dataWithBytesNoCopy:array length:length freeWhenDone:YES];
} }
@ -85,8 +87,10 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array,
// The following implementation is thus not optimal, sometimes requiring two // The following implementation is thus not optimal, sometimes requiring two
// copies (one by self.bytes and another by gpr_slice_from_copied_buffer). // copies (one by self.bytes and another by gpr_slice_from_copied_buffer).
// If it turns out to be an issue, we can use enumerateByteRangesUsingblock: // If it turns out to be an issue, we can use enumerateByteRangesUsingblock:
// to create an array of gpr_slice objects to pass to grpc_raw_byte_buffer_create. // to create an array of gpr_slice objects to pass to
// grpc_raw_byte_buffer_create.
// That would make it do exactly one copy, always. // That would make it do exactly one copy, always.
return CopyCharArrayToNewByteBuffer((const char *)self.bytes, (size_t)self.length); return CopyCharArrayToNewByteBuffer((const char *)self.bytes,
(size_t)self.length);
} }
@end @end

Loading…
Cancel
Save