diff --git a/src/file.c b/src/file.c index 2b871e2..37cd10e 100644 --- a/src/file.c +++ b/src/file.c @@ -68,7 +68,7 @@ CosmsCoreFileError cosms_core_file_open(struct cosms_core_file *file, const char } #elif defined(_WIN32) DWORD access_flags = 0; - DWORD create_flag = 0; + DWORD create_flag = OPEN_EXISTING; if (mode & COSMS_CORE_FILE_MODE_READ) { access_flags |= GENERIC_READ; @@ -122,7 +122,7 @@ CosmsCoreFileError cosms_core_file_close(struct cosms_core_file *file) { return COSMS_CORE_FILE_UNKOWN_ERROR; } #elif defined(_WIN32) - BOOL error = CloseHandle(file); + BOOL error = CloseHandle(file->native_file); if (error == 0) { if (GetLastError() == ERROR_INVALID_HANDLE) { return COSMS_CORE_FILE_INVALID_FILE; @@ -135,25 +135,32 @@ CosmsCoreFileError cosms_core_file_close(struct cosms_core_file *file) { return COSMS_CORE_FILE_OK; } -CosmsCoreFileError cosms_core_file_get_size(unsigned long long *size) { +CosmsCoreFileError cosms_core_file_get_size(struct cosms_core_file *file, unsigned long long *size) { #if defined(__GNUC__) struct stat file_stat; - if (stat(path, &file_stat) != 0) { + if (fstat(file->native_file, &file_stat) != 0) { + if (errno == EBADF) { + return COSMS_CORE_FILE_INVALID_FILE; + } + return COSMS_CORE_FILE_COULD_NOT_READ_SIZE; } (*size) = file_stat.st_size; #elif defined(_WIN32) DWORD high_size; - DWORD low_size = GetFileSize(file, &high_size); - if (low_size == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) { - CloseHandle(file); + DWORD low_size = GetFileSize(file->native_file, &high_size); + if (low_size == INVALID_FILE_SIZE) { + if (GetLastError() == ERROR_INVALID_HANDLE) { + return COSMS_CORE_FILE_INVALID_FILE; + } + return COSMS_CORE_FILE_COULD_NOT_READ_SIZE; } (*size) = ((unsigned long long)high_size << 32) | low_size; #endif - + return COSMS_CORE_FILE_OK; } @@ -454,6 +461,9 @@ const char *cosms_core_file_error_string(CosmsCoreFileError error) { case COSMS_CORE_FILE_STILL_OPEN: return "cosms-file still open"; + case COSMS_CORE_FILE_INVALID_FILE: + return "cosms-file invalid native file given"; + default: return NULL; } diff --git a/tests/data/large-write-file.txt b/tests/data/large-write-file.txt new file mode 100644 index 0000000..d4c5011 Binary files /dev/null and b/tests/data/large-write-file.txt differ diff --git a/tests/unit/file.c b/tests/unit/file.c index c6e4a42..a99c044 100644 --- a/tests/unit/file.c +++ b/tests/unit/file.c @@ -5,6 +5,186 @@ #include #include +COSMS_CORE_TEST_TEST(file_open, + COSMS_CORE_TEST_SUB_TEST(opening small file for reading, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/small-file.txt", COSMS_CORE_FILE_MODE_READ); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening large file for reading, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/large-file.txt", COSMS_CORE_FILE_MODE_READ); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening small file for writting, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/small-file.txt", COSMS_CORE_FILE_MODE_WRITE); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening large file for writting, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/large-file.txt", COSMS_CORE_FILE_MODE_WRITE); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening small file for appending, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/small-file.txt", COSMS_CORE_FILE_MODE_APPEND); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening large file for appending, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/large-file.txt", COSMS_CORE_FILE_MODE_APPEND); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening small file for reading and writting, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/small-file.txt", COSMS_CORE_FILE_MODE_READ | COSMS_CORE_FILE_MODE_WRITE); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(opening large file for reading and writting, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/large-file.txt", COSMS_CORE_FILE_MODE_READ | COSMS_CORE_FILE_MODE_WRITE); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) +) + +COSMS_CORE_TEST_TEST(file_close, + COSMS_CORE_TEST_SUB_TEST(closing file, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/small-file.txt", COSMS_CORE_FILE_MODE_READ); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(closing non-existing file, + struct cosms_core_file file; + file.native_file = 0; + + CosmsCoreFileError error = cosms_core_file_close(&file); + if (error != COSMS_CORE_FILE_INVALID_FILE) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + ) +) + +COSMS_CORE_TEST_TEST(file_size, + COSMS_CORE_TEST_SUB_TEST(reading small file size, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/small-file.txt", COSMS_CORE_FILE_MODE_READ); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + unsigned long long size = 0; + error = cosms_core_file_get_size(&file, &size); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + if (size != 13) { + cosms_core_test_sub_test_error = "result does not match expected result"; + } + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(reading large file size, + struct cosms_core_file file; + CosmsCoreFileError error = cosms_core_file_open(&file, "tests/data/large-file.txt", COSMS_CORE_FILE_MODE_READ); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + unsigned long long size = 0; + error = cosms_core_file_get_size(&file, &size); + if (error != COSMS_CORE_FILE_OK) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } else { + if (size != 5242880000ULL) { + cosms_core_test_sub_test_error = "result does not match expected result"; + } + } + } + ) + + COSMS_CORE_TEST_SUB_TEST(reading non-existing file size, + struct cosms_core_file file; + file.native_file = 0; + + unsigned long long size = 0; + CosmsCoreFileError error = cosms_core_file_get_size(&file, &size); + if (error != COSMS_CORE_FILE_INVALID_FILE) { + cosms_core_test_sub_test_error = cosms_core_file_error_string(error); + } + ) +) + COSMS_CORE_TEST_TEST(file_read, COSMS_CORE_TEST_SUB_TEST(reading small file, unsigned long long file_size = 0; diff --git a/tests/unit/file.h b/tests/unit/file.h index 1a8b33c..58946da 100644 --- a/tests/unit/file.h +++ b/tests/unit/file.h @@ -3,11 +3,17 @@ #include "test.h" +COSMS_CORE_TEST_DEFINE(file_open); +COSMS_CORE_TEST_DEFINE(file_close); +COSMS_CORE_TEST_DEFINE(file_size); COSMS_CORE_TEST_DEFINE(file_read); COSMS_CORE_TEST_DEFINE(file_write); COSMS_CORE_TEST_DEFINE(file_delete); COSMS_CORE_TEST_EXPORT(file, + COSMS_CORE_TEST_FUNCTION_NAME(file_open), + COSMS_CORE_TEST_FUNCTION_NAME(file_close), + COSMS_CORE_TEST_FUNCTION_NAME(file_size), COSMS_CORE_TEST_FUNCTION_NAME(file_read), COSMS_CORE_TEST_FUNCTION_NAME(file_write), COSMS_CORE_TEST_FUNCTION_NAME(file_delete)