/** * Send an event to controller thread on reception of any message. * data - Pointer to received message, should be copied for future usage. * sendorId - Pointer to user/device ID, should be copied for future usage. * datasize - Received message size. */ static bool PostControllerEventReceivedMessage(const FlowQueue* receiveMsgQueue, const char *data, const char *sendorId, const unsigned int datasize) { bool success = false; ControllerEvent *event = NULL; ReceivedMessage *receivedMsg = NULL; event = (ControllerEvent *)Flow_MemAlloc(sizeof(ControllerEvent)); if (event) { event->evtType = ControllerEvent_ReceivedMessage; receivedMsg = (ReceivedMessage *)Flow_MemAlloc(sizeof(ReceivedMessage)); if (receivedMsg) { //Allocate one extra byte for data, as the datasize we got from //FlowMessagingMessage_GetContentLength() doesn't include null terminator receivedMsg->data = (char *)Flow_MemAlloc(datasize + 1); receivedMsg->sendorId = (char *)Flow_MemAlloc(strlen(sendorId) + 1); if (receivedMsg->data && receivedMsg->sendorId) { strncpy(receivedMsg->data, data, datasize); receivedMsg->data[datasize] = '\0'; strcpy(receivedMsg->sendorId, sendorId); event->details = receivedMsg; success = FlowQueue_Enqueue(*receiveMsgQueue, event); } if (!success) { if (receivedMsg->data) { Flow_MemFree((void **)&receivedMsg->data); } if (receivedMsg->sendorId) { Flow_MemFree((void **)&receivedMsg->sendorId); } Flow_MemFree((void **)&receivedMsg); } } if (!success) { Flow_MemFree((void **)&event); } } return success; }
/** * Send an event to controller thread for success/failure of reading KVS config * data - Device setting read from datastore. * In case of any failure, user should free any memory allocated to it. * Otherwise, would be freed by receiver if successfully added to queue. */ static bool PostControllerEventSetting(const FlowQueue* receiveMsgQueue, char *data) { bool success = false; ControllerEvent *event = NULL; //Allocated memory should be freed by the receiver event = (ControllerEvent *)Flow_MemAlloc(sizeof(ControllerEvent)); if (event) { if (data) { event->evtType = ControllerEvent_SettingSuccess; } else { event->evtType = ControllerEvent_SettingFailure; } event->details = data; success = FlowQueue_Enqueue(*receiveMsgQueue, event); if (!success) { Flow_MemFree((void **)&event); } } return success; }
TreeNode TreeNode_Create(void) { _treeNode node = (_treeNode) Flow_MemAlloc(sizeof(TreeNodeImpl)); if (node) { memset(node, 0 , sizeof(TreeNodeImpl)); node->ChildSlots = INITIAL_TREENODE_CHILD_SLOTS; node->Children = (struct TreeNodeImpl**) Flow_MemAlloc(sizeof(struct TreeNodeImpl*)*node->ChildSlots); if (node->Children) { memset(node->Children, 0, sizeof(TreeNodeImpl*) * node->ChildSlots); } else { node->ChildSlots = 0; node->Children = NULL; } } return node; }
static char *FlowString_DuplicateWithLength(const char *text, int textLength) { char *result = NULL; if (text) { result = (char*)Flow_MemAlloc(textLength+1); if (result) { memcpy(result, text, textLength); result[textLength] = '\0'; } } return result; }
bool TreeNode_AddChild(TreeNode node, TreeNode child) { bool result = false; _treeNode _node = (_treeNode) node; if (_node && child) { // Check whether we need to resize the children list to add a new child if (_node->ChildSlots <= _node->ChildCount) { TreeNodeImpl **oldChildrenList = (TreeNodeImpl**) _node->Children; // Double list capacity uint32_t newChildrenListSize = sizeof(TreeNode) * (_node->ChildSlots * 2); _node->Children = (struct TreeNodeImpl**) Flow_MemAlloc(newChildrenListSize); if (_node->Children) { _node->ChildSlots = (_node->ChildSlots * 2); memset(_node->Children, 0, newChildrenListSize); memcpy(_node->Children, oldChildrenList, _node->ChildCount * sizeof(TreeNode)); Flow_MemFree((void **) &oldChildrenList); } else { _node->Children = (struct TreeNodeImpl**) oldChildrenList; goto error; } } // Add the new child to the list _node->Children[_node->ChildCount] = child; _node->ChildCount++; ((_treeNode)child)->ChildID = _node->ChildCount; // Make sure the Parent pointer is set so that // Tree_Delete will also free the root node. ((_treeNode)child)->Parent = (struct TreeNodeImpl *)_node; result = true; } error: return result; }
bool TreeNode_SetValue(const TreeNode node, const uint8_t* value, const uint32_t length) { bool result = false; _treeNode _node = (_treeNode) node; if (_node && value) { if (_node->Value) Flow_MemFree((void **) &_node->Value); _node->Value = Flow_MemAlloc(sizeof(uint8_t) * (length+1)); if (_node->Value) { if (length > 0) memcpy(_node->Value, value, length); _node->Value[length] = '\0'; result = true; } } return result; }
bool TreeNode_SetName(const TreeNode node, const char* name, const uint32_t length) { bool result = false; _treeNode _node = (_treeNode) node; if (_node && name) { if (_node->Name) Flow_MemFree((void **) &_node->Name); _node->Name = Flow_MemAlloc(sizeof(char) * (length+1)); if (_node->Name) { if (length > 0) memcpy(_node->Name, name, length); _node->Name[length] = '\0'; result = true; } } return result; }
TreeNode TreeNode_Navigate(const TreeNode rootNode, const char* path) { _treeNode currentNode = rootNode; _treeNode _node = (_treeNode) rootNode; // Validate inputs (Check rootNode & path are not null) // Assuming path is null-terminated if (rootNode && path) { char* _path = (char*) Flow_MemAlloc(sizeof(char) * (strlen((const char*) path)+1) ); if (_path) { // Design note: Need to make a copy of path ('_path') as Microchip's implementation // of strtok() appears to try to modify the string it's working on memset((void*)_path, 0, (sizeof(char) * (strlen((const char*) path)+1) )); memcpy((void*) _path, (void*) path, sizeof(char) * strlen((const char*) path) ); // Check for path separator '/' character if (strchr((const char*) _path, '/') == NULL) { if (strcmp((const char*) _node->Name, (const char*) _path) != 0) currentNode = NULL; } else { // Tokenise path and ensure first pathElement matches char *pathElement = strtok((char*) _path, (const char*) "/"); if (pathElement) { if (strcmp((const char*) currentNode->Name, (const char*) pathElement) == 0) { bool childFound = false; bool pathError = false; do { // Then, get next path-token and find a match for a child node's name pathElement = strtok(0, "/"); if (pathElement) { childFound = false; uint32_t childIndex = 0; for (childIndex = 0; childIndex < currentNode->ChildCount; childIndex++) { // For each token, check if a child's node name matches the next token in the path _treeNode thisChild = (_treeNode) currentNode->Children[childIndex]; if (strcmp((const char*) thisChild->Name, pathElement) == 0) { currentNode = thisChild; childFound = true; break; } } if (!childFound) { currentNode = NULL; pathError = true; } } } while(pathElement && !pathError); if (pathError) currentNode = NULL; } } } Flow_MemFree((void **) &_path); } else { } } return (TreeNode) currentNode; }