Skip to content
Snippets Groups Projects
Commit 8ecf5f5a authored by Jan Tattermusch's avatar Jan Tattermusch Committed by GitHub
Browse files

Merge pull request #7120 from makdharma/issue6746

fix for working with compressed data. Fixes #6746.
parents 3b9419ed 17974029
No related branches found
No related tags found
No related merge requests found
...@@ -39,17 +39,21 @@ ...@@ -39,17 +39,21 @@
// 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; // The slice contains uncompressed data even if compressed data was received
while (grpc_byte_buffer_reader_next(&reader, &next) != 0){ // because the reader takes care of automatically decompressing it
memcpy(array + offset, GPR_SLICE_START_PTR(next), gpr_slice slice = grpc_byte_buffer_reader_readall(&reader);
(size_t)GPR_SLICE_LENGTH(next)); size_t uncompressed_length = GPR_SLICE_LENGTH(slice);
offset += GPR_SLICE_LENGTH(next); char *result = malloc(uncompressed_length);
gpr_slice_unref(next); if (result) {
memcpy(result, GPR_SLICE_START_PTR(slice), uncompressed_length);
} }
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 +69,9 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, ...@@ -65,8 +69,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)); size_t 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,8 +79,9 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, ...@@ -74,8 +79,9 @@ 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); // Not depending upon size assumption of NSUInteger
return [self dataWithBytesNoCopy:array length:length freeWhenDone:YES]; NSUInteger length_max = MIN(length, UINT_MAX);
return [self dataWithBytesNoCopy:array length:length_max freeWhenDone:YES];
} }
- (grpc_byte_buffer *)grpc_byteBuffer { - (grpc_byte_buffer *)grpc_byteBuffer {
...@@ -85,8 +91,10 @@ static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, ...@@ -85,8 +91,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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment