From 3cd180b262db4490f811aaa2f19ef7a4d00ce24f Mon Sep 17 00:00:00 2001 From: jaortega Date: Thu, 1 Mar 2001 23:56:08 +0000 Subject: mix device operations handled via a vtable --- mixlib/mix_device.c | 168 ++++++++++++++++++---------------------------------- 1 file changed, 57 insertions(+), 111 deletions(-) (limited to 'mixlib/mix_device.c') 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); + } -- cgit v1.2.3