cvsuser 02/06/07 17:11:20
Modified: include/parrot io.h
io io.c
config/gen/makefiles root.in
Added: io io_buf.c
Removed: io io_stdio.c
Log:
Renamed io_stdio to io_buf.
Revision Changes Path
1.20 +2 -2 parrot/include/parrot/io.h
Index: io.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/io.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -w -r1.19 -r1.20
--- io.h 2 Jun 2002 21:15:37 -0000 1.19
+++ io.h 8 Jun 2002 00:11:17 -0000 1.20
@@ -1,7 +1,7 @@
/* io.h
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: io.h,v 1.19 2002/06/02 21:15:37 mrjoltcola Exp $
+ * $Id: io.h,v 1.20 2002/06/08 00:11:17 josh Exp $
* Overview:
* Parrot IO subsystem
* Data Structure and Algorithms:
@@ -164,7 +164,7 @@
#else
extern ParrotIOLayer pio_win32_layer;
#endif
-extern ParrotIOLayer pio_stdio_layer;
+extern ParrotIOLayer pio_buf_layer;
/* This is list of valid layers */
extern ParrotIOLayer *pio_registered_layers;
1.24 +3 -3 parrot/io/io.c
Index: io.c
===================================================================
RCS file: /cvs/public/parrot/io/io.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -w -r1.23 -r1.24
--- io.c 2 Jun 2002 21:16:39 -0000 1.23
+++ io.c 8 Jun 2002 00:11:19 -0000 1.24
@@ -1,11 +1,11 @@
/* io.c
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: io.c,v 1.23 2002/06/02 21:16:39 mrjoltcola Exp $
+ * $Id: io.c,v 1.24 2002/06/08 00:11:19 josh Exp $
* Overview:
* This is the Parrot IO subsystem API. Generic IO stuff
* goes here, each specific layer goes in its own file...
- * (io_unix, io_win32, io_stdio, io_utf8, etc.)
+ * (io_unix, io_win32, io_buf, io_stdio, io_utf8, etc.)
* Data Structure and Algorithms:
* Uses the IO PMC defined in io.h
* Uses ParrotIO structs in io.h
@@ -166,7 +166,7 @@
PIO_push_layer(interpreter, PIO_base_new_layer(&pio_win32_layer), NULL);
#endif
#if 0
- PIO_push_layer(interpreter, PIO_base_new_layer(&pio_stdio_layer), NULL);
+ PIO_push_layer(interpreter, PIO_base_new_layer(&pio_buf_layer), NULL);
#endif
/* Note: All layer pushes should be done before init calls */
1.1 parrot/io/io_buf.c
Index: io_buf.c
===================================================================
/* io_buf.c
* Copyright: (When this is determined...it will go here)
* CVS Info
* $Id: io_buf.c,v 1.1 2002/06/08 00:11:19 josh Exp $
* Overview:
* The "buf" layer of Parrot IO. Buffering and all the fun stuff.
*
* Data Structure and Algorithms:
* History:
* Initially written by Melvin Smith
* Notes:
* References:
* Some ideas from AT&T SFIO
*/
#include "parrot/parrot.h"
/* Defined at bottom */
extern ParrotIOLayerAPI pio_buf_layer_api;
ParrotIOLayer pio_buf_layer = {
NULL,
"buf",
PIO_L_TERMINAL,
&pio_buf_layer_api,
0, 0
};
/*
* Currently keeping layer prototypes local to each layer
* file.
*/
INTVAL PIO_buf_init(theINTERP, ParrotIOLayer *l);
ParrotIO *PIO_buf_open(theINTERP, ParrotIOLayer *l,
const char *path, INTVAL flags);
INTVAL PIO_buf_setbuf(theINTERP, ParrotIOLayer *l,
ParrotIO *io, size_t bufsize);
INTVAL PIO_buf_setlinebuf(theINTERP, ParrotIOLayer *l, ParrotIO *io);
ParrotIO *PIO_buf_fdopen(theINTERP, ParrotIOLayer *l,
PIOHANDLE fd, INTVAL flags);
INTVAL PIO_buf_close(theINTERP, ParrotIOLayer *l, ParrotIO *io);
void PIO_buf_flush(theINTERP, ParrotIOLayer *l, ParrotIO *io);
size_t PIO_buf_read(theINTERP, ParrotIOLayer *l,
ParrotIO *io, void *buffer, size_t len);
size_t PIO_buf_write(theINTERP, ParrotIOLayer *l,
ParrotIO *io, const void *buffer, size_t len);
INTVAL PIO_buf_puts(theINTERP, ParrotIOLayer *l, ParrotIO *io,
const char *s);
INTVAL PIO_buf_seek(theINTERP, ParrotIOLayer *l, ParrotIO *io,
INTVAL hi, INTVAL lo, INTVAL whence);
PIOOFF_T PIO_buf_tell(theINTERP, ParrotIOLayer *l, ParrotIO *io);
/* Local util functions */
size_t PIO_buf_writethru(theINTERP, ParrotIOLayer *layer,
ParrotIO *io, const void *buffer, size_t len);
INTVAL
PIO_buf_init(theINTERP, ParrotIOLayer *layer)
{
if (PIO_STDOUT(interpreter))
PIO_buf_setlinebuf(interpreter, layer, PIO_STDOUT(interpreter));
if (PIO_STDIN(interpreter))
PIO_buf_setbuf(interpreter, layer, PIO_STDIN(interpreter),
PIO_UNBOUND);
return 0;
}
ParrotIO *
PIO_buf_open(theINTERP, ParrotIOLayer *layer,
const char *path, INTVAL flags)
{
ParrotIO *io;
ParrotIOLayer *l = layer;
while (l) {
if (l->api->Open) {
io = (*l->api->Open) (interpreter, l, path, flags);
/*
* We have an IO stream now setup stuff
* for our layer before returning it.
*/
PIO_buf_setbuf(interpreter, l, io, PIO_UNBOUND);
return io;
}
l = PIO_DOWNLAYER(l);
}
return NULL;
}
/*
* Don't pass setbuf() calls down the stack, top layer wins.
* This doesn't mean other layers can't buffer, I just to
* think about the mechanism for buffer control or if it even
* makes sense this way. Most layers will not implement setbuf()...
*/
INTVAL
PIO_buf_setbuf(theINTERP, ParrotIOLayer *layer, ParrotIO *io, size_t bufsize)
{
ParrotIOLayer *l = layer;
ParrotIOBuf *b = &io->b;
/* If there is a buffer, make sure we flush before
* dinking around with the buffer.
*/
if (b->startb)
PIO_buf_flush(interpreter, l, io);
/* Choose an appropriate buffer size for caller */
if (bufsize == PIO_UNBOUND) {
b->size = PIO_getblksize(io->fd);
}
else {
b->size = (bufsize >= PIO_GRAIN ? bufsize : PIO_GRAIN);
}
if (b->startb && (b->flags & PIO_BF_MALLOC)) {
free(b->startb);
b->startb = b->next = NULL;
}
if (b->size > 0) {
b->startb = b->next = malloc(b->size);
b->flags |= PIO_BF_MALLOC;
}
if (bufsize != 0)
io->flags |= PIO_F_BLKBUF;
else
io->flags &= ~(PIO_F_BLKBUF | PIO_F_LINEBUF);
return 0;
}
INTVAL
PIO_buf_setlinebuf(theINTERP, ParrotIOLayer *l, ParrotIO *io)
{
/* Reuse setbuf call */
int err;
if ((err = PIO_buf_setbuf(interpreter, l, io, PIO_LINEBUFSIZE)) >= 0) {
/* Then switch to linebuf */
io->flags &= ~PIO_F_BLKBUF;
io->flags |= PIO_F_LINEBUF;
return 0;
}
return err;
}
ParrotIO *
PIO_buf_fdopen(theINTERP, ParrotIOLayer *layer, PIOHANDLE fd, INTVAL flags)
{
ParrotIO *io;
ParrotIOLayer *l = PIO_DOWNLAYER(layer);
while (l) {
if (l->api->FDOpen) {
io = (*l->api->FDOpen) (interpreter, l, fd, flags);
if (PIO_isatty(fd))
PIO_buf_setlinebuf(interpreter, l, io);
else
PIO_buf_setbuf(interpreter, l, io, PIO_UNBOUND);
return io;
}
l = PIO_DOWNLAYER(l);
}
return NULL;
}
INTVAL
PIO_buf_close(theINTERP, ParrotIOLayer *layer, ParrotIO *io)
{
ParrotIOLayer *l = PIO_DOWNLAYER(layer);
PIO_buf_flush(interpreter, layer, io);
while (l) {
if (l->api->Close) {
return (*l->api->Close) (interpreter, l, io);
}
l = PIO_DOWNLAYER(l);
}
return 0;
}
void
PIO_buf_flush(theINTERP, ParrotIOLayer *layer, ParrotIO *io)
{
long wrote;
size_t to_write;
/*
* Either buffering is null, disabled, or empty.
*/
if (!io->b.startb
|| (io->flags & (PIO_F_BLKBUF | PIO_F_LINEBUF)) == 0
|| (io->b.flags & (PIO_BF_WRITEBUF | PIO_BF_READBUF)) == 0)
return;
/*
* Write flush
*/
if (io->b.flags & PIO_BF_WRITEBUF) {
ParrotIOLayer *l = layer;
to_write = io->b.next - io->b.startb;
/* Flush to next layer */
wrote = PIO_buf_writethru(interpreter, l, io,
io->b.startb, to_write);
if (wrote == (long)to_write) {
io->b.next = io->b.startb;
/* Release buffer */
io->b.flags &= ~PIO_BF_WRITEBUF;
return;
}
else {
/* FIXME: I/O Error */
}
}
else {
/* Read flush */
io->b.flags &= ~PIO_BF_READBUF;
io->b.next = io->b.startb;
}
}
size_t
PIO_buf_read(theINTERP, ParrotIOLayer *layer, ParrotIO *io,
void *buffer, size_t len)
{
UNUSED(interpreter);
UNUSED(layer);
UNUSED(io);
UNUSED(buffer);
UNUSED(len);
return 0;
}
size_t
PIO_buf_write(theINTERP, ParrotIOLayer *layer, ParrotIO *io,
const void *buffer, size_t len)
{
size_t avail;
long wrote;
if (len <= 0)
return 0;
if (io->b.flags & PIO_BF_WRITEBUF) {
avail = io->b.size - (io->b.next - io->b.startb);
}
else if (io->b.flags & PIO_BF_READBUF) {
io->b.flags |= ~PIO_BF_READBUF;
io->b.next = io->b.startb;
avail = io->b.size;
}
else {
avail = io->b.size;
}
/*
* Large writes (multiples of blocksize) should write
* through generally for best performance, else you are
* just doing extra memcpys.
* FIXME: This is badly optimized, will fixup later.
*/
if (len >= io->b.size) {
/* Write through, skip buffer. */
PIO_buf_flush(interpreter, layer, io);
wrote = PIO_buf_writethru(interpreter, layer, io, buffer, len);
if (wrote == (long)len)
return wrote;
else {
/* FIXME: Write error */
}
}
else if (avail > len) {
memcpy(io->b.next, buffer, len);
io->b.next += len;
return len;
}
else {
/* Fill remainder, flush, then try to buffer more */
unsigned int diff = (int)(len - avail);
memcpy(io->b.next, buffer, diff);
/* We don't call flush here because it clears flag */
wrote = PIO_buf_writethru(interpreter, layer, io,
io->b.startb, io->b.size);
memcpy(io->b.startb, ((const char *)buffer + diff), len - diff);
io->b.next = io->b.startb + (len - diff);
return len;
}
return (size_t)-1;
}
/*
* Skip buffers, write through.
* PIO_buf_flush() should directly precede a call to this func.
*/
size_t
PIO_buf_writethru(theINTERP, ParrotIOLayer *layer,
ParrotIO *io, const void *buffer, size_t len)
{
ParrotIOLayer *l;
l = layer;
while ((l = PIO_DOWNLAYER(l)) != NULL) {
if (l->api->Write)
return (*l->api->Write) (interpreter, l, io, buffer, len);
}
return (size_t)-1;
}
INTVAL
PIO_buf_puts(theINTERP, ParrotIOLayer *layer, ParrotIO *io, const char *s)
{
ParrotIOLayer *l = layer;
while ((l = PIO_DOWNLAYER(l)) != NULL) {
if (l->api->PutS) {
return (*l->api->PutS) (interpreter, l, io, s);
}
}
return 0;
}
INTVAL
PIO_buf_seek(theINTERP, ParrotIOLayer *l, ParrotIO *io,
INTVAL hi, INTVAL lo, INTVAL whence)
{
int hardseek = 0;
UNUSED(hardseek)
if (io->flags & PIO_F_SHARED ||
!(io->flags & (PIO_F_BLKBUF | PIO_F_LINEBUF))) {
hardseek = 1;
}
if (io->b.flags & (PIO_BF_READBUF | PIO_BF_WRITEBUF)) {
/* FIXME: Flush on seek for now */
PIO_buf_flush(interpreter, l, io);
}
/*
* TODO : Try to satisfy seek request in buffer if possible,
* else make IO request.
*/
internal_exception(PIO_NOT_IMPLEMENTED, "Seek not implemented");
return -1;
}
PIOOFF_T
PIO_buf_tell(theINTERP, ParrotIOLayer *l, ParrotIO *io)
{
return io->fpos;
}
ParrotIOLayerAPI pio_buf_layer_api = {
PIO_buf_init,
PIO_base_new_layer,
PIO_base_delete_layer,
PIO_null_push_layer,
PIO_null_pop_layer,
PIO_buf_open,
PIO_null_open2,
PIO_null_open3,
PIO_null_open_async,
PIO_buf_fdopen,
PIO_buf_close,
PIO_buf_write,
PIO_null_write_async,
PIO_buf_read,
PIO_null_read_async,
PIO_null_flush,
PIO_null_seek,
PIO_null_tell,
PIO_buf_setbuf,
PIO_buf_setlinebuf,
PIO_null_getcount,
PIO_null_fill,
PIO_buf_puts,
PIO_null_gets,
PIO_null_eof
};
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: expandtab shiftwidth=4:
*/
1.8 +2 -2 parrot/config/gen/makefiles/root.in
Index: root.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/root.in,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -w -r1.7 -r1.8
--- root.in 7 Jun 2002 23:22:28 -0000 1.7
+++ root.in 8 Jun 2002 00:11:20 -0000 1.8
@@ -83,7 +83,7 @@
CHARTYPE_O_FILES = chartypes/unicode$(O) chartypes/usascii$(O)
-IO_O_FILES = io/io$(O) io/io_stdio$(O) io/io_unix$(O) io/io_win32$(O)
+IO_O_FILES = io/io$(O) io/io_buf$(O) io/io_unix$(O) io/io_win32$(O)
INTERP_O_FILES = exceptions$(O) global_setup$(O) interpreter$(O) parrot$(O) \
register$(O) core_ops$(O) core_ops_prederef$(O)
memory$(O) \
@@ -350,7 +350,7 @@
io/io$(O) : $(GENERAL_H_FILES)
-io/io_stdio$(O) : $(GENERAL_H_FILES)
+io/io_buf$(O) : $(GENERAL_H_FILES)
io/io_unix$(O) : $(GENERAL_H_FILES)