summaryrefslogtreecommitdiffhomepage
path: root/mixlib/mix_device.c
diff options
context:
space:
mode:
authorjaortega <jaortega>2001-03-01 23:56:08 +0000
committerjaortega <jaortega>2001-03-01 23:56:08 +0000
commit3cd180b262db4490f811aaa2f19ef7a4d00ce24f (patch)
tree95bba17660bd67204609f4916a64cb6c86f9122b /mixlib/mix_device.c
parentf20d7ac8e744fde911545618e96d52c26f008910 (diff)
downloadmdk-3cd180b262db4490f811aaa2f19ef7a4d00ce24f.tar.gz
mdk-3cd180b262db4490f811aaa2f19ef7a4d00ce24f.tar.bz2
mix device operations handled via a vtable
Diffstat (limited to 'mixlib/mix_device.c')
-rw-r--r--mixlib/mix_device.c168
1 files changed, 57 insertions, 111 deletions
diff --git a/mixlib/mix_device.c b/mixlib/mix_device.c
index 624702b..13e7150 100644
--- a/mixlib/mix_device.c
+++ b/mixlib/mix_device.c
@@ -1,7 +1,7 @@
/* -*-c-*- -------------- mix_device.c :
* Implementation of the functions declared in mix_device.h
* ------------------------------------------------------------------
- * Copyright (C) 2000 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,56 +21,14 @@
#include "mix_file.h"
-#include "mix_device.h"
-
-/*
- Actual definition of a mix device, which can be cast to
- a mix file.
-*/
-struct mix_device_t
-{
- mix_iochannel_t *file;
- mix_device_type_t type;
-};
-
-
-static const char *DEV_EXT_ = ".dev";
-
-static const char *DEF_NAMES_[] = {
- "tape0", "tape1", "tape2", "tape3", "tape4", "tape5", "tape6", "tape7",
- "disk0", "disk1", "disk2", "disk3", "disk4", "disk5", "disk6", "disk7",
- "cardrd", "cardwr", "printer", "console", "paper"
-};
-
-static const size_t SIZES_[] = {
- 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 100, 100,
- 16, 16, 24, 14, 14
-};
-
-static const mix_device_mode_t MODES_[] = {
- mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
- mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
- mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
- mix_dev_BIN, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR,
- mix_dev_CHAR
-};
-
-static const mix_fmode_t FMODES_[] = {
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_READ, mix_io_WRITE, mix_io_WRITE, mix_io_RDWRT, mix_io_WRITE
-};
-
-#define GET_CHANNEL_(dev) (dev->file)
-#define GET_FILE_(dev) ((mix_file_t *)(dev->file))
+#include "xmix_device.h"
mix_device_t *
mix_device_new (mix_device_type_t type)
{
- mix_device_t *result = g_new (mix_device_t, 1);
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
result->type = type;
if (type != mix_dev_CONSOLE) {
result->file = MIX_IOCHANNEL(mix_file_new_with_def_ext (DEF_NAMES_[type],
@@ -78,26 +36,18 @@ mix_device_new (mix_device_type_t type)
DEV_EXT_));
} else
result->file = mix_io_new (stdout);
-
+ result->vtable = DEF_DEV_VTABLE_;
return result;
}
-void
-mix_device_delete (mix_device_t *dev)
-{
- if (dev != NULL)
- {
- if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL)
- mix_file_delete (GET_FILE_(dev));
- g_free (dev);
- }
-}
+
mix_device_t *
mix_device_new_with_name (mix_device_type_t type, const gchar *name)
{
mix_device_t *result = NULL;
- g_return_val_if_fail (name != NULL, result);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
result = g_new (mix_device_t, 1);
result->type = type;
if (type != mix_dev_CONSOLE)
@@ -110,11 +60,46 @@ mix_device_new_with_name (mix_device_type_t type, const gchar *name)
{
result->file = mix_io_new (stdout);
}
+ result->vtable = DEF_DEV_VTABLE_;
return result;
}
+/*
+ Create a new device with a given type and stream
+*/
+mix_device_t *
+mix_device_new_with_file (mix_device_type_t type, FILE *file)
+{
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
+ result->type = type;
+ result->file = mix_io_new (file);
+ result->vtable = DEF_DEV_VTABLE_;
+ return result;
+}
+
+void
+mix_device_delete (mix_device_t *dev)
+{
+ if (dev != NULL)
+ {
+ if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL)
+ mix_file_delete (GET_FILE_(dev));
+ g_free (dev);
+ }
+}
+
+mix_device_type_t
+mix_device_type (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, mix_dev_INVALID);
+ return dev->type;
+}
+
const char *
-mix_device_get_name (mix_device_t *dev)
+mix_device_get_name (const mix_device_t *dev)
{
g_return_val_if_fail (dev != NULL, NULL);
return mix_file_base_name(GET_FILE_(dev));
@@ -124,7 +109,7 @@ mix_device_get_name (mix_device_t *dev)
Get the device block size
*/
size_t
-mix_device_block_size (mix_device_t *dev)
+mix_device_block_size (const mix_device_t *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return SIZES_[dev->type];
@@ -134,7 +119,7 @@ mix_device_block_size (mix_device_t *dev)
Get the device io mode
*/
mix_device_mode_t
-mix_device_mode (mix_device_t *dev)
+mix_device_mode (const mix_device_t *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return MODES_[dev->type];
@@ -146,23 +131,10 @@ mix_device_mode (mix_device_t *dev)
gboolean
mix_device_write (mix_device_t *dev, const mix_word_t *block)
{
- gboolean result;
-
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (block != NULL, FALSE);
- if (FMODES_[dev->type] == mix_io_READ) return FALSE;
- if (MODES_[dev->type] == mix_dev_CHAR)
- result = mix_io_write_word_array_as_char (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
- else
- result = mix_io_write_word_array (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
- if (result && mix_device_mode(dev) == mix_dev_CHAR)
- putc ('\n', mix_io_to_FILE (GET_CHANNEL_ (dev)));
-
- fflush (mix_io_to_FILE (GET_CHANNEL_ (dev)));
-
- return result;
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->write) (dev, block);
}
gboolean
@@ -170,48 +142,22 @@ mix_device_read (mix_device_t *dev, mix_word_t *block)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (block != NULL, FALSE);
- if (FMODES_[dev->type] == mix_io_WRITE) return FALSE;
- if (MODES_[dev->type] == mix_dev_CHAR)
- return mix_io_read_word_array_as_char (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
- else
- return mix_io_read_word_array (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->read) (dev, block);
}
gboolean
mix_device_ioc (mix_device_t *dev, mix_short_t arg)
{
- int m;
- FILE *file;
-
g_return_val_if_fail (dev != NULL, FALSE);
-
- m = mix_short_magnitude(arg);
- if (mix_short_is_negative(arg)) m = -m;
- m *= sizeof (mix_word_t) * SIZES_[dev->type];
- file = mix_io_to_FILE (GET_CHANNEL_(dev));
-
- if (dev->type >= mix_dev_TAPE_0 && dev->type <= mix_dev_TAPE_7)
- {
- if (m == 0) rewind (file);
- else fseek (file, m, SEEK_CUR);
- }
- if (dev->type >= mix_dev_DISK_0 && dev->type <= mix_dev_DISK_7)
- {
- g_return_val_if_fail (m == 0, FALSE);
- // position disk
- }
- if (dev->type == mix_dev_PAPER_TAPE)
- {
- g_return_val_if_fail (m == 0, FALSE);
- rewind (file);
- }
- return TRUE;
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->ioc) (dev, arg);
}
gboolean
-mix_device_busy (mix_device_t *dev)
+mix_device_busy (const mix_device_t *dev)
{
- return (dev != NULL && !mix_io_is_ready(GET_CHANNEL_(dev)));
+ g_return_val_if_fail (dev != NULL, FALSE);
+ return (dev->vtable->busy) (dev);
+
}