// header files #include "ArrayDataEngine.h" /* Data Structures typedef struct StateDataStruct { char name[ STD_STR_LEN ]; int population; double growth; char majority; } StateDataType; typedef struct StateArrayStruct { StateDataType *array; int size, capacity; } StateArrayType; Data Structures */ // function implementations /* Name: clearDataStructure Process: deallocates memory for the array data structure and encapsulated state data, returns NULL to calling function Function input/parameters: pointer to state data array (StateDataArray *) Function output/parameters: none Function output/returned: NULL Device input/---: none Device output/---: none Dependencies: free */ StateArrayType *clearDataStructure( StateArrayType *arrayPtr ) { // free the array from memory free(arrayPtr->array); // free the struct from memory free(arrayPtr); // return NULL return NULL; } /* Name: copyDataList Process: copies elements from one state data array to another resets array size as needed, also resets array capacity as needed if destination array type capacity is less than capacity of source array type Function input/parameters: source state data array type (StateArrayType *) Function output/parameters: pointer to destination state data array type (StateArrayType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: privateCheckForResize, deepCopyData */ void copyDataList( StateArrayType *dest, const StateArrayType src ) { int copyIterator; privateCheckForResize(dest); // check for resize if the destination capacity is less than source if(dest->capacity == src.capacity) { dest->size = src.size; // if it is, then size the dest to what source was // copy the data from source to dest using deepCopy for(copyIterator = 0; copyIterator < src.size; copyIterator++) { deepCopyData(&dest->array[copyIterator], src.array[copyIterator]); } } // no return, void } /* Name: createDataStructure Process: dynamically creates instance of state array type along with dynamically allocating the state data array within it Function input/parameters: given initial capacity (int) Function output/parameters: none Function output/returned: pointer to state array type (StateArrayType *) Device input/---: none Device output/---: none Dependencies: malloc, sizeof (C keyword) */ StateArrayType *createDataStructure( int initialCapacity ) { StateArrayType *stateDataStructure; // initialize data structure stateDataStructure = malloc(sizeof(StateArrayType)); stateDataStructure->size = 0; stateDataStructure->capacity = initialCapacity; // initialize array for data structure stateDataStructure->array = malloc(sizeof(StateDataType) * initialCapacity); // return data structure return stateDataStructure; } /* Name: deepCopyData Process: copies all members of a StateDataType item 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 Device output/---: none Dependencies: privateCopyString */ 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 array if array is not empty, otherwise displays "Data not found - Display aborted", allows for subtitle to be added to "Display Data - " Function input/parameters: state array type (const StateArrayType), 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 StateArrayType stateData, const char *subTitle ) { int displayIterator; // check to see if the list isn't empty if(!listIsEmpty(stateData)) { // if that is true, then display: // print Display Data printf("Display Data - "); // print subtitle (and new line) printf("%s\n", subTitle); // for loop (iterates through the array data) for(displayIterator = 0; displayIterator < stateData.size; displayIterator++) { // print Name, printf("%s, ", stateData.array[displayIterator].name); // print Population, printf("%d, ", stateData.array[displayIterator].population); // print Growth, printf("%f, ", stateData.array[displayIterator].growth); // print Majority printf("%c\n", stateData.array[displayIterator].majority); // print newline (included above) } // end for loop } 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 StateArrayType), 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 StateArrayType stateData, int listIndex ) { // check stateData size against list index if(listIndex < getListSize(stateData) && listIndex >= 0) { // copy data into returnVal deepCopyData(returnVal, stateData.array[listIndex]); // return true return true; } // otherwise, // use setItemToEmpty for returnVal setItemToEmpty(returnVal); // return false return false; } /* Name: getListSize Process: provides the size of the list Function input/parameters: state array type (const StateArrayType) Function output/parameters: none Function output/returned: size of the list (int) Device input/---: none Device output/---: none Dependencies: none */ int getListSize( const StateArrayType stateData ) { // return stateData.size return stateData.size; } /* Name: insertItemAtIndex Process: checks for index in bounds, inserts item at index, returns true, resizes array as needed, if index not in bounds, returns false Function input/parameters: pointer to state array type (StateArrayType *), StateDataType item to insert (const StateDataType), index for insertion (int) Function output/parameters: updated pointer to state array type (StateArrayType *) Function output/returned: Boolean result of specified process (bool) Device input/---: none Device output/---: none Dependencies: checkForResize */ bool insertItemAtIndex( StateArrayType *stateData, StateDataType toBeInserted, int insertIndex ) { int insertIterator; // check for resize privateCheckForResize(stateData); // check to see if index is within size if(insertIndex < getListSize(*stateData) && insertIndex >= 0) { // shift elements right of index to right for(insertIterator = insertIndex; insertIterator < getListSize(*stateData); insertIterator++) { // put the element into element + 1 stateData->array[insertIterator + 1] = stateData->array[insertIterator]; } // insert element at index stateData->array[insertIndex] = toBeInserted; // return true return true; } // return false return false; } /* Name: listIsEmpty Process: returns true if list is empty, false otherwise Function input/parameters: state array type (const StateArrayType) 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 StateArrayType array ) { // check to see if size is equal to 0 if(array.size == 0) { // return true since array empty return true; } // return false if not empty return false; } /* Name: privateCheckForResize Process: checks if array needs to be resized, resizes (increases capacity of) array to double current capacity Function input/parameters: pointer to state array type (StateArrayType *) Function output/parameters: updated pointer to state array type (StateArrayType *) if resize has taken place, otherwise array type is unchanged Function output/returned: none Device input/---: none Device output/---: none Dependencies: malloc, sizeof (C keyword), deepCopyData, free */ void privateCheckForResize( StateArrayType *stateData ) { StateDataType *biggerStateArray; int resizeIterator; // do a check for size equal to capacity if(stateData->size == stateData->capacity) { // 'create' bigger array stateData->capacity = stateData->capacity * 2; // allocate the bigger array biggerStateArray = (StateDataType *)malloc(sizeof(StateDataType) * stateData->capacity); // copy the new array stuff into the old space, use loop for(resizeIterator = 0; resizeIterator < stateData->size; resizeIterator++) { // use deep copy to copy the pieces of smaller array deepCopyData(&biggerStateArray[resizeIterator], stateData->array[resizeIterator]); } // free the old array free(stateData->array); // point the stateArray to the old array stateData->array = biggerStateArray; } // no return, void } /* 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. (destStringIterator + 1) dest[characterCount + 1] = NULL_CHAR; // no return, void } /* Name: removeItemAtIndex Process: removes from array at index, shifts data down as needed, returns true if found, false otherwise Function input/parameters: pointer to state array type (StateArrayType *), index to remove (int) Function output/parameters: pointer to updated state array type (StateArrayType *), pointer to removed item (StateDataType *) Function output/returned: Boolean result of removal operation (bool) Device input/---: none Device output/---: none Dependencies: none */ bool removeItemAtIndex( StateArrayType *stateData, StateDataType *removedItem, int removeIndex ) { int removalIterator; // check to see if index is within size if(removeIndex < getListSize(*stateData) && removeIndex >= 0) { // for loop (iterate through list starting at the index) for(removalIterator = removeIndex; removalIterator < getListSize(*stateData); removalIterator++) { // shift the next element to current element. stateData->array[removalIterator] = stateData->array[removalIterator + 1]; } // return true once done return true; } // return false if item not removable? 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 }