diff --git a/BuildDataBase.c b/BuildDataBase.c index 75128b80412f9692271817d672f01aefe03dc3da..afb9222e42f48d2900707bbe37e5ed58d49e35a6 100644 --- a/BuildDataBase.c +++ b/BuildDataBase.c @@ -44,10 +44,11 @@ typedef struct { double* hotttnesss; } songs_struct; // Songs struct. -int test_file_bool = 1; // Check if using smaller test csv or not. +int test_file_bool = 0; // Check if using smaller test csv or not. int songs_array_max = ARRAY_SIZE; // Saves current size of songs array. int song_index = 0; // Current song index. songs_struct** songs_array; // The array which holds all song pointers. +songs_struct** temp_array; // The temp array for sorting. // Method Declaration. @@ -59,7 +60,7 @@ void resize_array(); // Increase buffer size of song array. void populate_array(); // Populates array with fields. void print_all_songs(); // Prints info for all songs in array. void print_song_info(); // Prints all info for provided song. -void sort_array(); // Sorts array by song name. +void sort_array(); // Linearly sorts array by song name. void save_array(); // Saves entire array to file(s). void save_line(); // Creates/saves single line of song data. void write_song_field(); // Writes a single song_filed to file. @@ -83,12 +84,13 @@ int main(int argc, char* argv[]) { } read_file(file_descriptor); + write(1, "Sorting arrays...\n", 19); sort_array(); //print_all_songs(); write(1, "Saving to file...\n", 19); save_array(); write(1, "Finished.\n", 11); - write(1, "Closing program...\n", 19); + write(1, "Closing program...\n", 20); close(file_descriptor); exit_program(); } @@ -127,41 +129,63 @@ int open_file(char* file_location, int operator_flags) { void read_file(int file_descriptor) { char *read_buffer; char *temp_buffer; + int current_read_int = 0; int index; int offset_amount; - size_t read_size; + off_t read_value; + off_t offset_size; read_buffer = calloc(1, BUFFER_SIZE); - temp_buffer = calloc(1, BUFFER_SIZE); - off_t read_value = read(file_descriptor, read_buffer, BUFFER_SIZE); - if (read_value < 0) { - err_sys("Failed to read line."); - } + while ((read_value = read(file_descriptor, read_buffer, (BUFFER_SIZE - 1))) != 0) { + if (read_value < 0) { + err_sys("Failed to read line."); + } - // Start from end of buffer. Read backwards until first null terminator - // is found. - index = BUFFER_SIZE - 1; - offset_amount = 0; - *temp_buffer = *read_buffer; - while (index > 0) { - if (temp_buffer[index] == '\n') { - // Found first null terminator. Save location and exit loop. - offset_amount = index; - index = 0; + // Start from end of buffer. Read backwards until first null terminator + // is found. + index = BUFFER_SIZE - 1; + offset_amount = 0; + temp_buffer = read_buffer; + while (index > 0) { + if (temp_buffer[index] == '\n') { + // Found newline terminator. Save location and exit loop. + offset_amount = index; + index = 0; // To exit loop. + } + index--; } - index--; - } - free(temp_buffer); - // Set "Read Size" for lseek to travel to last null terminator. - read_size = BUFFER_SIZE - offset_amount; - off_t offset_size = lseek(file_descriptor, read_size, SEEK_CUR); - if (offset_size < 0) { - err_sys("Failed to update pointer on read in."); - } + // Rewind to start of current read, then go to actual read value + // of buffer after cutoff. + size_t actual_read_size = strlen(read_buffer); + if (actual_read_size != 4095) { + actual_read_size--; + } + + offset_size = lseek(file_descriptor, (-(actual_read_size)), SEEK_CUR); + if (offset_size < 0) { + err_sys("Failed to update pointer on read in."); + } + offset_size = lseek(file_descriptor, offset_amount, SEEK_CUR); + if (offset_size < 0) { + err_sys("Failed to update pointer on read in."); + } - read_line(read_buffer, read_size); + // Remove "garbage" data at end of read and pass forward. + index = offset_amount + 1; + while (index < BUFFER_SIZE) { + read_buffer[index] = '\0'; + index++; + } + read_line(read_buffer, offset_size); + + // Reset read buffer for next read. + free(read_buffer); + read_buffer = calloc(1, BUFFER_SIZE); + + current_read_int++; + } free(read_buffer); } @@ -224,10 +248,8 @@ void tokenize_line(char *line_buffer) { field_index = 0; line_index++; - //if (strcmp(field_buffer, "") != 0) { - populate_array(field_number, field_buffer); - field_number++; - //} + populate_array(field_number, field_buffer); + field_number++; free(field_buffer); field_buffer = calloc(1, BUFFER_SIZE); @@ -254,7 +276,7 @@ void resize_array() { songs_array = realloc(songs_array, songs_array_max * sizeof(songs_struct* )); if (songs_array != NULL) { - printf("Allocation successful.\n"); + //write(1, "Allocation successful.\n", 24); } else { err_dump("Could not allocate memory for realloc."); } @@ -281,14 +303,17 @@ void populate_array(int field_number, char *field_buffer) { switch(field_number) { case 3: // Album name. songs_array[song_index]->album_name = copy_string(field_buffer); + //printf("Album: %s\n", songs_array[song_index]->album_name); break; case 8: // Artist name. songs_array[song_index]->artist = copy_string(field_buffer); + //printf("Artist: %s\n", songs_array[song_index]->artist); break; case 10: // Duration. temp_float = atof(field_buffer); temp_float_ptr = &temp_float; songs_array[song_index]->duration = copy_float(temp_float_ptr); + //printf("Duration: %.2f\n", *songs_array[song_index]->duration); break; case 14: // Hotttnesss. temp_double = atof(field_buffer); @@ -298,14 +323,17 @@ void populate_array(int field_number, char *field_buffer) { } temp_double_ptr = &temp_double; songs_array[song_index]->hotttnesss = copy_double(temp_double_ptr); + //printf("Hotttnesss: %.2f\n", *songs_array[song_index]->hotttnesss); break; case 17: // Song name. songs_array[song_index]->song_name = copy_string(field_buffer); + //printf("Name: %s\n", songs_array[song_index]->song_name); break; case 18: // Year. temp_int = atoi(field_buffer); temp_int_ptr = &temp_int; songs_array[song_index]->year = copy_int(temp_int_ptr); + //printf("Year: %d\n", *songs_array[song_index]->year); break; default: // Do nothing. This is not a field we care about. @@ -315,7 +343,7 @@ void populate_array(int field_number, char *field_buffer) { /** - * Sorts array by song name. + * Uses linear sort to arrange array by song name. */ void sort_array() { int sorted_bool = 0; // Holds if array has been sorted during this call. @@ -324,7 +352,7 @@ void sort_array() { // Loop through all array elements and sort if necessary. // Starts at 1 due to comparing two elements at once. - while (songs_array[index] != NULL) { + while ((songs_array[index] != NULL) &&(songs_array[index]->song_name != NULL)) { if (strcmp(songs_array[index - 1]->song_name, songs_array[index]->song_name) > 0) { temp_song = songs_array[index - 1]; songs_array[index - 1] = songs_array[index]; @@ -356,16 +384,12 @@ void print_all_songs() { * Attempts to find song with provided name. Prints result. */ void print_song_info(songs_struct* song) { - float duration = *song->duration; - int year = *song->year; - double hotttnesss = *song->hotttnesss; - printf("Song Name: %s\n", song->song_name); printf("Album Name: %s\n", song->album_name); printf("Artist Name: %s\n", song->artist); - printf("Duration: %.2f\n", duration); - printf("Year: %d\n", year); - printf("Hotttnesss: %f\n", hotttnesss); + printf("Duration: %.2f\n", *song->duration); + printf("Year: %d\n", *song->year); + printf("Hotttnesss: %f\n", *song->hotttnesss); printf("\n"); } @@ -377,6 +401,7 @@ void save_array() { int song_directory_descriptor; int song_binary_descriptor; + // Check test csv bool. If true, write to smaller csv. if (test_file_bool) { song_directory_descriptor = open_file("Data/SongDirectory_Small", O_CREAT | O_TRUNC | O_WRONLY); @@ -385,8 +410,8 @@ void save_array() { song_directory_descriptor = open_file("Data/SongDirectory", O_CREAT | O_TRUNC | O_WRONLY); song_binary_descriptor = open_file("Data/BinarySongData", O_CREAT | O_TRUNC | O_WRONLY); } - song_index = 0; + song_index = 0; while (songs_array[song_index] != NULL) { save_line(song_directory_descriptor, song_binary_descriptor); song_index++; diff --git a/UseDataBase.c b/UseDataBase.c index 2470cf67f06e6e8ef6271fa4ab6314aadde984ee..4c0812c3385eb475500502d1e4aa159f0ab7e023 100644 --- a/UseDataBase.c +++ b/UseDataBase.c @@ -46,7 +46,7 @@ typedef struct { double* hotttnesss; } songs_struct; // Songs struct. -int test_file_bool = 1; // Check if using smaller test csv or not. +int test_file_bool = 0; // Check if using smaller test csv or not. int songs_array_max = ARRAY_SIZE; // Saves current size of songs array. int song_index = 0; // Current song index. songs_struct** songs_array; // The array which holds all song pointers. @@ -56,7 +56,7 @@ songs_struct** songs_array; // The array which holds all song pointers. int open_file(); // Initially opens file to read. void read_songs(); // Reads in songs from database files. void populate_array(); // Populates array with fields. -void resize_array(); // Reallocates memory for array. +void resize_array(); // Increase buffer size of song array. void print_all_songs(); // Prints info for all songs in array. void print_song_info(); // Prints all info for provided song. void print_help_text(); // Prints helper text for user. @@ -110,18 +110,22 @@ int main(int argc, char* argv[]) { print_help_text(); + // Actually run program for user input. while (run_program_bool) { user_input_string = calloc(1, BUFFER_SIZE); // Read input from console. write(1, "Enter input: ", 14); read_value = read(0, user_input_string, BUFFER_SIZE); + if (read_value < 0) { + err_sys("Failed to read line."); + } write(1, "\n", 2); user_input_string = remove_newline(user_input_string); // Read user input and handle accordingly. - if ((user_input_string != NULL) && (strcmp(user_input_string, "") != 0)) { + if ((user_input_string != NULL)) { // && (strcmp(user_input_string, "") != 0)) { input_to_lower = to_lower_case(user_input_string); // Check if user needs reprinting of help text. @@ -138,7 +142,6 @@ int main(int argc, char* argv[]) { print_all_songs(); } else { // Attempt to find song with given name. - //printf("User Input: %s", input_to_lower); find_song(input_to_lower); } free(input_to_lower); @@ -201,6 +204,11 @@ void populate_array(int song_size, ssize_t read_buffer) { double* double_buffer; double* double_pointer; + // Check to make sure there are still open spots in songs_array. + if (song_index >= songs_array_max) { + resize_array(); + } + songs_array[song_index] = calloc(1, sizeof(songs_struct)); // Get Song Name. @@ -265,10 +273,24 @@ void populate_array(int song_size, ssize_t read_buffer) { free(int_buffer); song_index++; - } +/** + * Increase current buffer size and rebuffer songs array. + * Call to initialize, and then anytime the array runs out of space. + */ +void resize_array() { + songs_array_max = songs_array_max * 2; + + songs_array = realloc(songs_array, songs_array_max * sizeof(songs_struct* )); + if (songs_array != NULL) { + //write(1, "Allocation successful.\n", 24); + } else { + err_dump("Could not allocate memory for realloc."); + } +} + /** * Prints all songs.