// header files #include "LLDataEngine.h" /* Data Structures typedef struct StateDataStruct { char name[ STD_STR_LEN ]; int population; double growth; char majority; struct StateDataStruct *nextPtr; } StateDataType; typedef struct StateLLStruct { StateDataType *headPtr; } StateLLType; Data Structures */ // function implementations /* Name: clearDataStructure Process: deallocates memory for the linked list data structure and encapsulated state data using helper function, returns NULL to calling function Function input/parameters: pointer to state linked list array (StateLLType *) Function output/parameters: none Function output/returned: NULL Device input/---: none Device output/---: none Dependencies: free, clearDataStructureHelper */ StateLLType *clearDataStructure( StateLLType *llPtr ) { // call clearDataStructureHelper with headPtr privateClearDataStructureHelper(llPtr->headPtr); // free the headPtr free(llPtr); // return NULL return NULL; } /* Name: copyDataList Process: deallocates destination linked list nodes if it is not empty, then if source list is not empty, copies all nodes from source list to destination list, if source list is empty, copied list will also be configured as empty Function input/parameters: pointer to source state data linked list type (const StateDataType *) Function output/parameters: pointer to destination state data array type (StateLLType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: clearDataStructureHelper, privateCreateNodeFromNode */ void copyDataList( StateLLType *dest, const StateLLType *src ) { // no return, void } /* Name: createDataStructure Process: dynamically creates instance of state linked list type along with initializing the linked list within Function input/parameters: none Function output/parameters: none Function output/returned: pointer to state linked list type (StateLLType *) Device input/---: none Device output/---: none Dependencies: malloc, sizeof (C keyword) */ StateLLType *createDataStructure() { // allocate and create StateLLType using malloc and size of StateLLType *dataStruct; dataStruct = malloc(sizeof(StateLLType)); // set the head pointer to null dataStruct->headPtr = NULL; // return StateLLType return dataStruct; } /* Name: deepCopyData Process: copies all members of a StateDataType node into another one Function input/parameters: state data type item (const StateDataType *) Function output/parameters: pointer to state data item (StateDataType *) Function output/returned: none Device input/---: none Dependencies: privateCopyString Device output/---: none */ void deepCopyData( StateDataType *dest, const StateDataType *src ) { // *dest.population = src.population (for each piece) dest->population = src->population; dest->growth = src->growth; dest->majority = src->majority; // privateCopyString for the string // privateCopyString(*dest.name, src.name) privateCopyString(dest->name, src->name); // no return, void } /* Name: displayData Process: displays comma-delimited data items in linked list if linked list is not empty, otherwise displays "Data not found - Display aborted", allows for subtitle to be added to "Display Data - " Function input/parameters: state linked list type (const StateLLType), subtitle (const char *) Function output/parameters: none Function output/returned: none Device input/---: none Device output/monitor: data displayed as specified Dependencies: printf, listIsEmpty */ void displayData( const StateLLType stateData, const char *subTitle ) { // create a working pointer StateDataType *currentPtr = stateData.headPtr; // check to see if the list is not empty if(!listIsEmpty(stateData)) { printf("Display Data - "); printf("%s\n", subTitle); // while through the linked list // get the data out of the first node printf("%s, ", currentPtr->name); printf("%d, ", currentPtr->population); printf("%f, ", currentPtr->growth); printf("%c\n", currentPtr->majority); while(currentPtr != NULL) { // move the pointer currentPtr = currentPtr->nextPtr; // get the data out of the current node printf("%s, ", currentPtr->name); printf("%d, ", currentPtr->population); printf("%f, ", currentPtr->growth); printf("%c\n", currentPtr->majority); } } else { // otherwise, display: // print Data Not Found printf("Data not found - Display aborted\n"); } // no return, void } /* Name: getItemAtIndex Process: checks for index within bounds, acquires and returns the value as a parameter, and returns true, otherwise sets data in parameter to empty and returns false Function input/parameters: state array type (const StateLLType), list index (int) Function output/parameters: value if found, otherwise, value set to empty (StateDataType *) Function output/returned: Boolean result of operation (bool) Device input/---: none Device output/---: none Dependencies: deepCopyData, setItemToEmpty */ bool getItemAtIndex( StateDataType *returnVal, const StateLLType stateData, int listIndex ) { int llIncrementer = 0; StateDataType *currentPtr = stateData.headPtr; // while through linked list while(!listIsEmpty(stateData) && currentPtr != NULL) { // look for listIndex if(listIndex == llIncrementer) { // if found, return true, copy data into return deepCopyData(returnVal, currentPtr); return true; } llIncrementer = llIncrementer + 1; } // since not found, return empty value in returnVal. setItemToEmpty(returnVal); // return false since not found, or not within bounds. return false; } /* Name: getListSize Process: calculates the linked list size Function input/parameters: state array type (const StateLLType) Function output/parameters: none Function output/returned: size of the list (int) Device input/---: none Device output/---: none Dependencies: none */ int getListSize( const StateLLType stateData ) { int listCounter = 0; StateDataType *currentPtr = stateData.headPtr; // check to see if the headPtr // while through the linked list. count up if next not null. while(currentPtr != NULL) { // listCounter increment listCounter = listCounter + 1; // move the pointer currentPtr = currentPtr->nextPtr; } // return listCounter return listCounter; } /* Name: insertItemAtIndex Process: checks for index in bounds, inserts item at index, returns true, if index not in bounds, returns false, must also insert item at index = size to all for appending data Function input/parameters: pointer to state array type (StateLLType *), StateDataType item to insert (const StateDataType), index for insertion (int) Function output/parameters: updated pointer to state array type (StateLLType *) Function output/returned: Boolean result of specified process (bool) Device input/---: none Device output/---: none Dependencies: privateCreateNodeFromNode */ bool insertItemAtIndex( StateLLType *stateData, StateDataType toBeInserted, int insertIndex ) { int llIncrementer = 0; StateDataType *currentPtr = stateData->headPtr; StateDataType *insertedNode; // while through linked list while(!listIsEmpty(*stateData) && currentPtr != NULL) { // checks within middle of list if(insertIndex == llIncrementer) { // if found, return true, insert data // create node given toBeInserted insertedNode = privateCreateNodeFromNode(toBeInserted); // move the node's nextPtr to currentPtr->nextPtr currentPtr->nextPtr = insertedNode->nextPtr; // move the currentPtr's nextPtr to the node currentPtr = insertedNode; return true; } llIncrementer = llIncrementer + 1; } // need a check for beginning of list if(insertIndex == 0) { if(stateData->headPtr == NULL) { // if at beginning of list, but no more data // create node given toBeInserted insertedNode = privateCreateNodeFromNode(toBeInserted); // move the headPtr to node stateData->headPtr = insertedNode; return true; } // if at beginning of list, if more data in list // create node given toBeInserted insertedNode = privateCreateNodeFromNode(toBeInserted); // need to point the headPtr->nextPtr to the node's nextPtr stateData->headPtr->nextPtr = insertedNode->nextPtr; // move the headPtr to node stateData->headPtr = insertedNode; return true; } // put the end of list check out here? if(insertIndex == getListSize(*stateData)) { // if found, return true, append data // create node given toBeInserted insertedNode = privateCreateNodeFromNode(toBeInserted); // move the node's nextPtr to NULL insertedNode->nextPtr = NULL; // move the currentPtr's nextPtr to the node currentPtr = insertedNode; return true; } // return false since not inserted, or not within bounds. return false; } /* Name: listIsEmpty Process: returns true if list is empty, false otherwise Function input/parameters: state linked list type (const StateLLType) Function output/parameters: none Function output/returned: Boolean result of test as specified (bool) Device input/---: none Device output/---: none Dependencies: none */ bool listIsEmpty( const StateLLType array ) { // return the check of headPtr == null return array.headPtr == NULL; } /* Name: privateClearDataStructureHelper Process: recursively iterates through linked list, removing nodes from bottom to top Function input/parameters: pointer to state data linked list (StateDataType *) Function output/parameters: none Function output/returned: NULL Device input/---: none Device output/---: none Dependencies: free, clearDataStructureHelper (recursively) */ StateDataType *privateClearDataStructureHelper( StateDataType *nodePtr ) { // check if node's nextPtr not null if(nodePtr->nextPtr != NULL) { // if it is not null, call the next recursion. nodePtr->nextPtr = privateClearDataStructureHelper(nodePtr->nextPtr); } // free the node using free free(nodePtr); // return NULL return NULL; } /* Name: privateCreateNodeFromData Process: creates linked list node provided member data Function input/parameters: name (const char *), population (int), growth (double), majority (char) Function output/parameters: none Function output/returned: pointer to created node (StateDataType *) Device input/---: none Device output/---: none Dependencies: malloc, privateCopyString, keyword sizeof */ StateDataType *privateCreateNodeFromData( const char *inName, int inPop, double inGrowth, char inMajority ) { // allocate node memory using malloc and size of StateDataType *workingNode; workingNode = malloc(sizeof(StateDataType)); // copy string into node privateCopyString(workingNode->name, inName); // copy other data pieces into node workingNode->population = inPop; workingNode->growth = inGrowth; workingNode->majority = inMajority; // set nextPtr to null workingNode->nextPtr = NULL; // return node return workingNode; } /* Name: privateCreateNodeFromNode Process: creates linked list node provided another node Function input/parameters: other node (const StateDataType) Function output/parameters: none Function output/returned: pointer to created node (StateDataType *) Device input/---: none Device output/---: none Dependencies: one line of code - privateCreateNodeFromData */ StateDataType *privateCreateNodeFromNode( const StateDataType source ) { // return the node return privateCreateNodeFromData(source.name, source.population, source.growth, source.majority); } /* Name: privateCopyString Process: copies string character for character up to NULL_CHAR of source string Function input/parameters: source string to be copied (const char *) Function output/parameters: destination string (char *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: none */ void privateCopyString( char *dest, const char *src ) { int characterCount = 0; // use a while loop, check for !NULL_CHAR while(src[characterCount] != NULL_CHAR) { // copy the character accessed into dest string dest[characterCount] = src[characterCount]; // iterate the number of characters characterCount = characterCount + 1; } // add a NULL_CHAR once done, characterCount is in the right place for \0 dest[characterCount] = NULL_CHAR; // no return, void } /* Name: removeItemAtIndex Process: removes node from linked list at index, returns true if found, false otherwise Function input/parameters: pointer to state linked list type (StateLLType *), index to remove (int) Function output/parameters: pointer to updated state linked list type (StateLLType *), pointer to removed item (StateDataType *) Function output/returned: Boolean result of removal operation (bool) Device input/---: none Device output/---: none Dependencies: deepCopyData, free, setItemToEmpty */ bool removeItemAtIndex( StateLLType *stateData, StateDataType *removedItem, int removeIndex ) { int llIncrementer = 0; StateDataType *currentPtr = stateData->headPtr; // while through linked list while(!listIsEmpty(*stateData) && currentPtr != NULL) { // checks within middle of list if(removeIndex == llIncrementer) { // if found, return true, insert data // copy data out of the list deepCopyData(removedItem, currentPtr); // move the pointer of currentPtr to the next item currentPtr->nextPtr = currentPtr->nextPtr->nextPtr; // free the memory of the removed item. free(currentPtr->nextPtr); return true; } llIncrementer = llIncrementer + 1; } // need a check for beginning of list if(removeIndex == 0) { if(stateData->headPtr == NULL) { // if at beginning of list, but no more data // copy data out of the list deepCopyData(removedItem, currentPtr); // free the memory of the removed item. free(currentPtr->nextPtr); return true; } // if at beginning of list, if more data in list // copy data out of the list deepCopyData(removedItem, currentPtr); // move the pointer of currentPtr to the next item currentPtr->nextPtr = currentPtr->nextPtr->nextPtr; // free the memory of the removed item. free(currentPtr->nextPtr); return true; } // put the end of list check out here? if(removeIndex == getListSize(*stateData)) { // if found, return true, append data // copy data out of the list deepCopyData(removedItem, currentPtr); // move the pointer of currentPtr to the next item currentPtr->nextPtr = currentPtr->nextPtr->nextPtr; // free the memory of the removed item. free(currentPtr->nextPtr); return true; } setItemToEmpty(removedItem); // return false since not inserted, or not within bounds. return false; } /* Name: setItemToEmpty Process: sets state data type struct to empty or default values, including empty string and majority 'x' Function input/parameters: pointer to state data value (StateDataType *) Function output/parameters: pointer to updated state data value (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: none */ void setItemToEmpty( StateDataType *data ) { // set the data's name to "" data->name[0] = NULL_CHAR; // set the data's population and growth to 0 data->population = 0; data->growth = 0.0; // set the data's majority to 'x' data->majority = 'x'; // no return, void }