diff --git a/c-programming/reverse-ramdisk.c b/c-programming/reverse-ramdisk.c index 9563393..c3fd48d 100644 --- a/c-programming/reverse-ramdisk.c +++ b/c-programming/reverse-ramdisk.c @@ -3,7 +3,13 @@ C programming idea: Handling temporary files like memory allocations (allocating 50% AI, 50% human (the code is tested and reviewed) -GCC/Clang/TCC: Compile with -DTEST to set macro TEST as defined +Warning: The current result is quick and dirty. Not for educational or +production purposes. + +GCC/Clang/TCC: Compile with -DTEST to set macro TEST as defined, with -DDEBUG +to enable debug mode + +To-Do: error handling on line 167, function fread() */ #include @@ -21,14 +27,34 @@ typedef struct { TempFile* temp_files = NULL; size_t num_temp_files = 0; -#define line_fail(x) do { \ +#ifdef DEBUG +# define line_fail(x) do { \ printf("failed on line %d\n", __LINE__ + x); \ } while (0) +#else +# define line_fail(x) do {} while (0) +#endif int tf_alloc(size_t n, size_t type_size) { // Create an empty file - char file_path[20]; - sprintf(file_path, "tf_%zu.tmp", num_temp_files); + size_t len_digit; + if (num_temp_files == 0) + len_digit = 1; + else + len_digit = (size_t) log((double) num_temp_files + 1.) / log(10.); + size_t file_path_len = len_digit + strlen("tf_.tmp"); + char* file_path = malloc((file_path_len + 1) * sizeof(char)); + if (file_path == NULL) { + fail_line(-2); + return -1; + } + int res = snprintf(file_path, file_path_len, "tf_%zu.tmp", num_temp_files); + if ((size_t) res != file_path_len) { + fail_line(-2); + return -1; + } + + // Open the file FILE* file = fopen(file_path, "w+b"); if (file == NULL) { line_fail(-2); @@ -36,7 +62,7 @@ int tf_alloc(size_t n, size_t type_size) { } // Allocate memory for the TempFile struct - TempFile* temp_file = (TempFile*)malloc(sizeof(TempFile)); + TempFile* temp_file = malloc(sizeof(TempFile)); if (temp_file == NULL) { line_fail(-2); return -1; @@ -51,7 +77,7 @@ int tf_alloc(size_t n, size_t type_size) { num_temp_files++; // Reallocate memory for the temp_files array - temp_files = (TempFile*)realloc(temp_files, num_temp_files * sizeof(TempFile)); + temp_files = realloc(temp_files, num_temp_files * sizeof(TempFile)); if (temp_files == NULL) { line_fail(-2); return -1; @@ -64,13 +90,7 @@ int tf_alloc(size_t n, size_t type_size) { } int tf_free(int ID) { - // Find the temp file with the given ID - int index = -1; - for (int i = 0; i < num_temp_files; i++) - if (temp_files[i].ID == ID) { - index = i; - break; - } + size_t index = (size_t) ID; if (index == -1) return -1; @@ -79,6 +99,7 @@ int tf_free(int ID) { // Delete the file if (remove(temp_files[index].file_path) != 0) { + line_fail(-1); return -1; } @@ -86,15 +107,15 @@ int tf_free(int ID) { // Shift the remaining temp files in the array for (int i = index; i < num_temp_files - 1; i++) { - temp_files[i] = temp_files[i + 1]; + temp_files[(size_t) i] = temp_files[(size_t) i + 1]; } - // Decrease the number of temp files num_temp_files--; // Reallocate memory for the temp_files array - temp_files = (TempFile*)realloc(temp_files, num_temp_files * sizeof(TempFile)); + temp_files = realloc(temp_files, num_temp_files * sizeof(TempFile)); if (temp_files == NULL && num_temp_files > 0) { + line_fail(-2); return -1; } @@ -102,24 +123,17 @@ int tf_free(int ID) { } int tf_write(int ID, size_t offset, void* data, size_t data_size) { - // Find the temp file with the given ID - int index = -1; - for (int i = 0; i < num_temp_files; i++) { - if (temp_files[i].ID == ID) { - index = i; - break; - } - } + size_t index = (size_t) ID; if (index == -1) return -1; - // Open the file in append mode + // Check file handler for NULL FILE* file = temp_files[index].file; if (file == NULL) return -1; - // Seek + // Set the position fseek(file, offset, SEEK_SET); // Write the data to the file @@ -132,18 +146,7 @@ int tf_write(int ID, size_t offset, void* data, size_t data_size) { } int tf_read(int ID, size_t offset, void* dest, size_t data_size) { - // Find the temp file with the given ID - int index = -1; - for (int i = 0; i < num_temp_files; i++) { - if (temp_files[i].ID == ID) { - index = i; - break; - } - } - - if (index == -1) { - return -1; - } + size_t index = (size_t) ID; // Open the file in read mode FILE* file = temp_files[index].file; @@ -154,16 +157,14 @@ int tf_read(int ID, size_t offset, void* dest, size_t data_size) { void* data = malloc(data_size); if (data == NULL) { fclose(file); + fail_line(-3); return -1; } // Initialize the memory in the data buffer - memset(data, 0, data_size); - - fseek(file, offset, SEEK_SET); - size_t bytes_read = fread(data, 1, data_size, file); - - // Copy the data to the destination pointer + memset(data, 0, data_size); // clear destination + fseek(file, offset, SEEK_SET); // set position + size_t bytes_read = fread(data, 1, data_size, file); // read bytes memcpy(dest, data, data_size); free(data); // Free the allocated memory @@ -173,11 +174,13 @@ int tf_read(int ID, size_t offset, void* dest, size_t data_size) { return -1; } +#ifdef DEBUG printf("Read: ID = %d, data = %016" PRIXPTR ", size = %zu -> '", ID, (uintptr_t)dest, data_size); for (size_t i = 0; i < data_size; i++) printf("0x%02" PRIX8 " ", *((uint8_t*)(dest + i))); printf("'\n"); +#endif return 0; }