in source/list_utils.c [43:106]
static int list_copy_all(
struct aws_allocator *alloc,
struct aws_array_list *dest,
const struct aws_array_list *src,
clone_item_fn cloner,
clean_up_item_fn cleaner) {
AWS_ERROR_PRECONDITION(aws_allocator_is_valid(alloc));
AWS_ERROR_PRECONDITION(src != dest);
AWS_ERROR_PRECONDITION(aws_array_list_is_valid(dest));
AWS_ERROR_PRECONDITION(aws_array_list_is_valid(src));
AWS_ERROR_PRECONDITION(dest->item_size == src->item_size);
size_t initial_length = aws_array_list_length(dest);
size_t src_length = aws_array_list_length(src);
int lasterr;
/* You can do this with a variable length uint8_t array everywhere except Windows,
* but Microsoft forces us to do an allocation here.
*/
void *dest_item = aws_mem_acquire(alloc, dest->item_size);
if (!dest_item) {
return AWS_OP_ERR;
}
for (size_t i = 0; i < src_length; i++) {
void *src_item;
if (aws_array_list_get_at_ptr(src, &src_item, i)) {
goto err;
}
if (cloner(alloc, dest_item, src_item)) {
goto err;
}
if (aws_array_list_push_back(dest, dest_item)) {
cleaner(dest_item);
goto err;
}
}
aws_mem_release(alloc, dest_item);
return AWS_OP_SUCCESS;
err:
aws_mem_release(alloc, dest_item);
lasterr = aws_last_error();
while (aws_array_list_length(dest) > initial_length) {
void *dest_item_ptr;
if (aws_array_list_get_at_ptr(dest, &dest_item_ptr, aws_array_list_length(dest) - 1)) {
/*
* We had elements at aws_array_list, but not anymore, it seems.
* Someone must be mucking with the destination list from another thread;
* abort before we do any more damage.
*/
abort();
}
cleaner(dest_item_ptr);
aws_array_list_pop_back(dest);
}
return aws_raise_error(lasterr);
}