UMOCKCALLRECORDER_HANDLE umockcallrecorder_clone()

in src/umockcallrecorder.c [594:719]


UMOCKCALLRECORDER_HANDLE umockcallrecorder_clone(UMOCKCALLRECORDER_HANDLE umock_call_recorder)
{
    UMOCKCALLRECORDER_HANDLE result;

    if (umock_call_recorder == NULL)
    {
        /* Codes_SRS_UMOCKCALLRECORDER_01_036: [ If the umock_call_recorder argument is NULL, umockcallrecorder_clone shall fail and return NULL. ]*/
        UMOCK_LOG("umockcallrecorder_clone: NULL umock_call_recorder.");
        result = NULL;
    }
    else
    {
        /* Codes_SRS_UMOCKCALLRECORDER_01_082: [ If a lock was created for the call recorder umock_call_recorder, umockcallrecorder_clone shall acquire_the lock in shared mode for umock_call_recorder. ]*/
        internal_lock_acquire_shared_if_needed(umock_call_recorder);
        {
            /* Codes_SRS_UMOCKCALLRECORDER_01_037: [ If allocating memory for the new umock call recorder instance fails, umockcallrecorder_clone shall fail and return NULL. ]*/
            /* Codes_SRS_UMOCKCALLRECORDER_01_085: [ If the lock_factory_create_lock associated with umock_call_recorder is not NULL, umockcallrecorder_clone shall create a new lock for the cloned call recorder. ]*/
            result = umockcallrecorder_create(umock_call_recorder->lock_factory_create_lock, umock_call_recorder->lock_factory_create_lock_params);
            if (result != NULL)
            {
                size_t i;

                result->expected_calls = umockalloc_malloc(sizeof(UMOCK_EXPECTED_CALL) * umock_call_recorder->expected_call_count);
                if (result->expected_calls == NULL)
                {
                    /* Codes_SRS_UMOCKCALLRECORDER_01_052: [ If any error occurs, umockcallrecorder_clone shall fail and return NULL. ]*/
                    umockcallrecorder_destroy(result);
                    result = NULL;
                    UMOCK_LOG("umockcallrecorder: clone call recorder failed - cannot allocate expected_calls.");
                }
                else
                {
                    for (i = 0; i < umock_call_recorder->expected_call_count; i++)
                    {
                        result->expected_calls[i].umockcall = NULL;
                    }

                    /* Codes_SRS_UMOCKCALLRECORDER_01_038: [ umockcallrecorder_clone shall clone all the expected calls. ]*/
                    for (i = 0; i < umock_call_recorder->expected_call_count; i++)
                    {
                        result->expected_calls[i].is_matched = umock_call_recorder->expected_calls[i].is_matched;

                        /* Codes_SRS_UMOCKCALLRECORDER_01_039: [ Each expected call shall be cloned by calling umockcall_clone. ]*/
                        result->expected_calls[i].umockcall = umockcall_clone(umock_call_recorder->expected_calls[i].umockcall);
                        if (result->expected_calls[i].umockcall == NULL)
                        {
                            break;
                        }
                    }

                    if (i < umock_call_recorder->expected_call_count)
                    {
                        size_t j;

                        /* Codes_SRS_UMOCKCALLRECORDER_01_040: [ If cloning an expected call fails, umockcallrecorder_clone shall fail and return NULL. ]*/
                        for (j = 0; j < i; j++)
                        {
                            umockcall_destroy(result->expected_calls[j].umockcall);
                            result->expected_calls[j].umockcall = NULL;
                        }

                        umockcallrecorder_destroy(result);
                        result = NULL;
                        UMOCK_LOG("umockcallrecorder: clone call recorder failed - cannot clone all expected calls.");
                    }
                    else
                    {
                        result->expected_call_count = umock_call_recorder->expected_call_count;

                        result->actual_calls = umockalloc_malloc(sizeof(UMOCKCALL_HANDLE) * umock_call_recorder->actual_call_count);
                        if (result->actual_calls == NULL)
                        {
                            /* Codes_SRS_UMOCKCALLRECORDER_01_052: [ If any error occurs, umockcallrecorder_clone shall fail and return NULL. ]*/
                            umockcallrecorder_destroy(result);
                            result = NULL;
                            UMOCK_LOG("umockcallrecorder: clone call recorder failed - cannot allocate expected_calls.");
                        }
                        else
                        {
                            for (i = 0; i < umock_call_recorder->actual_call_count; i++)
                            {
                                result->actual_calls[i] = NULL;
                            }

                            /* Codes_SRS_UMOCKCALLRECORDER_01_041: [ umockcallrecorder_clone shall clone all the actual calls. ]*/
                            for (i = 0; i < umock_call_recorder->actual_call_count; i++)
                            {
                                /* Codes_SRS_UMOCKCALLRECORDER_01_042: [ Each actual call shall be cloned by calling umockcall_clone. ]*/
                                result->actual_calls[i] = umockcall_clone(umock_call_recorder->actual_calls[i]);
                                if (result->actual_calls[i] == NULL)
                                {
                                    break;
                                }
                            }

                            if (i < umock_call_recorder->actual_call_count)
                            {
                                size_t j;

                                /* Codes_SRS_UMOCKCALLRECORDER_01_043: [ If cloning an actual call fails, umockcallrecorder_clone shall fail and return NULL. ]*/
                                for (j = 0; j < i; j++)
                                {
                                    umockcall_destroy(result->actual_calls[j]);
                                    result->actual_calls[j] = NULL;
                                }

                                umockcallrecorder_destroy(result);
                                result = NULL;
                                UMOCK_LOG("umockcallrecorder: clone call recorder failed - cannot clone all actual calls.");
                            }
                            else
                            {
                                result->actual_call_count = umock_call_recorder->actual_call_count;
                            }
                        }
                    }
                }
            }

            /* Codes_SRS_UMOCKCALLRECORDER_01_083: [ If a lock was created for the call recorder umock_call_recorder, umockcallrecorder_clone shall release the shared lock for umock_call_recorder. ]*/
            internal_lock_release_shared_if_needed(umock_call_recorder);
        }
    }

    return result;
}