in src/constbuffer_array_batcher.c [11:170]
CONSTBUFFER_ARRAY_HANDLE constbuffer_array_batcher_batch(CONSTBUFFER_ARRAY_HANDLE* payloads, uint32_t count)
{
CONSTBUFFER_ARRAY_HANDLE result;
if (
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_001: [ If payloads is NULL, constbuffer_array_batcher_batch shall fail and return NULL. ]*/
(payloads == NULL) ||
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_002: [ If count is 0, constbuffer_array_batcher_batch shall fail and return NULL. ]*/
(count == 0)
)
{
LogError("CONSTBUFFER_ARRAY_HANDLE* payloads=%p, uint32_t count=%" PRIu32,
payloads, count);
}
else
{
uint32_t i;
size_t total_buffer_count = 0;
uint32_t* header_memory;
for (i = 0; i < count; i++)
{
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_023: [ If any of the payload const buffer arrays is NULL, constbuffer_array_batcher_batch shall fail and return NULL. ]*/
if (payloads[i] == NULL)
{
break;
}
}
if (i < count)
{
LogError("Payload %" PRIu32 " is NULL", i);
}
else
{
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_003: [ Otherwise constbuffer_array_batcher_batch shall obtain the number of buffers used by each CONSTBUFFER_ARRAY. ]*/
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_004: [ constbuffer_array_batcher_batch shall allocate memory for the header buffer (enough to hold the entire batch header namingly (count + 1) uint32_t values). ]*/
size_t count_size_t = (size_t)count; // handle -Werror=type-limits
size_t malloc_size = safe_add_size_t(count_size_t, 1);
malloc_size = safe_multiply_size_t(malloc_size, sizeof(uint32_t));
if (malloc_size == SIZE_MAX ||
(header_memory = malloc(malloc_size)) == NULL)
{
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_010: [ If any error occurrs, constbuffer_array_batcher_batch shall fail and return NULL. ]*/
LogError("malloc failed, size:%zu", malloc_size);
}
else
{
CONSTBUFFER_HANDLE* all_buffers;
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_005: [ count shall be written as the first uint32_t in the header memory. ]*/
write_uint32_t((void*)&header_memory[0], count);
for (i = 0; i < count; i++)
{
uint32_t buffer_count;
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_003: [ Otherwise constbuffer_array_batcher_batch shall obtain the number of buffers used by each CONSTBUFFER_ARRAY. ]*/
(void)constbuffer_array_get_buffer_count(payloads[i], &buffer_count);
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_006: [ The count of buffers for each array in payloads shall also be written in the header. ]*/
write_uint32_t((void*)&header_memory[i + 1], buffer_count);
total_buffer_count += buffer_count;
}
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_007: [ constbuffer_array_batcher_batch shall allocate enough memory for all the buffer handles in all the arrays + one extra header buffer handle. ]*/
size_t all_buffers_array_size = safe_add_size_t(total_buffer_count, 1);
malloc_size = safe_multiply_size_t(sizeof(CONSTBUFFER_HANDLE), (all_buffers_array_size));
if (malloc_size == SIZE_MAX)
{
LogError("malloc size is invalid");
}
else if ((all_buffers = malloc(malloc_size)) == NULL)
{
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_010: [ If any error occurrs, constbuffer_array_batcher_batch shall fail and return NULL. ]*/
LogError("malloc failed");
}
else
{
uint32_t current_index = 0;
size_t move_memory_size = safe_multiply_size_t(sizeof(uint32_t), ((size_t)count + 1));
if (move_memory_size == SIZE_MAX)
{
LogError("invalid malloc size in CONSTBUFFER_CreateWithMoveMemory");
}
else if ((all_buffers[current_index] = CONSTBUFFER_CreateWithMoveMemory((void*)header_memory, move_memory_size)) == NULL)
{
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_010: [ If any error occurrs, constbuffer_array_batcher_batch shall fail and return NULL. ]*/
LogError("CONSTBUFFER_CreateWithMoveMemory failed");
}
else
{
current_index++;
header_memory = NULL;
/* Codes_SRS_CONSTBUFFER_ARRAY_BATCHER_01_009: [ constbuffer_array_batcher_batch shall populate the rest of the handles in the newly allocated handles array with the const buffer handles obtained from the arrays in payloads. ]*/
for (i = 0; i < count; i++)
{
uint32_t buffer_count;
uint32_t j;
(void)constbuffer_array_get_buffer_count(payloads[i], &buffer_count);
for (j = 0; j < buffer_count; j++)
{
#ifdef _MSC_VER
#pragma warning(disable:6386) // warning C6386: Buffer overrun while writing to 'all_buffers'
#endif
all_buffers[current_index++] = constbuffer_array_get_buffer(payloads[i], j);
#ifdef _MSC_VER
#pragma warning (default:6386)
#endif
}
}
result = constbuffer_array_create(all_buffers, (uint32_t)all_buffers_array_size);
for (i = 0; i < all_buffers_array_size; i++)
{
#ifdef _MSC_VER
#pragma warning(disable:6385) // warning C6385: Reading invalid data from 'all_buffers'
#endif
CONSTBUFFER_DecRef(all_buffers[i]);
#ifdef _MSC_VER
#pragma warning (default:6385)
#endif
}
if (result == NULL)
{
LogError("constbuffer_array_create failed");
}
else
{
free(all_buffers);
all_buffers = NULL;
goto all_ok;
}
}
free(all_buffers);
}
if (header_memory != NULL)
{
free(header_memory);
}
}
}
}
result = NULL;
all_ok:
return result;
}