Refactor IO, add buffered IO

I wasn't happy with existing implementation of the IO, so I decided
to change it - as a result there is no longer BH_IOOpen and BH_IOClose
and many IO operations are now optional (behind BH_IOCtl).

Finnally implemented buffered IO and fixed size memory buffer IO.
This commit is contained in:
2025-04-26 07:50:13 +03:00
parent 48ddd91dd4
commit 1b6c858a1b
16 changed files with 1473 additions and 1122 deletions

View File

@@ -5,130 +5,139 @@
#include "Common.h"
#define BH_IO_INFO_CB 0x0000
#define BH_IO_INIT_CB 0x0001
#define BH_IO_DESTROY_CB 0x0002
#define BH_IO_OPEN_CB 0x0003
#define BH_IO_CLOSE_CB 0x0004
#define BH_IO_READ_CB 0x0005
#define BH_IO_WRITE_CB 0x0006
#define BH_IO_PEEK_CB 0x0007
#define BH_IO_TELL_CB 0x0008
#define BH_IO_SEEK_CB 0x0009
#define BH_IO_FLUSH_CB 0x000A
#define BH_IO_SIZE_CB 0x000B
#define BH_IO_FLAGS_CB 0x000C
#define BH_IO_CLEAR_CB 0x000D
#define BH_IO_OP_DESTROY 0x0000
#define BH_IO_OP_READ 0x0001
#define BH_IO_OP_WRITE 0x0002
#define BH_IO_OP_CTL 0x0003
#define BH_IO_OP_CAP 0x0004
#define BH_IO_READ 0x0001
#define BH_IO_WRITE 0x0002
#define BH_IO_READWRITE 0x0003
#define BH_IO_APPEND 0x0010
#define BH_IO_TRUNCATE 0x0020
#define BH_IO_CREATE 0x0040
#define BH_IO_EXIST 0x0080
#define BH_IO_CTL_FLAGS 0x0000
#define BH_IO_CTL_CLEAR 0x0001
#define BH_IO_CTL_PEEK 0x0002
#define BH_IO_CTL_FLUSH 0x0003
#define BH_IO_CTL_SIZE 0x0004
#define BH_IO_CTL_TELL 0x0005
#define BH_IO_CTL_SEEK 0x0006
#define BH_IO_CTL_GET_IO 0x0007
#define BH_IO_CTL_SET_IO 0x0008
#define BH_IO_SEEK_SET 0x0000
#define BH_IO_SEEK_CUR 0x0001
#define BH_IO_SEEK_END 0x0002
#define BH_IO_SEEK_SET 0x0000
#define BH_IO_SEEK_CUR 0x0001
#define BH_IO_SEEK_END 0x0002
#define BH_IO_FLAG_OK 0x0000
#define BH_IO_FLAG_ERROR 0x0001
#define BH_IO_FLAG_EOF 0x0002
#define BH_IO_FLAG_OPEN 0x0004
#define BH_FILE_CLASSNAME "BH_File"
#define BH_IO_FLAG_OK 0x0000
#define BH_IO_FLAG_ERROR 0x0001
#define BH_IO_FLAG_EOF 0x0002
typedef struct BH_IO BH_IO;
typedef int (*BH_IOCallback)(void *, int ,void *, void *);
#define BH_FILE_READ 0x0001
#define BH_FILE_WRITE 0x0002
#define BH_FILE_READWRITE 0x0003
#define BH_FILE_APPEND 0x0010
#define BH_FILE_TRUNCATE 0x0020
#define BH_FILE_CREATE 0x0040
#define BH_FILE_EXIST 0x0080
typedef int (*BH_IOCallback)(void *, int, void *);
typedef struct BH_IO
{
BH_IOCallback callback;
} BH_IO;
typedef struct BH_IOReadInfo
{
char *data;
size_t size;
size_t *actual;
} BH_IOReadInfo;
typedef struct BH_IOWriteInfo
{
const char *data;
size_t size;
size_t *actual;
} BH_IOWriteInfo;
typedef struct BH_IOCtlInfo
{
int op;
void *arg;
} BH_IOCtlInfo;
typedef struct BH_IOSeekInfo
{
int64_t offset;
int whence;
} BH_IOSeekInfo;
/**
* Creates the IO that represents file with the given \a path.
* Creates an input/output device representing a file at the given \a path.
*
* \param path File path
* \param path File path
* \param mode Open mode
* \param result Result code
*
* \return On success, returns IO pointer.
* \return On success, returns IO device pointer.
* \return On failure, returns NULL pointer.
*/
BH_IO *BH_FileNew(const char *path);
BH_IO *BH_FileNew(const char *path,
int mode,
int *result);
/**
* Creates the IO that buffers access to other \a io.
* Creates an input/output deivce that buffers access to other \a device.
*
* \param io IO pointer
* \param device IO device pointer
* \param size Buffer size
* \param result Result code
*
* \return On success, returns IO pointer.
* \return On success, returns IO device pointer.
* \return On failure, returns NULL pointer.
*/
BH_IO *BH_BufferNew(BH_IO *io);
BH_IO *BH_BufferNew(BH_IO *device,
size_t size,
int *result);
/**
* Creates the IO with specified callback \a cb and \a data.
* Creates an input/output devices that access memory buffer.
*
* \param cb Callback
* \param data Initialization data
* \param data Buffer pointer
* \param size Buffer size
* \param result Result code
*
* \return On success, returns IO pointer.
* \return On success, returns IO device pointer.
* \return On failure, returns NULL pointer.
*/
BH_IO *BH_IONew(BH_IOCallback cb,
void *data);
BH_IO *BH_BytesNew(char *data,
size_t size,
int *result);
/**
* Destroys the \a io.
* Destroys the input/output \a device.
*
* \param io IO pointer
* \param device IO device pointer
*/
void BH_IOFree(BH_IO *io);
void BH_IOFree(BH_IO *device);
/**
* Returns the \a io classname.
* Reads up to \a size bytes from the \a device into \a buffer.
*
* \param io IO pointer
*
* \return On success, returns pointer to constant string.
* \return On failure, returns NULL pointer
*/
const char *BH_IOClassname(BH_IO* io);
/**
* Opens the \a io in specified \a mode of operation.
*
* \param io IO pointer
* \param mode Mode of operation
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOOpen(BH_IO *io,
int mode);
/**
* Closes the \a io.
*
* \param io IO pointer
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOClose(BH_IO *io);
/**
* Reads up to \a size bytes from the \a io into \a buffer.
*
* \param io IO pointer
* \param device IO device pointer
* \param buffer Buffer pointer
* \param size Buffer size
* \param actual Bytes read (optional)
@@ -136,16 +145,16 @@ int BH_IOClose(BH_IO *io);
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IORead(BH_IO *io,
int BH_IORead(BH_IO *device,
char *buffer,
size_t size,
size_t *actual);
/**
* Writes up to \a size bytes to the \a io from \a buffer.
* Writes up to \a size bytes to the \a device from \a buffer.
*
* \param io IO pointer
* \param io IO device pointer
* \param buffer Buffer pointer
* \param size Buffer size
* \param actual Bytes written (optional)
@@ -160,9 +169,37 @@ int BH_IOWrite(BH_IO *io,
/**
* Peeks up to \a size bytes from \a io into \a buffer.
* Manupulates an input/output \a device with specific \a op and and \a arg.
*
* \param io IO pointer
* \param device IO device pointer
* \param op Operation
* \param arg Argument
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOCtl(BH_IO *device,
int op,
void *arg);
/**
* Checks if an input/output \a device supports specific \a op.
*
* \param device IO device pointer
* \param op Operation
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOCap(BH_IO *device,
int op);
/**
* Peeks up to \a size bytes from the \a device into \a buffer.
*
* \param device IO device pointer
* \param buffer Buffer pointer
* \param size Buffer size
* \param actial Bytes peeked (optional)
@@ -170,83 +207,106 @@ int BH_IOWrite(BH_IO *io,
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOPeek(BH_IO *io,
int BH_IOPeek(BH_IO *device,
char *buffer,
size_t size,
size_t *actual);
/**
* Tells current \a position in the \a io.
* Tells current \a offset in the \a device.
*
* \param io IO pointer
* \param position Position
* \param device IO device pointer
* \param offset Position
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOTell(BH_IO *io,
int64_t *position);
int BH_IOTell(BH_IO *device,
int64_t *offset);
/**
* Seeks to specified \a position and \a direction in the \a io.
* Seeks to specified \a offset and \a whence in the \a device.
*
* \param io IO pointer
* \param position Position
* \param direction Direction
* \param device IO device pointer
* \param offset Position
* \param whence Direction
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOSeek(BH_IO *io,
int64_t position,
int direction);
int BH_IOSeek(BH_IO *device,
int64_t offset,
int whence);
/**
* Flushes the internal buffers of the \a io.
* Flushes the internal buffers of the \a device.
*
* \param io IO pointer
* \param device IO device pointer
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOFlush(BH_IO *io);
int BH_IOFlush(BH_IO *device);
/**
* Returns total or available size of the \a io.
* Returns total or available size of the \a device.
*
* \param io IO pointer
* \param size Available/total size
* \param device IO pointer
* \param size Available/total size
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOSize(BH_IO *io,
int BH_IOSize(BH_IO *device,
int64_t *size);
/**
* Returns flags of the \a io.
* Returns flags of the \a device.
*
* \param io IO pointer
*
* \return Flags of the IO
*/
int BH_IOFlags(BH_IO *io);
/**
* Clears errors of the \a io.
*
* \param io IO pointer
* \param device IO device pointer
* \param flags Flags
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOClear(BH_IO *io);
int BH_IOFlags(BH_IO *device,
int *flags);
/**
* Returns error flag of the \a device.
*
* \param device IO device pointer
*
* \return Returns error flag.
*/
int BH_IOError(BH_IO *device);
/**
* Returns end-of-file flag of the \a device.
*
* \param device IO device pointer
*
* \return Returns end-of-file flag.
*/
int BH_IOEndOfFile(BH_IO *device);
/**
* Clears errors of the \a device.
*
* \param device IO device pointer
*
* \return On success, returns zero.
* \return On failure, returns error code.
*/
int BH_IOClear(BH_IO *device);
#endif /* BH_IO_H */