/* Clones the list and its elements
 *
 * The values are cloned using the value_clone_function
 * On error the values are freed using the value_free_function
 *
 * Returns 1 if successful or -1 on error
 */
int libewf_list_clone(
    libewf_list_t **destination_list,
    libewf_list_t *source_list,
    int (*value_free_function)(
        intptr_t *value,
        liberror_error_t **error ),
    int (*value_clone_function)(
        intptr_t **destination,
        intptr_t *source,
        liberror_error_t **error ),
    liberror_error_t **error )
{
    libewf_list_element_t *source_list_element = NULL;
    intptr_t *destination_value                = NULL;
    static char *function                      = "libewf_list_clone";
    int element_index                          = 0;

    if( destination_list == NULL )
    {
        liberror_error_set(
            error,
            LIBERROR_ERROR_DOMAIN_ARGUMENTS,
            LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
            "%s: invalid destination list.",
            function );

        return( -1 );
    }
    if( *destination_list != NULL )
    {
        liberror_error_set(
            error,
            LIBERROR_ERROR_DOMAIN_RUNTIME,
            LIBERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
            "%s: invalid destination list already set.",
            function );

        return( -1 );
    }
    if( value_free_function == NULL )
    {
        liberror_error_set(
            error,
            LIBERROR_ERROR_DOMAIN_ARGUMENTS,
            LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
            "%s: invalid value free function.",
            function );

        return( -1 );
    }
    if( value_clone_function == NULL )
    {
        liberror_error_set(
            error,
            LIBERROR_ERROR_DOMAIN_ARGUMENTS,
            LIBERROR_ARGUMENT_ERROR_INVALID_VALUE,
            "%s: invalid value clone function.",
            function );

        return( -1 );
    }
    if( source_list == NULL )
    {
        *destination_list = NULL;

        return( 1 );
    }
    if( libewf_list_initialize(
                destination_list,
                error ) != 1 )
    {
        liberror_error_set(
            error,
            LIBERROR_ERROR_DOMAIN_RUNTIME,
            LIBERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
            "%s: unable to create destination list.",
            function );

        goto on_error;
    }
    if( *destination_list == NULL )
    {
        liberror_error_set(
            error,
            LIBERROR_ERROR_DOMAIN_RUNTIME,
            LIBERROR_RUNTIME_ERROR_VALUE_MISSING,
            "%s: missing destination list.",
            function );

        goto on_error;
    }
    source_list_element = source_list->first_element;

    for( element_index = 0;
            element_index < source_list->number_of_elements;
            element_index++ )
    {
        if( source_list_element == NULL )
        {
            liberror_error_set(
                error,
                LIBERROR_ERROR_DOMAIN_RUNTIME,
                LIBERROR_RUNTIME_ERROR_VALUE_MISSING,
                "%s: corruption detected in source list element: %d.",
                function,
                element_index );

            goto on_error;
        }
        if( value_clone_function(
                    &destination_value,
                    source_list_element->value,
                    error ) != 1 )
        {
            liberror_error_set(
                error,
                LIBERROR_ERROR_DOMAIN_RUNTIME,
                LIBERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
                "%s: unable to clone value of list element: %d.",
                function,
                element_index );

            goto on_error;
        }
        if( libewf_list_append_value(
                    *destination_list,
                    destination_value,
                    error ) != 1 )
        {
            liberror_error_set(
                error,
                LIBERROR_ERROR_DOMAIN_RUNTIME,
                LIBERROR_RUNTIME_ERROR_APPEND_FAILED,
                "%s: unable to append value of list element: %d.",
                function,
                element_index );

            goto on_error;
        }
        destination_value = NULL;

        source_list_element = source_list_element->next_element;
    }
    return( 1 );

on_error:
    if( destination_value != NULL )
    {
        value_free_function(
            destination_value,
            NULL );
    }
    if( *destination_list != NULL )
    {
        libewf_list_free(
            destination_list,
            value_free_function,
            error );
    }
    return( -1 );
}
/* Clones the range list value
 *
 * The values are cloned using the value_clone_function
 * On error the values are freed using the value_free_function
 *
 * Returns 1 if successful or -1 on error
 */
int libcdata_range_list_value_clone(
     libcdata_range_list_value_t **destination_range_list_value,
     libcdata_range_list_value_t *source_range_list_value,
     int (*value_free_function)(
            intptr_t **value,
            libcerror_error_t **error ),
     int (*value_clone_function)(
            intptr_t **destination_value,
            intptr_t *source_value,
            libcerror_error_t **error ),
     libcerror_error_t **error )
{
	static char *function = "libcdata_range_list_value_clone";

	if( destination_range_list_value == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid destination range list value.",
		 function );

		return( -1 );
	}
	if( *destination_range_list_value != NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
		 "%s: invalid destination range list value value already set.",
		 function );

		return( -1 );
	}
	if( value_free_function == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid value free function.",
		 function );

		return( -1 );
	}
	if( value_clone_function == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid value clone function.",
		 function );

		return( -1 );
	}
	if( source_range_list_value == NULL )
	{
		*destination_range_list_value = NULL;

		return( 1 );
	}
	*destination_range_list_value = memory_allocate_structure(
	                                 libcdata_range_list_value_t );

	if( *destination_range_list_value == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
		 "%s: unable to create destination range list value.",
		 function );

		goto on_error;
	}
	if( memory_copy(
	     *destination_range_list_value,
	     source_range_list_value,
	     sizeof( libcdata_range_list_value_t ) ) == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
		 "%s: unable to copy source to destination range list value.",
		 function );

		memory_free(
		 *destination_range_list_value );

		*destination_range_list_value = NULL;

		return( -1 );
	}
	( *destination_range_list_value )->value = NULL;

	if( value_clone_function(
	     &( ( *destination_range_list_value )->value ),
	     source_range_list_value->value,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
		 "%s: unable to create destination value.",
		 function );

		goto on_error;
	}
	return( 1 );

on_error:
	if( *destination_range_list_value != NULL )
	{
		if( ( *destination_range_list_value )->value != NULL )
		{
			value_free_function(
			 &( ( *destination_range_list_value )->value ),
			 NULL );
		}
		memory_free(
		 *destination_range_list_value );

		*destination_range_list_value = NULL;
	}
	return( -1 );
}