src/async_type_helper.c (159 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. #include <stdint.h> #include <inttypes.h> #include "macro_utils/macro_utils.h" #include "c_logging/logger.h" #include "c_pal/gballoc_hl.h" #include "c_pal/gballoc_hl_redirect.h" #include "c_util/uuid_string.h" #include "c_util/async_type_helper.h" DEFINE_ASYNC_TYPE_HELPER_COPY_HANDLER(UUID_T, dest, source) { int result; /*Codes_SRS_ASYNC_TYPE_HELPER_04_001: [ If dest is NULL then the copy handler will fail and return a non-zero value. ]*/ if (dest == NULL) { LogError("Invalid args: UUID_T* dest=%p, const UUID_T source=%" PRI_UUID_T "", dest, UUID_T_VALUES_OR_NULL(source)); result = MU_FAILURE; } else { /*Codes_SRS_ASYNC_TYPE_HELPER_04_002: [ If source is NULL then the copy handler will set the dest to a zero UUID value. ]*/ if (source == NULL) { (void)memcpy(*dest, NIL_UUID, sizeof(UUID_T)); } else { /*Codes_SRS_ASYNC_TYPE_HELPER_04_003: [ Otherwise, the copy handler shall copy the UUID_T from source to dest. ]*/ (void)memcpy(*dest, source, sizeof(UUID_T)); } /*Codes_SRS_ASYNC_TYPE_HELPER_04_004: [ The copy handler shall succeed and return 0. ]*/ result = 0; } return result; } DEFINE_ASYNC_TYPE_HELPER_FREE_HANDLER(UUID_T, value) { /*Codes_SRS_ASYNC_TYPE_HELPER_04_005: [This handler shall do nothing.]*/ (void)value; // We do nothing since we don't malloc a UUID_T in the copy handler. } int ASYNC_TYPE_HELPER_COPY_HANDLER(const_UUID_T)(const_UUID_T* dest, const_UUID_T source) { int result; /* Codes_SRS_ASYNC_TYPE_HELPER_01_001: [ If dest is NULL then the copy handler will fail and return a non-zero value. ]*/ if (dest == NULL) { LogError("Invalid args: const_UUID_T* dest=%p, const const_UUID_T source=%" PRI_UUID_T "", dest, UUID_T_VALUES_OR_NULL(source)); result = MU_FAILURE; } else { if (source == NULL) { /* Codes_SRS_ASYNC_TYPE_HELPER_01_002: [ If source is NULL then the copy handler will set the dest to a zero UUID value. ]*/ (void)memcpy((void*)*dest, NIL_UUID, sizeof(const_UUID_T)); } else { /* Codes_SRS_ASYNC_TYPE_HELPER_01_003: [ Otherwise, the copy handler shall copy the const UUID_T from source to dest. ]*/ (void)memcpy((void*)*dest, source, sizeof(const_UUID_T)); } /* Codes_SRS_ASYNC_TYPE_HELPER_01_004: [ The copy handler shall succeed and return 0. ]*/ result = 0; } return result; } void ASYNC_TYPE_HELPER_FREE_HANDLER(const_UUID_T)(const_UUID_T value) { /* Codes_SRS_ASYNC_TYPE_HELPER_01_005: [ This handler shall do nothing. ]*/ (void)value; // We do nothing since we don't malloc a const_UUID_T in the copy handler. } DEFINE_ASYNC_TYPE_HELPER_COPY_HANDLER(const_charptr_t, dest, source) { int result; if ( /*Codes_SRS_ASYNC_TYPE_HELPER_42_006: [ If dest is NULL then the copy handler will fail and return a non-zero value. ]*/ dest == NULL ) { LogError("Invalid argument: char** dest=%p, const char* source=%p", dest, source); result = MU_FAILURE; } else if (source == NULL) { /*Codes_SRS_ASYNC_TYPE_HELPER_42_007: [ If source is NULL then the copy handler will set the dest to NULL and return 0. ]*/ *dest = NULL; result = 0; } else { /*Codes_SRS_ASYNC_TYPE_HELPER_42_008: [ The copy handler shall allocate a string large enough to hold source, including the terminating NULL. ]*/ size_t size_needed = strlen(source) + 1; *dest = malloc(size_needed); if (*dest == NULL) { /*Codes_SRS_ASYNC_TYPE_HELPER_42_010: [ If there are any failures then the copy handler shall fail and return a non-zero value. ]*/ LogError("Failed to allocate copy of string malloc(%zu)", size_needed); result = MU_FAILURE; } else { /*Codes_SRS_ASYNC_TYPE_HELPER_42_009: [ The copy handler shall copy the string from source to dest. ]*/ (void)strcpy(*dest, source); /*Codes_SRS_ASYNC_TYPE_HELPER_42_011: [ The copy handler shall succeed and return 0. ]*/ result = 0; } } return result; } DEFINE_ASYNC_TYPE_HELPER_FREE_HANDLER(const_charptr_t, value) { if (value == NULL) { /*Codes_SRS_ASYNC_TYPE_HELPER_42_012: [ If value is NULL then the free handler shall return. ]*/ LogError("Invalid arg: char* value=%p", value); } else { /*Codes_SRS_ASYNC_TYPE_HELPER_42_013: [ The free handler shall free value. ]*/ free(value); } } int constbuffer_array_ptr_copy(constbuffer_array_ptr* dest, const constbuffer_array_ptr src, uint32_t item_count) { int result; if ( /*Codes_SRS_ASYNC_TYPE_HELPER_28_001: [ If dest is NULL then the copy handler will fail and return a non-zero value. ]*/ dest == NULL || /*Codes_SRS_ASYNC_TYPE_HELPER_28_011: [ If item_count is 0, the copy handler will fail and return a non-zero value. ]*/ item_count == 0) { LogError("Invalid argument: CONSTBUFFER_ARRAY_HANDLE** dest=%p, const CONSTBUFFER_ARRAY_HANDLE* src=%p, uin32_t item_count=%" PRIu32 "", dest, src, item_count); result = MU_FAILURE; } else if (src == NULL) { /*Codes_SRS_ASYNC_TYPE_HELPER_28_002: [ If src is NULL then the copy handler will set the dest to NULL and return 0. ]*/ *dest = NULL; result = 0; } else { /*Codes_SRS_ASYNC_TYPE_HELPER_28_003: [ The copy handler shall allocate an array to store all the constbuffer_array in the src. ]*/ *dest = malloc_2(item_count, sizeof(CONSTBUFFER_ARRAY_HANDLE)); if (*dest == NULL) { /*Codes_SRS_ASYNC_TYPE_HELPER_28_004: [ If there are any failures then the copy handler shall fail and return a non-zero value. ]*/ LogError("malloc_2(item_count=%" PRIu32 ", sizeof(CONSTBUFFER_ARRAY_HANDLE)=%zu) failed", item_count, sizeof(CONSTBUFFER_ARRAY_HANDLE)); result = MU_FAILURE; } else { for (uint32_t i = 0; i < item_count; i++) { /*Codes_SRS_ASYNC_TYPE_HELPER_28_005: [ The copy handler shall call constbuffer_array_inc_ref on each constbuffer array in src. ]*/ constbuffer_array_inc_ref(src[i]); /*Codes_SRS_ASYNC_TYPE_HELPER_28_006: [ The copy handler shall copy all the constbuffer_arrays from the src to the dest. ]*/ (*dest)[i] = src[i]; } /*Codes_SRS_ASYNC_TYPE_HELPER_28_007: [ The copy handler shall succeed and return 0. ]*/ result = 0; } } return result; } void constbuffer_array_ptr_free(const constbuffer_array_ptr value, uint32_t item_count) { if ( /*Codes_SRS_ASYNC_TYPE_HELPER_28_008: [ If value is NULL then the free handler shall return. ]*/ value == NULL || /*Codes_SRS_ASYNC_TYPE_HELPER_28_012: [ If item_count is 0, the free handler shall return. ]*/ item_count == 0) { LogError("Invalid arg: CONSTBUFFER_ARRAY_HANDLE* value=%p, uin32_t item_count=%" PRIu32 "", value, item_count); } else { for (uint32_t i = 0; i < item_count; i++) { /*Codes_SRS_ASYNC_TYPE_HELPER_28_009: [ The free handler shall call constbuffer_array_dec_ref on each constbuffer array in value. ]*/ constbuffer_array_dec_ref(value[i]); } /*Codes_SRS_ASYNC_TYPE_HELPER_28_010: [ The free handler shall free value. ]*/ free(value); } }