diff --git a/src/base/logger.h b/src/base/logger.h index 9624c8c12ea..a5c872df49c 100644 --- a/src/base/logger.h +++ b/src/base/logger.h @@ -7,7 +7,7 @@ #include #include -typedef struct IOINTERNAL *IOHANDLE; +typedef void *IOHANDLE; /** * @ingroup Log diff --git a/src/base/system.cpp b/src/base/system.cpp index ddcaad016d6..263e1e47066 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -91,10 +91,10 @@ IOHANDLE io_stdin() { - return (IOHANDLE)stdin; + return stdin; } -IOHANDLE io_stdout() { return (IOHANDLE)stdout; } -IOHANDLE io_stderr() { return (IOHANDLE)stderr; } +IOHANDLE io_stdout() { return stdout; } +IOHANDLE io_stderr() { return stderr; } IOHANDLE io_current_exe() { @@ -258,21 +258,52 @@ IOHANDLE io_open_impl(const char *filename, int flags) dbg_assert(flags == (IOFLAG_READ | IOFLAG_SKIP_BOM) || flags == IOFLAG_READ || flags == IOFLAG_WRITE || flags == IOFLAG_APPEND, "flags must be read, read+skipbom, write or append"); #if defined(CONF_FAMILY_WINDOWS) const std::wstring wide_filename = windows_utf8_to_wide(filename); + DWORD desired_access; + DWORD creation_disposition; if((flags & IOFLAG_READ) != 0) - return (IOHANDLE)_wfsopen(wide_filename.c_str(), L"rb", _SH_DENYNO); - if(flags == IOFLAG_WRITE) - return (IOHANDLE)_wfsopen(wide_filename.c_str(), L"wb", _SH_DENYNO); - if(flags == IOFLAG_APPEND) - return (IOHANDLE)_wfsopen(wide_filename.c_str(), L"ab", _SH_DENYNO); - return 0x0; + { + desired_access = FILE_READ_DATA; + creation_disposition = OPEN_EXISTING; + } + else if(flags == IOFLAG_WRITE) + { + desired_access = FILE_WRITE_DATA; + creation_disposition = OPEN_ALWAYS; + } + else if(flags == IOFLAG_APPEND) + { + desired_access = FILE_APPEND_DATA; + creation_disposition = OPEN_ALWAYS; + } + else + { + dbg_assert(false, "logic error"); + return nullptr; + } + HANDLE handle = CreateFileW(wide_filename.c_str(), desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, creation_disposition, FILE_ATTRIBUTE_NORMAL, nullptr); + if(handle == INVALID_HANDLE_VALUE) + return nullptr; // otherwise all existing checks don't work for the invalid handle + return handle; #else + const char *open_mode; if((flags & IOFLAG_READ) != 0) - return (IOHANDLE)fopen(filename, "rb"); - if(flags == IOFLAG_WRITE) - return (IOHANDLE)fopen(filename, "wb"); - if(flags == IOFLAG_APPEND) - return (IOHANDLE)fopen(filename, "ab"); - return 0x0; + { + open_mode = "rb"; + } + else if(flags == IOFLAG_WRITE) + { + open_mode = "wb"; + } + else if(flags == IOFLAG_APPEND) + { + open_mode = "ab"; + } + else + { + dbg_assert(false, "logic error"); + return nullptr; + } + return fopen(filename, open_mode); #endif } @@ -293,7 +324,13 @@ IOHANDLE io_open(const char *filename, int flags) unsigned io_read(IOHANDLE io, void *buffer, unsigned size) { +#if defined(CONF_FAMILY_WINDOWS) + DWORD actual_size; + ReadFile((HANDLE)io, buffer, size, &actual_size, nullptr); + return actual_size; +#else return fread(buffer, 1, size, (FILE *)io); +#endif } void io_read_all(IOHANDLE io, void **result, unsigned *result_len) @@ -343,14 +380,31 @@ char *io_read_all_str(IOHANDLE io) unsigned io_skip(IOHANDLE io, int size) { - fseek((FILE *)io, size, SEEK_CUR); - return size; + return io_seek(io, size, IOSEEK_CUR); } int io_seek(IOHANDLE io, int offset, int origin) { +#if defined(CONF_FAMILY_WINDOWS) + DWORD move_method; + switch(origin) + { + case IOSEEK_START: + move_method = FILE_BEGIN; + break; + case IOSEEK_CUR: + move_method = FILE_CURRENT; + break; + case IOSEEK_END: + move_method = FILE_END; + break; + default: + dbg_assert(false, "origin invalid"); + return -1; + } + return SetFilePointer((HANDLE)io, offset, nullptr, move_method); +#else int real_origin; - switch(origin) { case IOSEEK_START: @@ -363,15 +417,20 @@ int io_seek(IOHANDLE io, int offset, int origin) real_origin = SEEK_END; break; default: + dbg_assert(false, "origin invalid"); return -1; } - return fseek((FILE *)io, offset, real_origin); +#endif } long int io_tell(IOHANDLE io) { +#if defined(CONF_FAMILY_WINDOWS) + return SetFilePointer((HANDLE)io, 0, nullptr, FILE_CURRENT); +#else return ftell((FILE *)io); +#endif } long int io_length(IOHANDLE io) @@ -385,12 +444,23 @@ long int io_length(IOHANDLE io) int io_error(IOHANDLE io) { +#if defined(CONF_FAMILY_WINDOWS) + // Only works when called directly after the operation that failed + return GetLastError(); +#else return ferror((FILE *)io); +#endif } unsigned io_write(IOHANDLE io, const void *buffer, unsigned size) { +#if defined(CONF_FAMILY_WINDOWS) + DWORD actual_size; + WriteFile((HANDLE)io, buffer, size, &actual_size, nullptr); + return actual_size; +#else return fwrite(buffer, 1, size, (FILE *)io); +#endif } bool io_write_newline(IOHANDLE io) @@ -404,12 +474,20 @@ bool io_write_newline(IOHANDLE io) int io_close(IOHANDLE io) { +#if defined(CONF_FAMILY_WINDOWS) + return CloseHandle((HANDLE)io) == 0; +#else return fclose((FILE *)io) != 0; +#endif } int io_flush(IOHANDLE io) { +#if defined(CONF_FAMILY_WINDOWS) + return FlushFileBuffers((HANDLE)io) == FALSE; +#else return fflush((FILE *)io); +#endif } int io_sync(IOHANDLE io) @@ -419,7 +497,7 @@ int io_sync(IOHANDLE io) return 1; } #if defined(CONF_FAMILY_WINDOWS) - return FlushFileBuffers((HANDLE)_get_osfhandle(_fileno((FILE *)io))) == 0; + return FlushFileBuffers((HANDLE)io) == 0; #else return fsync(fileno((FILE *)io)) != 0; #endif diff --git a/src/base/system.h b/src/base/system.h index 71781c4ef54..d837399aed7 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -223,7 +223,7 @@ enum IO_MAX_PATH_LENGTH = 512, }; -typedef struct IOINTERNAL *IOHANDLE; +typedef void *IOHANDLE; /** * Opens a file.