From 6fe692e91158ebb68fabcb524c106adf1bc4f957 Mon Sep 17 00:00:00 2001 From: Mikael Djurfeldt Date: Mon, 26 Feb 2001 03:06:57 +0000 Subject: [PATCH] ports.c, ports.h (scm_c_read, scm_c_write): New functions. ports.h (SCM_READ_BUFFER_EMPTY_P): New macro. --- NEWS | 19 +++++++++- libguile/ChangeLog | 6 ++++ libguile/ports.c | 89 ++++++++++++++++++++++++++++++++++++++++++++-- libguile/ports.h | 5 ++- 4 files changed, 114 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 024bed287..6666ae5fd 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ Guile NEWS --- history of user-visible changes. -*- text -*- -Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. See the end for copying conditions. Please send Guile bug reports to bug-guile@gnu.org. @@ -372,6 +372,23 @@ There is no such concept as a weak binding any more. * Changes to the scm_ interface +** New function: scm_c_read (SCM port, void *buffer, scm_sizet size) + +Used by an application to read arbitrary number of bytes from a port. +Same semantics as libc read, except that scm_c_read only returns less +than SIZE bytes if at end-of-file. + +Warning: Doesn't update port line and column counts! + +** New function: scm_c_write (SCM port, const void *ptr, scm_sizet size) + +Used by an application to write arbitrary number of bytes to an SCM +port. Similar semantics as libc write. However, unlike libc +write, scm_c_write writes the requested number of bytes and has no +return value. + +Warning: Doesn't update port line and column counts! + ** New function: scm_init_guile () In contrast to scm_boot_guile, scm_init_guile will return normally diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 271c98a48..71163e693 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,9 @@ +2001-02-23 Mikael Djurfeldt + + * ports.c, ports.h (scm_c_read, scm_c_write): New functions. + + * ports.h (SCM_READ_BUFFER_EMPTY_P): New macro. + 2001-02-24 Neil Jerram * numbers.c (scm_two_doubles, scm_sys_expt, scm_sys_atan2, diff --git a/libguile/ports.c b/libguile/ports.c index 85015d100..fd7362031 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999, 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 @@ -963,6 +963,14 @@ scm_puts (const char *s, SCM port) scm_lfwrite (s, strlen (s), port); } +/* scm_lfwrite + * + * Currently, this function has an identical implementation to + * scm_c_write. We could have turned it into a macro expanding into a + * call to scm_c_write. However, the implementation is small and + * might differ in the future. + */ + void scm_lfwrite (const char *ptr, scm_sizet size, SCM port) { @@ -978,6 +986,81 @@ scm_lfwrite (const char *ptr, scm_sizet size, SCM port) pt->rw_active = SCM_PORT_WRITE; } +/* scm_c_read + * + * Used by an application to read arbitrary number of bytes from an + * SCM port. Same semantics as libc read, except that scm_c_read only + * returns less than SIZE bytes if at end-of-file. + * + * Warning: Doesn't update port line and column counts! */ + +scm_sizet +scm_c_read (SCM port, void *buffer, scm_sizet size) +{ + scm_port *pt = SCM_PTAB_ENTRY (port); + scm_sizet n_read = 0, n_available; + + if (pt->rw_active == SCM_PORT_WRITE) + scm_ptobs[SCM_PTOBNUM (port)].flush (port); + + if (pt->rw_random) + pt->rw_active = SCM_PORT_READ; + + if (SCM_READ_BUFFER_EMPTY_P (pt)) + { + if (scm_fill_input (port) == EOF) + return 0; + } + + n_available = pt->read_end - pt->read_pos; + + while (n_available < size) + { + memcpy (buffer, pt->read_pos, n_available); + buffer += n_available; + pt->read_pos += n_available; + n_read += n_available; + + if (SCM_READ_BUFFER_EMPTY_P (pt)) + { + if (scm_fill_input (port) == EOF) + return n_read; + } + + size -= n_available; + n_available = pt->read_end - pt->read_pos; + } + + memcpy (buffer, pt->read_pos, size); + pt->read_pos += size; + + return n_read + size; +} + +/* scm_c_write + * + * Used by an application to write arbitrary number of bytes to an SCM + * port. Similar semantics as libc write. However, unlike libc + * write, scm_c_write writes the requested number of bytes and has no + * return value. + * + * Warning: Doesn't update port line and column counts! + */ + +void +scm_c_write (SCM port, const void *ptr, scm_sizet size) +{ + scm_port *pt = SCM_PTAB_ENTRY (port); + scm_ptob_descriptor *ptob = &scm_ptobs[SCM_PTOBNUM (port)]; + + if (pt->rw_active == SCM_PORT_READ) + scm_end_input (port); + + ptob->write (port, ptr, size); + + if (pt->rw_random) + pt->rw_active = SCM_PORT_WRITE; +} void scm_flush (SCM port) @@ -1199,8 +1282,8 @@ SCM_DEFINE (scm_seek, "seek", 3, 0, 0, object = SCM_COERCE_OUTPORT (object); - off = SCM_NUM2LONG (2,offset); - SCM_VALIDATE_INUM_COPY (3,whence,how); + off = SCM_NUM2LONG (2, offset); + SCM_VALIDATE_INUM_COPY (3, whence, how); if (how != SEEK_SET && how != SEEK_CUR && how != SEEK_END) SCM_OUT_OF_RANGE (3, whence); if (SCM_OPPORTP (object)) diff --git a/libguile/ports.h b/libguile/ports.h index fe2c0dc92..fabf744eb 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -2,7 +2,7 @@ #ifndef PORTSH #define PORTSH -/* Copyright (C) 1995,1996,1997,1998,1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999, 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 @@ -135,6 +135,7 @@ typedef struct extern scm_port **scm_port_table; extern int scm_port_table_size; /* Number of ports in scm_port_table. */ +#define SCM_READ_BUFFER_EMPTY_P(c_port) (c_port->read_pos >= c_port->read_end) @@ -279,6 +280,8 @@ extern SCM scm_flush_all_ports (void); extern SCM scm_read_char (SCM port); extern void scm_putc (char c, SCM port); extern void scm_puts (const char *str_data, SCM port); +extern scm_sizet scm_c_read (SCM port, void *buffer, scm_sizet size); +extern void scm_c_write (SCM port, const void *buffer, scm_sizet size); extern void scm_lfwrite (const char *ptr, scm_sizet size, SCM port); extern void scm_flush (SCM port); extern void scm_end_input (SCM port);