MESSAGE_HANDLE Message_Create(const MESSAGE_CONFIG * cfg) { MESSAGE_HANDLE_DATA* result; /*Codes_SRS_MESSAGE_02_002: [If cfg is NULL then Message_Create shall return NULL.]*/ if (cfg == NULL) { result = NULL; LogError("invalid parameter (NULL)."); } /*Codes_SRS_MESSAGE_02_003: [If field source of cfg is NULL and size is not zero, then Message_Create shall fail and return NULL.] */ else if ((cfg->size > 0) && (cfg->source == NULL)) { result = NULL; LogError("invalid parameter combination cfg->size=%zd, cfg->source=%p", cfg->size, cfg->source); } else { /*Codes_SRS_MESSAGE_02_006: [Otherwise, Message_Create shall return a non-NULL handle and shall set the internal ref count to "1".]*/ result = REFCOUNT_TYPE_CREATE(MESSAGE_HANDLE_DATA); if (result == NULL) { LogError("malloc returned NULL"); /*return as is*/ } else { /*Codes_SRS_MESSAGE_02_004: [Mesages shall be allowed to be created from zero-size content.]*/ /*Codes_SRS_MESSAGE_02_015: [The MESSAGE_CONTENT's field size shall have the same value as the cfg's field size.]*/ /*Codes_SRS_MESSAGE_17_003: [Message_Create shall copy the source to a readonly CONSTBUFFER.]*/ result->content = CONSTBUFFER_Create(cfg->source, cfg->size); if (result->content == NULL) { LogError("CONSBUFFER Create failed"); free(result); result = NULL; } else { /*Codes_SRS_MESSAGE_02_019: [Message_Create shall clone the sourceProperties to a readonly CONSTMAP.]*/ result->properties = ConstMap_Create(cfg->sourceProperties); if (result->properties == NULL) { /*Codes_SRS_MESSAGE_02_005: [If Message_Create encounters an error while building the internal structures of the message, then it shall return NULL.] */ LogError("ConstMap_Create failed"); CONSTBUFFER_Destroy(result->content); free(result); result = NULL; } else { /*all is fine, return as is.*/ } } } } return (MESSAGE_HANDLE)result; }
void Message_Destroy(MESSAGE_HANDLE message) { /*Codes_SRS_MESSAGE_02_017: [If message is NULL then Message_Destroy shall do nothing.] */ if (message == NULL) { LogError("invalid arg: message is NULL"); } else { MESSAGE_HANDLE_DATA* messageData = (MESSAGE_HANDLE_DATA*)message; /*Codes_SRS_MESSAGE_17_002: [Message_Destroy shall destroy the CONSTMAP properties.]*/ ConstMap_Destroy(messageData->properties); /*Codes_SRS_MESSAGE_17_005: [Message_Destroy shall destroy the CONSTBUFFER.]*/ CONSTBUFFER_Destroy(messageData->content); /*Codes_SRS_MESSAGE_02_020: [Otherwise, Message_Destroy shall decrement the internal ref count of the message.]*/ if (DEC_REF(MESSAGE_HANDLE_DATA, message) == DEC_RETURN_ZERO) { /*Codes_SRS_MESSAGE_02_021: [If the ref count is zero then the allocated resources are freed.]*/ free(message); } } }
static void publish_with_new_properties(MAP_HANDLE newProperties, MESSAGE_HANDLE messageHandle, IDENTITY_MAP_DATA * idModule) { /*Codes_SRS_IDMAP_17_034: [IdentityMap_Receive shall clone message content.] */ CONSTBUFFER_HANDLE content = Message_GetContentHandle(messageHandle); if (content == NULL) { /*Codes_SRS_IDMAP_17_035: [If cloning message content fails, IdentityMap_Receive shall deallocate all resources and return.]*/ LogError("Could not extract message content"); } else { MESSAGE_BUFFER_CONFIG newMessageConfig = { content, newProperties }; /*Codes_SRS_IDMAP_17_036: [IdentityMap_Receive shall create a new message by calling Message_CreateFromBuffer with new map and cloned content.]*/ MESSAGE_HANDLE newMessage = Message_CreateFromBuffer(&newMessageConfig); if (newMessage == NULL) { /*Codes_SRS_IDMAP_17_037: [If creating new message fails, IdentityMap_Receive shall deallocate all resources and return.]*/ LogError("Could not create new message to publish"); } else { MESSAGE_BUS_RESULT busStatus; /*Codes_SRS_IDMAP_17_038: [IdentityMap_Receive shall call MessageBus_Publish with busHandle and new message.]*/ busStatus = MessageBus_Publish(idModule->busHandle, newMessage); if (busStatus != MESSAGE_BUS_OK) { LogError("Message bus publish failure: %s", ENUM_TO_STRING(MESSAGE_BUS_RESULT, busStatus)); } Message_Destroy(newMessage); } /*Codes_SRS_IDMAP_17_039: [IdentityMap_Receive will destroy all resources it created.]*/ CONSTBUFFER_Destroy(content); } }
void constbuffer_array_dec_ref(CONSTBUFFER_ARRAY_HANDLE constbuffer_array_handle) { if (constbuffer_array_handle == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_039: [ If constbuffer_array_handle is NULL then constbuffer_array_dec_ref shall return. ]*/ LogError("invalid argument CONSTBUFFER_ARRAY_HANDLE constbuffer_array_handle=%p", constbuffer_array_handle); } else { /* Codes_SRS_CONSTBUFFER_ARRAY_01_016: [ Otherwise `constbuffer_array_dec_ref` shall decrement the reference count for `constbuffer_array_handle`. ]*/ if (DEC_REF(CONSTBUFFER_ARRAY_HANDLE_DATA, constbuffer_array_handle) == DEC_RETURN_ZERO) { uint32_t i; /*Codes_SRS_CONSTBUFFER_ARRAY_02_038: [ If the reference count reaches 0, `constbuffer_array_dec_ref` shall free all used resources. ]*/ for (i = 0; i < constbuffer_array_handle->nBuffers; i++) { CONSTBUFFER_Destroy(constbuffer_array_handle->buffers[i]); } REFCOUNT_TYPE_DESTROY(CONSTBUFFER_ARRAY_HANDLE_DATA, constbuffer_array_handle); } } }
CONSTBUFFER_ARRAY_HANDLE constbuffer_array_create(const CONSTBUFFER_HANDLE* buffers, uint32_t buffer_count) { CONSTBUFFER_ARRAY_HANDLE result; if ( /* Codes_SRS_CONSTBUFFER_ARRAY_01_012: [ If `buffers` is NULL and `buffer_count` is not 0, `constbuffer_array_create` shall fail and return NULL. ]*/ (buffers == NULL) && (buffer_count != 0) ) { LogError("Invalid arguments: const CONSTBUFFER_HANDLE* buffers=%p, uint32_t buffer_count=%" PRIu32, buffers, buffer_count); } else { /* Codes_SRS_CONSTBUFFER_ARRAY_01_009: [ `constbuffer_array_create` shall allocate memory for a new `CONSTBUFFER_ARRAY_HANDLE` that can hold `buffer_count` buffers. ]*/ result = REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(CONSTBUFFER_ARRAY_HANDLE_DATA, buffer_count * sizeof(CONSTBUFFER_HANDLE)); if (result == NULL) { /* Codes_SRS_CONSTBUFFER_ARRAY_01_014: [ If any error occurs, `constbuffer_array_create` shall fail and return NULL. ]*/ LogError("failure in allocating const buffer array"); } else { uint32_t i; for (i = 0; i < buffer_count; i++) { /* Codes_SRS_CONSTBUFFER_ARRAY_01_010: [ `constbuffer_array_create` shall clone the buffers in `buffers` and store them. ]*/ result->buffers[i] = CONSTBUFFER_Clone(buffers[i]); if (result->buffers[i] == NULL) { /* Codes_SRS_CONSTBUFFER_ARRAY_01_014: [ If any error occurs, `constbuffer_array_create` shall fail and return NULL. ]*/ LogError("Failed cloning buffer at index %" PRIu32, i); break; } } if (i < buffer_count) { uint32_t j; LogError("Failed creating const buffer array"); for (j = 0; j < i; j++) { CONSTBUFFER_Destroy(result->buffers[j]); } } else { result->nBuffers = buffer_count; /* Codes_SRS_CONSTBUFFER_ARRAY_01_011: [ On success `constbuffer_array_create` shall return a non-NULL handle. ]*/ goto all_ok; } REFCOUNT_TYPE_DESTROY(CONSTBUFFER_ARRAY_HANDLE_DATA, result); } } result = NULL; all_ok: return result; }
CONSTBUFFER_ARRAY_HANDLE constbuffer_array_remove_front(CONSTBUFFER_ARRAY_HANDLE constbuffer_array_handle, CONSTBUFFER_HANDLE* constbuffer_handle) { CONSTBUFFER_ARRAY_HANDLE result; if ( /*Codes_SRS_CONSTBUFFER_ARRAY_02_012: [ If constbuffer_array_handle is NULL then constbuffer_array_remove_front shall fail and return NULL. ]*/ (constbuffer_array_handle == NULL) || /*Codes_SRS_CONSTBUFFER_ARRAY_02_045: [ If constbuffer_handle is NULL then constbuffer_array_remove_front shall fail and return NULL. ]*/ (constbuffer_handle == NULL) ) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_036: [ If there are any failures then constbuffer_array_remove_front shall fail and return NULL. ]*/ LogError("invalid arguments CONSTBUFFER_ARRAY_HANDLE constbuffer_array_handle=%p, CONSTBUFFER_HANDLE* constbuffer_handle=%p", constbuffer_array_handle, constbuffer_handle); } else { /*Codes_SRS_CONSTBUFFER_ARRAY_02_002: [ constbuffer_array_remove_front shall fail when called on a newly constructed CONSTBUFFER_ARRAY_HANDLE. ]*/ /*Codes_SRS_CONSTBUFFER_ARRAY_02_013: [ If there is no front CONSTBUFFER_HANDLE then constbuffer_array_remove_front shall fail and return NULL. ]*/ if (constbuffer_array_handle->nBuffers == 0) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_036: [ If there are any failures then constbuffer_array_remove_front shall fail and return NULL. ]*/ LogError("cannot remove from that which does not have"); } else { /*Codes_SRS_CONSTBUFFER_ARRAY_02_046: [ constbuffer_array_remove_front shall allocate memory to hold all of constbuffer_array_handle CONSTBUFFER_HANDLEs except the front one. ]*/ result = REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(CONSTBUFFER_ARRAY_HANDLE_DATA, (constbuffer_array_handle->nBuffers - 1) * sizeof(CONSTBUFFER_HANDLE)); if (result == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_036: [ If there are any failures then constbuffer_array_remove_front shall fail and return NULL. ]*/ LogError("failure in malloc"); /*return as is*/ } else { /* Codes_SRS_CONSTBUFFER_ARRAY_01_001: [ `constbuffer_array_remove_front` shall inc_ref the removed buffer. ]*/ CONSTBUFFER_HANDLE clonedFrontBuffer = CONSTBUFFER_Clone(constbuffer_array_handle->buffers[0]); if (clonedFrontBuffer == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_036: [ If there are any failures then constbuffer_array_remove_front shall fail and return NULL. ]*/ LogError("failure in CONSTBUFFER_Clone"); } else { uint32_t i; result->nBuffers = constbuffer_array_handle->nBuffers - 1; /*Codes_SRS_CONSTBUFFER_ARRAY_02_047: [ constbuffer_array_remove_front shall copy all of constbuffer_array_handle CONSTBUFFER_HANDLEs except the front one. ]*/ /*Codes_SRS_CONSTBUFFER_ARRAY_02_048: [ constbuffer_array_remove_front shall inc_ref all the copied CONSTBUFFER_HANDLEs. ]*/ for (i = 1; i < constbuffer_array_handle->nBuffers; i++) { if ((result->buffers[i - 1] = CONSTBUFFER_Clone(constbuffer_array_handle->buffers[i])) == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_036: [ If there are any failures then constbuffer_array_remove_front shall fail and return NULL. ]*/ LogError("failure in CONSTBUFFER_Clone"); break; } } if (i != constbuffer_array_handle->nBuffers) { uint32_t j; for (j = 1; j < i; j++) { CONSTBUFFER_Destroy(result->buffers[j - 1]); } } else { /*Codes_SRS_CONSTBUFFER_ARRAY_02_049: [ constbuffer_array_remove_front shall succeed, write in constbuffer_handle the front handle and return a non-NULL value. ]*/ *constbuffer_handle = clonedFrontBuffer; goto allOk; } CONSTBUFFER_Destroy(clonedFrontBuffer); } REFCOUNT_TYPE_DESTROY(CONSTBUFFER_ARRAY_HANDLE_DATA, result); } } } /*Codes_SRS_CONSTBUFFER_ARRAY_02_036: [ If there are any failures then constbuffer_array_remove_front shall fail and return NULL. ]*/ result = NULL; allOk:; return result; }
CONSTBUFFER_ARRAY_HANDLE constbuffer_array_add_front(CONSTBUFFER_ARRAY_HANDLE constbuffer_array_handle, CONSTBUFFER_HANDLE constbuffer_handle) { CONSTBUFFER_ARRAY_HANDLE result; if ( /*Codes_SRS_CONSTBUFFER_ARRAY_02_006: [ If constbuffer_array_handle is NULL then constbuffer_array_add_front shall fail and return NULL ]*/ (constbuffer_array_handle == NULL) || /*Codes_SRS_CONSTBUFFER_ARRAY_02_007: [ If constbuffer_handle is NULL then constbuffer_array_add_front shall fail and return NULL ]*/ (constbuffer_handle == NULL) ) { LogError("invalid arguments CONSTBUFFER_ARRAY_HANDLE constbuffer_array_handle=%p, CONSTBUFFER_HANDLE constbuffer_handle=%p", constbuffer_array_handle, constbuffer_handle); } else { /*Codes_SRS_CONSTBUFFER_ARRAY_02_042: [ constbuffer_array_add_front shall allocate enough memory to hold all of constbuffer_array_handle existing CONSTBUFFER_HANDLE and constbuffer_handle. ]*/ result = REFCOUNT_TYPE_CREATE_WITH_EXTRA_SIZE(CONSTBUFFER_ARRAY_HANDLE_DATA, (constbuffer_array_handle->nBuffers + 1) * sizeof(CONSTBUFFER_HANDLE)); if (result == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_011: [ If there any failures constbuffer_array_add_front shall fail and return NULL. ]*/ LogError("failure in malloc"); /*return as is*/ } else { /*Codes_SRS_CONSTBUFFER_ARRAY_02_043: [ constbuffer_array_add_front shall copy constbuffer_handle and all of constbuffer_array_handle existing CONSTBUFFER_HANDLE. ]*/ /*Codes_SRS_CONSTBUFFER_ARRAY_02_044: [ constbuffer_array_add_front shall inc_ref all the CONSTBUFFER_HANDLE it had copied. ]*/ result->nBuffers = constbuffer_array_handle->nBuffers + 1; if ((result->buffers[0] = CONSTBUFFER_Clone(constbuffer_handle)) == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_011: [ If there any failures constbuffer_array_add_front shall fail and return NULL. ]*/ LogError("failure in CONSTBUFFER_Clone"); } else { uint32_t i; for (i = 1; i < result->nBuffers; i++) { result->buffers[i] = CONSTBUFFER_Clone(constbuffer_array_handle->buffers[i - 1]); if (result->buffers[i] == NULL) { /*Codes_SRS_CONSTBUFFER_ARRAY_02_011: [ If there any failures constbuffer_array_add_front shall fail and return NULL. ]*/ LogError("failure in CONSTBUFFER_Clone"); break; } } if (i != result->nBuffers) { uint32_t j; for (j = 1; j < i; j++) { CONSTBUFFER_Destroy(result->buffers[j]); } } else { /*Codes_SRS_CONSTBUFFER_ARRAY_02_010: [ constbuffer_array_add_front shall succeed and return a non-NULL value. ]*/ goto allOk; } CONSTBUFFER_Destroy(result->buffers[0]); } REFCOUNT_TYPE_DESTROY(CONSTBUFFER_ARRAY_HANDLE_DATA, result); } } /*Codes_SRS_CONSTBUFFER_ARRAY_02_011: [ If there any failures constbuffer_array_add_front shall fail and return NULL. ]*/ result = NULL; allOk:; return result; }
MESSAGE_HANDLE Message_CreateFromBuffer(const MESSAGE_BUFFER_CONFIG* cfg) { MESSAGE_HANDLE_DATA* result; /*Codes_SRS_MESSAGE_17_008: [ If cfg is NULL then Message_CreateFromBuffer shall return NULL.] */ if (cfg == NULL) { result = NULL; LogError("invalid parameter (NULL)."); } /* Codes_SRS_MESSAGE_17_009: [If field sourceContent of cfg is NULL, then Message_CreateFromBuffer shall fail and return NULL.]*/ else if (cfg->sourceContent == NULL) { result = NULL; LogError("invalid CONSTBUFFER (NULL)"); } /*Codes_SRS_MESSAGE_17_010: [If field sourceProperties of cfg is NULL, then Message_CreateFromBuffer shall fail and return NULL.]*/ else if (cfg->sourceProperties == NULL) { result = NULL; LogError("invalid properties (NULL)"); } else { /*Codes_SRS_MESSAGE_17_011: [If Message_CreateFromBuffer encounters an error while building the internal structures of the message, then it shall return NULL.]*/ /*Codes_SRS_MESSAGE_17_014: [On success, Message_CreateFromBuffer shall return a non-NULL handle and set the internal ref count to "1".]*/ result = REFCOUNT_TYPE_CREATE(MESSAGE_HANDLE_DATA); if (result == NULL) { LogError("malloc returned NULL"); /*return as is*/ } else { /*Codes_SRS_MESSAGE_17_013: [Message_CreateFromBuffer shall clone the CONSTBUFFER sourceBuffer.]*/ result->content = CONSTBUFFER_Clone(cfg->sourceContent); if (result->content == NULL) { LogError("CONSBUFFER Clone failed"); free(result); result = NULL; } else { /*Codes_SRS_MESSAGE_17_012: [Message_CreateFromBuffer shall copy the sourceProperties to a readonly CONSTMAP.]*/ result->properties = ConstMap_Create(cfg->sourceProperties); if (result->properties == NULL) { LogError("ConstMap_Create failed"); CONSTBUFFER_Destroy(result->content); free(result); result = NULL; } else { /*all is fine, return as is.*/ } } } } return (MESSAGE_HANDLE)result; }