123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- #pragma once
- // Baselib FileIO
- //
- // This is a file reading abstraction api heavily influenced by next-gen async API's like io_uring, windows register I/O, etc.
- // This api allows for platform independent async file reading.
- #include "Baselib_ErrorState.h"
- #include "Baselib_Memory.h"
- #include "Internal/Baselib_EnumSizeCheck.h"
- #ifdef __cplusplus
- BASELIB_C_INTERFACE
- {
- #endif
- // Event queue handle.
- typedef struct Baselib_FileIO_EventQueue {void* handle;} Baselib_FileIO_EventQueue;
- // Async file handle.
- typedef struct Baselib_FileIO_AsyncFile {void* handle;} Baselib_FileIO_AsyncFile;
- // Sync file handle.
- typedef struct Baselib_FileIO_SyncFile {void* handle;} Baselib_FileIO_SyncFile;
- // Event queue handle invalid constant.
- static const Baselib_FileIO_EventQueue Baselib_FileIO_EventQueue_Invalid = { NULL };
- // Async file handle invalid constant.
- static const Baselib_FileIO_AsyncFile Baselib_FileIO_AsyncFile_Invalid = { NULL };
- // Sync file handle invalid constant.
- static const Baselib_FileIO_SyncFile Baselib_FileIO_SyncFile_Invalid = { (void*)-1 };
- typedef enum Baselib_FileIO_OpenFlags_t
- {
- // Allows read access to the file.
- Baselib_FileIO_OpenFlags_Read = 0x01,
- // Allows write access to the file.
- Baselib_FileIO_OpenFlags_Write = 0x02,
- // Opens existing file without changes or creates 0 size file if file doesn't exist.
- // On some platforms open will implicitly add write flag if required by native API's.
- Baselib_FileIO_OpenFlags_OpenAlways = 0x04,
- // Always creates 0 size file.
- // On some platforms open will implicitly add write flag if required by native API's.
- Baselib_FileIO_OpenFlags_CreateAlways = 0x08,
- } Baselib_FileIO_OpenFlags_t;
- typedef uint32_t Baselib_FileIO_OpenFlags;
- // File IO read request.
- typedef struct Baselib_FileIO_ReadRequest
- {
- // Offset in a file to read from.
- // If offset+size is pointing pass EOF, will read up to EOF bytes.
- // If offset is pointing pass EOF, will read 0 bytes.
- uint64_t offset;
- // Buffer to read to, must be available for duration of operation.
- void* buffer;
- // Size of requested read.
- // If 0 is passed will read 0 bytes and raise no error.
- uint64_t size;
- } Baselib_FileIO_ReadRequest;
- // File IO priorities.
- // First we process all requests with high priority, then with normal priority.
- // There's no round-robin, and high priority can starve normal priority.
- typedef enum Baselib_FileIO_Priority
- {
- Baselib_FileIO_Priority_Normal = 0,
- Baselib_FileIO_Priority_High = 1
- } Baselib_FileIO_Priority;
- BASELIB_ENUM_ENSURE_ABI_COMPATIBILITY(Baselib_FileIO_Priority);
- typedef enum Baselib_FileIO_EventQueue_ResultType
- {
- // Upon receiving this event, please call the provided callback with provided data argument.
- Baselib_FileIO_EventQueue_Callback = 1,
- // Result of open file operation.
- Baselib_FileIO_EventQueue_OpenFile = 2,
- // Result of read file operation.
- Baselib_FileIO_EventQueue_ReadFile = 3,
- // Result of close file operation.
- Baselib_FileIO_EventQueue_CloseFile = 4
- } Baselib_FileIO_EventQueue_ResultType;
- BASELIB_ENUM_ENSURE_ABI_COMPATIBILITY(Baselib_FileIO_EventQueue_ResultType);
- typedef void (*EventQueueCallback)(uint64_t userdata);
- typedef struct Baselib_FileIO_EventQueue_Result_Callback
- {
- // Please invoke this callback with userdata from the event.
- EventQueueCallback callback;
- } Baselib_FileIO_EventQueue_Result_Callback;
- typedef struct Baselib_FileIO_EventQueue_Result_OpenFile
- {
- // Size of the file as seen on during open.
- uint64_t fileSize;
- } Baselib_FileIO_EventQueue_Result_OpenFile;
- typedef struct Baselib_FileIO_EventQueue_Result_ReadFile
- {
- // Bytes transferred during read.
- uint64_t bytesTransferred;
- } Baselib_FileIO_EventQueue_Result_ReadFile;
- // Event queue result.
- typedef struct Baselib_FileIO_EventQueue_Result
- {
- // Event type.
- Baselib_FileIO_EventQueue_ResultType type;
- // Userdata as provided to the request.
- uint64_t userdata;
- // Error state of the operation.
- Baselib_ErrorState errorState;
- union
- {
- Baselib_FileIO_EventQueue_Result_Callback callback;
- Baselib_FileIO_EventQueue_Result_OpenFile openFile;
- Baselib_FileIO_EventQueue_Result_ReadFile readFile;
- };
- } Baselib_FileIO_EventQueue_Result;
- // Creates event queue.
- //
- // \returns Event queue.
- BASELIB_API Baselib_FileIO_EventQueue Baselib_FileIO_EventQueue_Create(void);
- // Frees event queue.
- //
- // \param eq event queue to free.
- BASELIB_API void Baselib_FileIO_EventQueue_Free(
- Baselib_FileIO_EventQueue eq
- );
- // Dequeue events from event queue.
- //
- // \param eq Event queue to dequeue from.
- // \param results Results array to dequeue elements into.
- // If null will return 0.
- // \param count Amount of elements in results array.
- // If equals 0 will return 0.
- // \param timeoutInMilliseconds If no elements are present in the queue,
- // waits for any elements to be appear for specified amount of time.
- // If 0 is passed, wait is omitted.
- // If elements are present, dequeues up-to-count elements, and wait is omitted.
- //
- // File operations errors are reported via Baselib_FileIO_EventQueue_Result::errorState
- // Possible error codes:
- // - InvalidPathname: Requested pathname is invalid (not found, a directory, etc).
- // - RequestedAccessIsNotAllowed: Access to requested pathname is not allowed.
- // - IOError: IO error occured.
- //
- // \returns Amount of results filled.
- BASELIB_API uint64_t Baselib_FileIO_EventQueue_Dequeue(
- Baselib_FileIO_EventQueue eq,
- Baselib_FileIO_EventQueue_Result results[],
- uint64_t count,
- uint32_t timeoutInMilliseconds // 0 will return immediately
- );
- // Request dequeue to shutdown
- //
- // \param eq Event queue to shutdown.
- // \param threadCount Number of threads to signal termination
- //
- // An empty queue will hang in Baselib_FileIO_EventQueue_Dequeue for as long as the timeout lasts.
- // This function can be used to exit such a condition
- BASELIB_API void Baselib_FileIO_EventQueue_Shutdown(
- Baselib_FileIO_EventQueue eq,
- uint32_t threadCount
- );
- // Asynchronously opens a file.
- //
- // \param eq Event queue to associate file with.
- // File can only be associated with one event queue,
- // but one event queue can be associated with multiple files.
- // If invalid event queue is passed, will return invalid file handle.
- // \param pathname Platform defined pathname of a file.
- // Can be freed after this function returns.
- // If null is passed will return invalid file handle.
- // \param userdata Userdata to be set in the completion event.
- // \param priority Priority for file opening operation.
- //
- // Please note errors are reported via Baselib_FileIO_EventQueue_Result::errorState
- // Possible error codes:
- // - InvalidPathname: Requested pathname is invalid (not found, a directory, etc).
- // - RequestedAccessIsNotAllowed: Access to requested pathname is not allowed.
- // - IOError: IO error occured.
- //
- // \returns Async file handle, which can be used immediately for scheduling other operations.
- // In case if file opening fails, all scheduled operations will fail as well.
- // In case if invalid arguments are passed, might return invalid file handle (see args descriptions).
- BASELIB_API Baselib_FileIO_AsyncFile Baselib_FileIO_AsyncOpen(
- Baselib_FileIO_EventQueue eq,
- const char* pathname,
- uint64_t userdata,
- Baselib_FileIO_Priority priority
- );
- // Asynchronously reads data from a file.
- //
- // Note scheduling reads on closed file is undefined.
- //
- // \param file Async file to read from.
- // If invalid file handle is passed, will no-op.
- // If file handle was already closed, behavior is undefined.
- // \param requests Requests to schedule.
- // If more than 1 provided,
- // will provide completion event per individual request in the array.
- // If null is passed, will no-op.
- // \param count Amount of requests in requests array.
- // If 0 is passed, will no-op.
- // \param userdata Userdata to be set in the completion event(s).
- // \param priority Priority for file reading operation(s).
- //
- // Please note errors are reported via Baselib_FileIO_EventQueue_Result::errorState
- // If file is invalid handle, error can not be reported because event queue is not known.
- // Possible error codes:
- // - IOError: IO error occured.
- BASELIB_API void Baselib_FileIO_AsyncRead(
- Baselib_FileIO_AsyncFile file,
- Baselib_FileIO_ReadRequest requests[],
- uint64_t count,
- uint64_t userdata,
- Baselib_FileIO_Priority priority
- );
- // Asynchronously closes a file.
- //
- // Will wait for all pending operations to complete,
- // after that will close a file and put a completion event.
- //
- // \param file Async file to close.
- // If invalid file handle is passed, will no-op.
- //
- // Please note errors are reported via Baselib_FileIO_EventQueue_Result::errorState
- // If file is invalid handle, error can not be reported because event queue is not known.
- // Possible error codes:
- // - IOError: IO error occured.
- BASELIB_API void Baselib_FileIO_AsyncClose(
- Baselib_FileIO_AsyncFile file
- );
- // Synchronously opens a file.
- //
- // Will try use the most open access permissions options that are available for each platform.
- // Meaning it might be possible for other process to write to file opened via this API.
- // On most platforms file can be simultaneously opened with different open flags.
- // If you require more strict options, or platform specific access configuration, please use Baselib_FileIO_SyncFileFromNativeHandle.
- //
- // \param pathname Platform defined pathname to open.
- // \param openFlags Open flags.
- // If file is created because one of Create flags is passed, it will have size of 0 bytes.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - RequestedAccessIsNotAllowed: Request access is not allowed.
- // - IOError: Generic IO error occured.
- //
- // \returns SyncFile handle.
- BASELIB_API Baselib_FileIO_SyncFile Baselib_FileIO_SyncOpen(
- const char* pathname,
- Baselib_FileIO_OpenFlags openFlags,
- Baselib_ErrorState* errorState
- );
- // Transfer ownership of native handle to Baselib_FileIO_SyncFile handle.
- //
- // This function transfers ownership, meaning you don't need to close native handle yourself,
- // instead returned SyncFile must closed via Baselib_FileIO_SyncClose.
- // Implementations might cache information about the file state,
- // so native handle shouldn't be used after transfering ownership.
- //
- // \param handle Platform defined native handle.
- // If invalid native handle is passed, will return Baselib_FileIO_SyncFile_Invalid.
- // \param type Platform defined native handle type from Baselib_FileIO_NativeHandleType enum.
- // If unsupported type is passed, will return Baselib_FileIO_SyncFile_Invalid.
- //
- // \returns SyncFile handle.
- BASELIB_API Baselib_FileIO_SyncFile Baselib_FileIO_SyncFileFromNativeHandle(
- uint64_t handle,
- uint32_t type
- );
- // Synchronously reads data from a file.
- //
- // \param file File to read from.
- // If invalid file handle is passed, will raise InvalidArgument error and return 0.
- // \param offset Offset in the file to read data at.
- // If offset+size goes past end-of-file (EOF), function will read until EOF.
- // If offset points past EOF, will return 0.
- // \param buffer Pointer to data to read into.
- // \param size Size of data to read.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - IOError: Generic IO error occured.
- //
- // \returns Amount of bytes read.
- BASELIB_API uint64_t Baselib_FileIO_SyncRead(
- Baselib_FileIO_SyncFile file,
- uint64_t offset,
- void* buffer,
- uint64_t size,
- Baselib_ErrorState* errorState
- );
- // Synchronously writes data to a file.
- //
- // \param file File to write to.
- // If invalid file handle is passed, will raise InvalidArgument error and return 0.
- // \param offset Offset in the file to write data at.
- // If offset+size goes past end-of-file (EOF), then file will be resized.
- // \param buffer Pointer to data to write.
- // \param size Size of data to write.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - IOError: Generic IO error occured.
- //
- // \returns Amount of bytes written.
- BASELIB_API uint64_t Baselib_FileIO_SyncWrite(
- Baselib_FileIO_SyncFile file,
- uint64_t offset,
- const void* buffer,
- uint64_t size,
- Baselib_ErrorState* errorState
- );
- // Synchronously flushes file buffers.
- //
- // Operating system might buffer some write operations.
- // Flushing buffers is required to guarantee (best effort) writing data to disk.
- //
- // \param file File to flush.
- // If invalid file handle is passed, will no-op.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - IOError: Generic IO error occured.
- BASELIB_API void Baselib_FileIO_SyncFlush(
- Baselib_FileIO_SyncFile file,
- Baselib_ErrorState* errorState
- );
- // Synchronously changes file size.
- //
- // \param file File to get size of.
- // If invalid file handle is passed, will raise invalid argument error.
- // \param size New file size.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - IOError: Generic IO error occured.
- //
- // \returns File size.
- BASELIB_API void Baselib_FileIO_SyncSetFileSize(
- Baselib_FileIO_SyncFile file,
- uint64_t size,
- Baselib_ErrorState* errorState
- );
- // Synchronously retrieves file size.
- //
- // \param file File to get size of.
- // If invalid file handle is passed, will return 0.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - IOError: Generic IO error occured.
- //
- // \returns File size.
- BASELIB_API uint64_t Baselib_FileIO_SyncGetFileSize(
- Baselib_FileIO_SyncFile file,
- Baselib_ErrorState* errorState
- );
- // Synchronously closes a file.
- //
- // Close does not guarantee that the data was written to disk,
- // Please use Baselib_FileIO_SyncFlush to guarantee (best effort) that data was written to disk.
- //
- // \param file File to close.
- // If invalid file handle is passed, will no-op.
- //
- // Possible error codes:
- // - InvalidArgument: Invalid argument was passed.
- // - IOError: Generic IO error occured.
- BASELIB_API void Baselib_FileIO_SyncClose(
- Baselib_FileIO_SyncFile file,
- Baselib_ErrorState* errorState
- );
- #include <C/Baselib_FileIO.inl.h>
- #ifdef __cplusplus
- } // BASELIB_C_INTERFACE
- #endif
|