aboutsummaryrefslogtreecommitdiff
path: root/src/IO.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/IO.c')
-rw-r--r--src/IO.c249
1 files changed, 97 insertions, 152 deletions
diff --git a/src/IO.c b/src/IO.c
index 2b2b302..caca243 100644
--- a/src/IO.c
+++ b/src/IO.c
@@ -5,231 +5,176 @@
#define BUFFER_SIZE (sizeof(char *))
-struct BH_IO
-{
- BH_IOCallback cb;
-};
-
-
-BH_IO *BH_IONew(BH_IOCallback cb,
- void *data)
-{
- size_t requested;
- BH_IO *io;
-
- /* Get information about IO device size */
- if (cb(NULL, BH_IO_INFO_CB, &requested, NULL))
- return NULL;
-
- /* Allocate space for the IO device */
- io = malloc(sizeof(*io) + requested);
- if (!io)
- return NULL;
-
- /* Initialize IO device */
- io->cb = cb;
- if (cb(io + 1, BH_IO_INIT_CB, data, NULL))
- {
- free(io);
- return NULL;
- }
-
- return io;
-}
-
-
-void BH_IOFree(BH_IO *io)
+void BH_IOFree(BH_IO *device)
{
/* Prevent working with NULL io */
- if (!io)
+ if (!device)
return;
- /* Call the IO device destruction handler */
- io->cb(io + 1, BH_IO_DESTROY_CB, NULL, NULL);
-
- /* Deallocate object */
- free(io);
+ /* Call the IO device destruction handler and deallocate */
+ device->callback(device, BH_IO_OP_DESTROY, NULL);
}
-const char *BH_IOClassname(BH_IO *io)
+int BH_IORead(BH_IO *device,
+ char *buffer,
+ size_t size,
+ size_t *actual)
{
- const char *name;
-
- if (!io)
- goto error;
+ BH_IOReadInfo info;
- if (io->cb(io + 1, BH_IO_INFO_CB, NULL, &name) != BH_OK)
- goto error;
-
- return name;
-
-error:
- return NULL;
-}
-
-
-int BH_IOOpen(BH_IO *io,
- int mode)
-{
/* Prevent working with NULL io */
- if (!io)
+ if (!device)
return BH_ERROR;
- /* Call the IO device open handler with specified mode */
- return io->cb(io + 1, BH_IO_OPEN_CB, &mode, NULL);
+ info.data = buffer;
+ info.size = size;
+ info.actual = actual;
+ return device->callback(device, BH_IO_OP_READ, &info);
}
-int BH_IOClose(BH_IO *io)
+int BH_IOWrite(BH_IO *device,
+ const char *buffer,
+ size_t size,
+ size_t *actual)
{
+ BH_IOWriteInfo info;
+
/* Prevent working with NULL io */
- if (!io)
+ if (!device)
return BH_ERROR;
- /* Call the IO device close handler */
- return io->cb(io + 1, BH_IO_CLOSE_CB, NULL, NULL);
+ info.data = buffer;
+ info.size = size;
+ info.actual = actual;
+
+ return device->callback(device, BH_IO_OP_WRITE, &info);
}
-int BH_IORead(BH_IO *io,
- char *buffer,
- size_t size,
- size_t *actual)
+int BH_IOCtl(BH_IO *device,
+ int op,
+ void *arg)
{
- int code;
+ BH_IOCtlInfo info;
- /* Prevent working with NULL io */
- if (!io)
+ if (!device)
return BH_ERROR;
- /* Call the IO device read handler */
- code = io->cb(io + 1, BH_IO_READ_CB, buffer, &size);
-
- /* If caller wants to know actual read size - report it back */
- if (actual)
- *actual = size;
-
- return code;
+ info.op = op;
+ info.arg = arg;
+ return device->callback(device, BH_IO_OP_CTL, &info);
}
-int BH_IOWrite(BH_IO *io,
- const char *buffer,
- size_t size,
- size_t *actual)
+int BH_IOCap(BH_IO *device,
+ int op)
{
- int code;
-
- /* Prevent working with NULL io */
- if (!io)
+ if (!device)
return BH_ERROR;
- /* Call the IO device write handler */
- code = io->cb(io + 1, BH_IO_WRITE_CB, (void *)buffer, &size);
-
- /* If caller wants to know actual written size - report it back */
- if (actual)
- *actual = size;
-
- return code;
+ return device->callback(device, BH_IO_OP_CAP, &op);
}
-int BH_IOPeek(BH_IO *io,
+int BH_IOPeek(BH_IO *device,
char *buffer,
size_t size,
size_t *actual)
{
- int code;
+ BH_IOReadInfo readInfo;
+ BH_IOSeekInfo posInfo;
+ size_t readed;
- /* Prevent working with NULL io */
- if (!io)
- return BH_ERROR;
+ readInfo.data = buffer;
+ readInfo.size = size;
+ readInfo.actual = actual;
+
+ if (BH_IOCap(device, BH_IO_CTL_PEEK))
+ {
+ if (BH_IOCap(device, BH_IO_CTL_SEEK))
+ return BH_NOIMPL;
+
+ if (BH_IORead(device, buffer, size, &readed))
+ return BH_ERROR;
+
+ posInfo.whence = BH_IO_SEEK_CUR;
+ posInfo.offset = -(int64_t)readed;
+ if (BH_IOCtl(device, BH_IO_CTL_SEEK, &posInfo))
+ return BH_ERROR;
- /* Call the IO device peek handler */
- code = io->cb(io + 1, BH_IO_PEEK_CB, (void *)buffer, &size);
+ if (actual)
+ *actual = readed;
- /* If caller wants to know actual written size - report it back */
- if (actual)
- *actual = size;
+ return BH_OK;
+ }
- return code;
+ return BH_IOCtl(device, BH_IO_CTL_PEEK, &readInfo);
}
-int BH_IOTell(BH_IO *io,
- int64_t *position)
+int BH_IOTell(BH_IO *device,
+ int64_t *offset)
{
- /* Prevent working with NULL io */
- if (!io)
- return BH_ERROR;
-
- /* Call the IO device tell handler */
- return io->cb(io + 1, BH_IO_TELL_CB, position, NULL);
+ return BH_IOCtl(device, BH_IO_CTL_TELL, offset);
}
-int BH_IOSeek(BH_IO *io,
- int64_t position,
- int direction)
+int BH_IOSeek(BH_IO *device,
+ int64_t offset,
+ int whence)
{
- /* Prevent working with NULL io */
- if (!io)
- return BH_ERROR;
+ BH_IOSeekInfo info;
- /* Call the IO device seek handler */
- return io->cb(io + 1, BH_IO_SEEK_CB, &position, &direction);
+ info.offset = offset;
+ info.whence = whence;
+ return BH_IOCtl(device, BH_IO_CTL_SEEK, &info);
}
-int BH_IOFlush(BH_IO *io)
+int BH_IOFlush(BH_IO *device)
{
- /* Prevent working with NULL io */
- if (!io)
- return BH_ERROR;
-
- /* Call the IO device flush handler */
- return io->cb(io + 1, BH_IO_FLUSH_CB, NULL, NULL);
+ return BH_IOCtl(device, BH_IO_CTL_FLUSH, NULL);
}
-int BH_IOSize(BH_IO *io,
+int BH_IOSize(BH_IO *device,
int64_t *size)
{
- /* Prevent working with NULL io */
- if (!io)
- return BH_ERROR;
-
- /* Call the IO device size handler */
- return io->cb(io + 1, BH_IO_SIZE_CB, size, NULL);
+ return BH_IOCtl(device, BH_IO_CTL_SIZE, size);
}
-int BH_IOFlags(BH_IO *io)
+int BH_IOFlags(BH_IO *device, int *flags)
{
- /* Prevent working with NULL io */
- if (!io)
- return BH_IO_FLAG_ERROR;
+ return BH_IOCtl(device, BH_IO_CTL_FLAGS, flags);
+}
- /* Call the IO device flags handler */
- return io->cb(io + 1, BH_IO_FLAGS_CB, NULL, NULL);
+
+int BH_IOClear(BH_IO *device)
+{
+ return BH_IOCtl(device, BH_IO_CTL_CLEAR, NULL);
}
-int BH_IOClear(BH_IO *io)
+int BH_IOError(BH_IO *device)
{
- /* Prevent working with NULL io */
- if (!io)
- return BH_OK;
+ int flags;
- /* Call the IO device clear error handler */
- return io->cb(io + 1, BH_IO_CLEAR_CB, NULL, NULL);
+ if (BH_IOFlags(device, &flags))
+ return BH_ERROR;
+
+ return flags & BH_IO_FLAG_ERROR;
}
-BH_IO *BH_BufferNew(BH_IO *io)
+int BH_IOEndOfFile(BH_IO *device)
{
- (void)io;
- return NULL;
+ int flags;
+
+ if (BH_IOFlags(device, &flags))
+ return BH_ERROR;
+
+ return flags & BH_IO_FLAG_EOF;
}