From b18073a5cdd590f4338cd75068cf0b5918ec738a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 2 Jan 2024 21:43:57 +0100 Subject: [PATCH 1/2] Minor improvement of I/O functions documentation --- src/base/system.h | 117 +++++++++++++++++++++++++++++++--------------- src/base/types.h | 5 ++ 2 files changed, 85 insertions(+), 37 deletions(-) diff --git a/src/base/system.h b/src/base/system.h index de2de0346..3245ac161 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -219,12 +219,42 @@ bool mem_has_null(const void *block, size_t size); */ enum { + /** + * Open file for reading. + * + * @see io_open + */ IOFLAG_READ = 1, + /** + * Open file for writing. + * + * @see io_open + */ IOFLAG_WRITE = 2, + /** + * Open file for appending at the end. + * + * @see io_open + */ IOFLAG_APPEND = 4, + /** + * Start seeking from the beginning of the file. + * + * @see io_seek + */ IOSEEK_START = 0, + /** + * Start seeking from the current position. + * + * @see io_seek + */ IOSEEK_CUR = 1, + /** + * Start seeking from the end of the file. + * + * @see io_seek + */ IOSEEK_END = 2, }; @@ -236,10 +266,9 @@ enum * @param File to open. * @param flags A set of IOFLAG flags. * - * @sa IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND. - * - * @return A handle to the file on success and 0 on failure. + * @see IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND. * + * @return A handle to the file on success, or `nullptr` on failure. */ IOHANDLE io_open(const char *filename, int flags); @@ -253,7 +282,6 @@ IOHANDLE io_open(const char *filename, int flags); * @param size Number of bytes to read from the file. * * @return Number of bytes read. - * */ unsigned io_read(IOHANDLE io, void *buffer, unsigned size); @@ -279,7 +307,7 @@ void io_read_all(IOHANDLE io, void **result, unsigned *result_len); * * @param io Handle to the file to read data from. * - * @return The file's remaining contents or null on failure. + * @return The file's remaining contents, or `nullptr` on failure. * * @remark Guarantees that there are no internal null bytes. * @remark Guarantees that result will contain zero-termination. @@ -300,7 +328,7 @@ char *io_read_all_str(IOHANDLE io); int io_skip(IOHANDLE io, int size); /** - * Writes data from a buffer to file. + * Writes data from a buffer to a file. * * @ingroup File-IO * @@ -313,13 +341,13 @@ int io_skip(IOHANDLE io, int size); unsigned io_write(IOHANDLE io, const void *buffer, unsigned size); /** - * Writes a platform dependent newline to file. + * Writes a platform dependent newline to a file. * * @ingroup File-IO * * @param io Handle to the file. * - * @return true on success, false on failure. + * @return `true` on success, `false` on failure. */ bool io_write_newline(IOHANDLE io); @@ -329,10 +357,10 @@ bool io_write_newline(IOHANDLE io); * @ingroup File-IO * * @param io Handle to the file. - * @param offset Offset from pos to stop. + * @param offset Offset from position to search. * @param origin Position to start searching from. * - * @return 0 on success. + * @return `0` on success. */ int io_seek(IOHANDLE io, int offset, int origin); @@ -343,18 +371,18 @@ int io_seek(IOHANDLE io, int offset, int origin); * * @param io Handle to the file. * - * @return The current position. @c -1L if an error occurred. + * @return The current position, or `-1` on failure. */ long int io_tell(IOHANDLE io); /** - * Gets the total length of the file. Resetting cursor to the beginning + * Gets the total length of the file. Resets cursor to the beginning. * * @ingroup File-IO * * @param io Handle to the file. * - * @return The total size. @c -1L if an error occurred. + * @return The total size, or `-1` on failure. */ long int io_length(IOHANDLE io); @@ -365,7 +393,7 @@ long int io_length(IOHANDLE io); * * @param io Handle to the file. * - * @return 0 on success. + * @return `0` on success. */ int io_close(IOHANDLE io); @@ -376,7 +404,7 @@ int io_close(IOHANDLE io); * * @param io Handle to the file. * - * @return 0 on success. + * @return `0` on success. */ int io_flush(IOHANDLE io); @@ -387,7 +415,7 @@ int io_flush(IOHANDLE io); * * @param io Handle to the file. * - * @return 0 on success. + * @return `0` on success. */ int io_sync(IOHANDLE io); @@ -398,34 +426,57 @@ int io_sync(IOHANDLE io); * * @param io Handle to the file. * - * @return nonzero on error, 0 otherwise. + * @return `0` on success, or non-`0` on error. */ int io_error(IOHANDLE io); /** * @ingroup File-IO - * @return An to the standard input. + * + * Returns a handle for the standard input. + * + * @return An @link IOHANDLE @endlink for the standard input. + * + * @remark The handle must not be closed. */ IOHANDLE io_stdin(); /** * @ingroup File-IO - * @return An to the standard output. + * + * Returns a handle for the standard output. + * + * @return An @link IOHANDLE @endlink for the standard output. + * + * @remark The handle must not be closed. */ IOHANDLE io_stdout(); /** * @ingroup File-IO - * @return An to the standard error. + * + * Returns a handle for the standard error. + * + * @return An @link IOHANDLE @endlink for the standard error. + * + * @remark The handle must not be closed. */ IOHANDLE io_stderr(); /** * @ingroup File-IO - * @return An to the current executable. + * + * Returns a handle for the current executable. + * + * @return An @link IOHANDLE @endlink for the current executable. */ IOHANDLE io_current_exe(); +/** + * Wrapper for asynchronously writing to an @link IOHANDLE @endlink. + * + * @ingroup File-IO + */ typedef struct ASYNCIO ASYNCIO; /** @@ -436,12 +487,11 @@ typedef struct ASYNCIO ASYNCIO; * @param io Handle to the file. * * @return The handle for asynchronous writing. - * */ ASYNCIO *aio_new(IOHANDLE io); /** - * Locks the ASYNCIO structure so it can't be written into by + * Locks the `ASYNCIO` structure so it can't be written into by * other threads. * * @ingroup File-IO @@ -451,7 +501,7 @@ ASYNCIO *aio_new(IOHANDLE io); void aio_lock(ASYNCIO *aio); /** - * Unlocks the ASYNCIO structure after finishing the contiguous + * Unlocks the `ASYNCIO` structure after finishing the contiguous * write. * * @ingroup File-IO @@ -477,12 +527,11 @@ void aio_write(ASYNCIO *aio, const void *buffer, unsigned size); * @ingroup File-IO * * @param aio Handle to the file. - * */ void aio_write_newline(ASYNCIO *aio); /** - * Queues a chunk of data for writing. The ASYNCIO struct must be + * Queues a chunk of data for writing. The `ASYNCIO` struct must be * locked using @link aio_lock @endlink first. * * @ingroup File-IO @@ -490,18 +539,16 @@ void aio_write_newline(ASYNCIO *aio); * @param aio Handle to the file. * @param buffer Pointer to the data that should be written. * @param size Number of bytes to write. - * */ void aio_write_unlocked(ASYNCIO *aio, const void *buffer, unsigned size); /** - * Queues a newline for writing. The ASYNCIO struct must be locked + * Queues a newline for writing. The `ASYNCIO` struct must be locked * using @link aio_lock @endlink first. * * @ingroup File-IO * * @param aio Handle to the file. - * */ void aio_write_newline_unlocked(ASYNCIO *aio); @@ -509,16 +556,15 @@ void aio_write_newline_unlocked(ASYNCIO *aio); * Checks whether errors have occurred during the asynchronous * writing. * - * Call this function regularly to see if there are errors. Call - * this function after to see if the process of writing + * Call this function regularly to see if there are errors. Call this + * function after @link aio_wait @endlink to see if the process of writing * to the file succeeded. * * @ingroup File-IO * * @param aio Handle to the file. * - * @eturn 0 if no error occurred, and nonzero on error. - * + * @return `0` on success, or non-`0` on error. */ int aio_error(ASYNCIO *aio); @@ -528,7 +574,6 @@ int aio_error(ASYNCIO *aio); * @ingroup File-IO * * @param aio Handle to the file. - * */ void aio_close(ASYNCIO *aio); @@ -538,17 +583,15 @@ void aio_close(ASYNCIO *aio); * @ingroup File-IO * * @param aio Handle to the file. - * */ void aio_wait(ASYNCIO *aio); /** - * Frees the resources associated to the asynchronous file handle. + * Frees the resources associated with the asynchronous file handle. * * @ingroup File-IO * * @param aio Handle to the file. - * */ void aio_free(ASYNCIO *aio); diff --git a/src/base/types.h b/src/base/types.h index 13abeb0e8..b1d5af051 100644 --- a/src/base/types.h +++ b/src/base/types.h @@ -10,6 +10,11 @@ enum class TRISTATE ALL, }; +/** + * Handle for input/output files/streams. + * + * @ingroup File-IO + */ typedef void *IOHANDLE; typedef int (*FS_LISTDIR_CALLBACK)(const char *name, int is_dir, int dir_type, void *user); From 1021fdf7ae26f08a03be73c137c8471a4ec00eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 15 Sep 2024 15:36:57 +0200 Subject: [PATCH 2/2] Consistently order I/O functions declarations and definitions --- src/base/system.cpp | 136 ++++++++++++++++++++++---------------------- src/base/system.h | 48 ++++++++-------- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/src/base/system.cpp b/src/base/system.cpp index b244163f9..f42341453 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -84,58 +84,6 @@ #include #endif -IOHANDLE io_stdin() -{ - return stdin; -} - -IOHANDLE io_stdout() -{ - return stdout; -} - -IOHANDLE io_stderr() -{ - return stderr; -} - -IOHANDLE io_current_exe() -{ - // From https://stackoverflow.com/a/1024937. -#if defined(CONF_FAMILY_WINDOWS) - wchar_t wide_path[IO_MAX_PATH_LENGTH]; - if(GetModuleFileNameW(NULL, wide_path, std::size(wide_path)) == 0 || GetLastError() != ERROR_SUCCESS) - { - return 0; - } - const std::optional path = windows_wide_to_utf8(wide_path); - return path.has_value() ? io_open(path.value().c_str(), IOFLAG_READ) : 0; -#elif defined(CONF_PLATFORM_MACOS) - char path[IO_MAX_PATH_LENGTH]; - uint32_t path_size = sizeof(path); - if(_NSGetExecutablePath(path, &path_size)) - { - return 0; - } - return io_open(path, IOFLAG_READ); -#else - static const char *NAMES[] = { - "/proc/self/exe", // Linux, Android - "/proc/curproc/exe", // NetBSD - "/proc/curproc/file", // DragonFly - }; - for(auto &name : NAMES) - { - IOHANDLE result = io_open(name, IOFLAG_READ); - if(result) - { - return result; - } - } - return 0; -#endif -} - static NETSTATS network_stats = {0}; #define VLEN 128 @@ -403,11 +351,6 @@ long int io_length(IOHANDLE io) return length; } -int io_error(IOHANDLE io) -{ - return ferror((FILE *)io); -} - unsigned io_write(IOHANDLE io, const void *buffer, unsigned size) { return fwrite(buffer, 1, size, (FILE *)io); @@ -445,6 +388,63 @@ int io_sync(IOHANDLE io) #endif } +int io_error(IOHANDLE io) +{ + return ferror((FILE *)io); +} + +IOHANDLE io_stdin() +{ + return stdin; +} + +IOHANDLE io_stdout() +{ + return stdout; +} + +IOHANDLE io_stderr() +{ + return stderr; +} + +IOHANDLE io_current_exe() +{ + // From https://stackoverflow.com/a/1024937. +#if defined(CONF_FAMILY_WINDOWS) + wchar_t wide_path[IO_MAX_PATH_LENGTH]; + if(GetModuleFileNameW(NULL, wide_path, std::size(wide_path)) == 0 || GetLastError() != ERROR_SUCCESS) + { + return 0; + } + const std::optional path = windows_wide_to_utf8(wide_path); + return path.has_value() ? io_open(path.value().c_str(), IOFLAG_READ) : 0; +#elif defined(CONF_PLATFORM_MACOS) + char path[IO_MAX_PATH_LENGTH]; + uint32_t path_size = sizeof(path); + if(_NSGetExecutablePath(path, &path_size)) + { + return 0; + } + return io_open(path, IOFLAG_READ); +#else + static const char *NAMES[] = { + "/proc/self/exe", // Linux, Android + "/proc/curproc/exe", // NetBSD + "/proc/curproc/file", // DragonFly + }; + for(auto &name : NAMES) + { + IOHANDLE result = io_open(name, IOFLAG_READ); + if(result) + { + return result; + } + } + return 0; +#endif +} + #define ASYNC_BUFSIZE (8 * 1024) #define ASYNC_LOCAL_BUFSIZE (64 * 1024) @@ -719,17 +719,6 @@ int aio_error(ASYNCIO *aio) return aio->error; } -void aio_free(ASYNCIO *aio) -{ - aio->lock.lock(); - if(aio->thread) - { - thread_detach(aio->thread); - aio->thread = 0; - } - aio_handle_free_and_unlock(aio); -} - void aio_close(ASYNCIO *aio) { { @@ -755,6 +744,17 @@ void aio_wait(ASYNCIO *aio) thread_wait(thread); } +void aio_free(ASYNCIO *aio) +{ + aio->lock.lock(); + if(aio->thread) + { + thread_detach(aio->thread); + aio->thread = 0; + } + aio_handle_free_and_unlock(aio); +} + struct THREAD_RUN { void (*threadfunc)(void *); diff --git a/src/base/system.h b/src/base/system.h index 3245ac161..cf75ce309 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -327,30 +327,6 @@ char *io_read_all_str(IOHANDLE io); */ int io_skip(IOHANDLE io, int size); -/** - * Writes data from a buffer to a file. - * - * @ingroup File-IO - * - * @param io Handle to the file. - * @param buffer Pointer to the data that should be written. - * @param size Number of bytes to write. - * - * @return Number of bytes written. - */ -unsigned io_write(IOHANDLE io, const void *buffer, unsigned size); - -/** - * Writes a platform dependent newline to a file. - * - * @ingroup File-IO - * - * @param io Handle to the file. - * - * @return `true` on success, `false` on failure. - */ -bool io_write_newline(IOHANDLE io); - /** * Seeks to a specified offset in the file. * @@ -386,6 +362,30 @@ long int io_tell(IOHANDLE io); */ long int io_length(IOHANDLE io); +/** + * Writes data from a buffer to a file. + * + * @ingroup File-IO + * + * @param io Handle to the file. + * @param buffer Pointer to the data that should be written. + * @param size Number of bytes to write. + * + * @return Number of bytes written. + */ +unsigned io_write(IOHANDLE io, const void *buffer, unsigned size); + +/** + * Writes a platform dependent newline to a file. + * + * @ingroup File-IO + * + * @param io Handle to the file. + * + * @return `true` on success, `false` on failure. + */ +bool io_write_newline(IOHANDLE io); + /** * Closes a file. *