Author: allison
Date: Sat Nov  8 20:56:02 2008
New Revision: 32460

Modified:
   branches/pdd22io/src/io/buffer.c

Log:
[pdd22io] Converted I/O buffering to new architecture.


Modified: branches/pdd22io/src/io/buffer.c
==============================================================================
--- branches/pdd22io/src/io/buffer.c    (original)
+++ branches/pdd22io/src/io/buffer.c    Sat Nov  8 20:56:02 2008
@@ -4,11 +4,11 @@
 
 =head1 NAME
 
-src/io/io_buf.c - IO buffer layer
+src/io/buffer.c - I/O buffering 
 
 =head1 DESCRIPTION
 
-The "buf" layer of Parrot IO. Buffering and all the fun stuff.
+This file implements a collection of utility functions for I/O buffering.
 
 =head2 Functions
 
@@ -25,137 +25,9 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will 
be lost. */
 
-static INTVAL PIO_buf_close(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*io);
-
-PARROT_CAN_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static ParrotIO * PIO_buf_fdopen(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    PIOHANDLE fd,
-    INTVAL flags)
-        __attribute__nonnull__(1);
-
-static size_t PIO_buf_fill_readbuf(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io),
-    ARGMOD(ParrotIOBuf *b))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*io)
-        FUNC_MODIFIES(*b);
-
-static INTVAL PIO_buf_flush(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*io);
-
-static INTVAL PIO_buf_init(PARROT_INTERP, ARGMOD(ParrotIOLayer *layer))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*layer);
-
-PARROT_CAN_RETURN_NULL
-static ParrotIO * PIO_buf_open(PARROT_INTERP,
-    ARGMOD(ParrotIOLayer *layer),
-    ARGIN(const char *path),
-    INTVAL flags)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*layer);
-
-static size_t PIO_buf_peek(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io),
-    ARGOUT(STRING **buf))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*io)
-        FUNC_MODIFIES(*buf);
-
-static size_t PIO_buf_read(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io),
-    ARGOUT(STRING **buf))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*io)
-        FUNC_MODIFIES(*buf);
-
-static size_t PIO_buf_readline(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io),
-    ARGOUT(STRING **buf))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*io)
-        FUNC_MODIFIES(*buf);
-
-static PIOOFF_T PIO_buf_seek(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *l),
-    ARGMOD(ParrotIO *io),
-    PIOOFF_T offset,
-    INTVAL whence)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*io);
-
-static INTVAL PIO_buf_setbuf(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io),
-    size_t bufsize)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*io);
-
-static INTVAL PIO_buf_setlinebuf(PARROT_INTERP,
-    ARGIN_NULLOK(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*io);
-
-static PIOOFF_T PIO_buf_tell(SHIM_INTERP,
-    SHIM(ParrotIOLayer *layer),
-    ARGIN(ParrotIO *io))
-        __attribute__nonnull__(3);
-
-static size_t PIO_buf_write(PARROT_INTERP,
-    ARGMOD(ParrotIOLayer *layer),
-    ARGMOD(ParrotIO *io),
-    ARGIN(STRING *s))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*layer)
-        FUNC_MODIFIES(*io);
-
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will 
be lost. */
 /* HEADERIZER END: static */
 
-/* Defined at bottom */
-extern const ParrotIOLayerAPI pio_buf_layer_api;
-
-ParrotIOLayer pio_buf_layer = {
-    NULL,
-    "buf",
-    PIO_L_TERMINAL,
-    &pio_buf_layer_api,
-    0, 0
-};
-
 
 /* XXX: This is not portable */
 #define DEFAULT_RECSEP '\n'
@@ -167,149 +39,117 @@
 
 /*
 
-=item C<static INTVAL PIO_buf_init>
+=item C<INTVAL Parrot_io_init_buffer>
 
-The buffer layer's C<Init> function. Initializes buffering.
+Initialize buffering on STDOUT and STDIN.
 
 =cut
 
 */
 
-static INTVAL
-PIO_buf_init(PARROT_INTERP, ARGMOD(ParrotIOLayer *layer))
+INTVAL
+Parrot_io_init_buffer(PARROT_INTERP)
 {
-    if (PIO_STDOUT(interp))
-        PIO_buf_setlinebuf(interp, layer,
-                           PMC_data_typed(PIO_STDOUT(interp), ParrotIO *));
-
-    if (PIO_STDIN(interp))
-        PIO_buf_setbuf(interp, layer,
-            PMC_data_typed(PIO_STDIN(interp), ParrotIO *), PIO_UNBOUND);
+    if (Parrot_io_STDOUT(interp))
+        Parrot_io_setlinebuf(interp, Parrot_io_STDOUT(interp));
+
+    if (Parrot_io_STDIN(interp))
+        Parrot_io_setbuf(interp, Parrot_io_STDIN(interp), PIO_UNBOUND);
 
     return 0;
 }
 
 /*
 
-=item C<static ParrotIO * PIO_buf_open>
+=item C<INTVAL Parrot_io_setbuf>
 
-The buffer layer's C<Open> function.
+Set the buffering mode for the filehandle.
 
 =cut
 
 */
 
-PARROT_CAN_RETURN_NULL
-static ParrotIO *
-PIO_buf_open(PARROT_INTERP, ARGMOD(ParrotIOLayer *layer),
-        ARGIN(const char *path), INTVAL flags)
+void
+Parrot_io_setbuf(PARROT_INTERP, ARGMOD(PMC *filehandle), size_t bufsize)
 {
-    ParrotIOLayer * const l = PIO_DOWNLAYER(layer);
-    ParrotIO * const io = PIO_open_down(interp, l, path, flags);
-    if (!io) {
-        /* error creating IO stream */
-        return NULL;
-    }
-    /*
-     * We have an IO stream. Now setup stuff
-     * for our layer before returning it.
-     * XXX: Make default behaviour linebuffered?
-     */
-    /*PIO_buf_setlinebuf(interp, l, io);*/
-    PIO_buf_setbuf(interp, l, io, PIO_UNBOUND);
-    return io;
-}
-
-/*
-
-=item C<static INTVAL PIO_buf_setbuf>
-
-The buffer layer's C<SetBuf> function.
+    INTVAL filehandle_flags = Parrot_io_get_flags(interp, filehandle);
+    INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, 
filehandle);
+    unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
 
-Don't pass C<SetBuf> calls down the stack, top layer wins. This doesn't
-mean other layers can't buffer, I just need to think about the mechanism
-for buffer control or if it even makes sense this way. Most layers will
-not implement C<SetBuf>.
-
-=cut
-
-*/
-
-static INTVAL
-PIO_buf_setbuf(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io), size_t bufsize)
-{
-    ParrotIOLayer * const l = layer ? layer : io->stack;
-    ParrotIOBuf   * const b = &io->b;
-
-    /* If there is a buffer, make sure we flush before
-     * dinking around with the buffer.
-     */
-    if (b->startb)
-        PIO_buf_flush(interp, l, io);
+    /* If there is already a buffer, make sure we flush before modifying it. */
+    if (buffer_start)
+        Parrot_io_buf_flush(interp, filehandle);
 
     /* Choose an appropriate buffer size for caller */
     switch (bufsize) {
         case 0:
-            b->size = 0;
+            Parrot_io_set_buffer_size(interp, filehandle, 0);
             break;
         case PIO_UNBOUND:
-            b->size = PIO_getblksize(io->fd);
+            Parrot_io_set_buffer_size(interp, filehandle,
+                    PIO_GETBLKSIZE(Parrot_io_get_os_handle(interp, 
filehandle)));
             break;
         default:
-            b->size = (bufsize >= PIO_GRAIN ? bufsize : PIO_GRAIN);
+            Parrot_io_set_buffer_size(interp, filehandle,
+                    (bufsize >= PIO_GRAIN ? bufsize : PIO_GRAIN));
             break;
     }
 
-    if (b->startb && (b->flags & PIO_BF_MALLOC)) {
-        mem_sys_free(b->startb);
-        b->startb = b->next = NULL;
+    if (buffer_start && (buffer_flags & PIO_BF_MALLOC)) {
+        mem_sys_free(buffer_start);
+        Parrot_io_set_buffer_start(interp, filehandle, NULL);
+        Parrot_io_set_buffer_next(interp, filehandle, NULL);
+        buffer_start = buffer_next = NULL;
     }
 
-    if (b->size > 0) {
-        b->startb = b->next = (unsigned char *)mem_sys_allocate(b->size);
-        b->flags |= PIO_BF_MALLOC;
+    if (buffer_size > 0) {
+        buffer_start = buffer_next = (unsigned char 
*)mem_sys_allocate(buffer_size);
+        buffer_flags |= PIO_BF_MALLOC;
     }
     else
-        b->flags &= ~PIO_BF_MALLOC;
+        buffer_flags &= ~PIO_BF_MALLOC;
+
+    Parrot_io_set_buffer_flags(interp, filehandle, buffer_flags);
 
-    if (b->size != 0) {
-        io->flags &= ~PIO_F_LINEBUF;
-        io->flags |= PIO_F_BLKBUF;
+    if (buffer_size != 0) {
+        filehandle_flags &= ~PIO_F_LINEBUF;
+        filehandle_flags |= PIO_F_BLKBUF;
     }
     else
-        io->flags &= ~(PIO_F_BLKBUF | PIO_F_LINEBUF);
+        filehandle_flags &= ~(PIO_F_BLKBUF | PIO_F_LINEBUF);
+
+    Parrot_io_set_flags(interp, filehandle, filehandle_flags);
 
-    return 0;
 }
 
 /*
 
-=item C<static INTVAL PIO_buf_setlinebuf>
+=item C<INTVAL Parrot_io_setlinebuf>
 
-The buffer layer's C<SetLineBuf> function.
+Set the file handle to line buffering mode.
 
 =cut
 
 */
 
-static INTVAL
-PIO_buf_setlinebuf(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io))
+INTVAL
+Parrot_io_setlinebuf(PARROT_INTERP, ARGMOD(PMC *filehandle))
 {
     int err;
-    ParrotIOLayer * const l = layer ? layer : io->stack;
+    INTVAL filehandle_flags = Parrot_io_get_flags(interp, filehandle);
 
     /* already linebuffering */
-    if (io->flags & PIO_F_LINEBUF)
+    if (filehandle_flags & PIO_F_LINEBUF)
         return 0;
 
     /* Reuse setbuf call */
-    if ((err = PIO_buf_setbuf(interp, l, io, PIO_LINEBUFSIZE)) >= 0) {
+    if ((err = Parrot_io_setbuf(interp, filehandle, PIO_LINEBUFSIZE)) >= 0) {
         /* Then switch to linebuf */
-        io->flags &= ~PIO_F_BLKBUF;
-        io->flags |= PIO_F_LINEBUF;
-        io->recsep = DEFAULT_RECSEP;
+        filehandle_flags &= ~PIO_F_BLKBUF;
+        filehandle_flags |= PIO_F_LINEBUF;
+        Parrot_io_set_flags(interp, filehandle, filehandle_flags);
+        Parrot_io_set_record_separator(interp, filehandle, DEFAULT_RECSEP);
         return 0;
     }
     return err;
@@ -317,108 +157,66 @@
 
 /*
 
-=item C<static ParrotIO * PIO_buf_fdopen>
-
-The buffer layer's C<FDOpen> function.
-
-=cut
-
-*/
-
-PARROT_CAN_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static ParrotIO *
-PIO_buf_fdopen(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer), PIOHANDLE 
fd, INTVAL flags)
-{
-    ParrotIOLayer * const l = PIO_DOWNLAYER(layer);
-    ParrotIO * const io = PIO_fdopen_down(interp, l, fd, flags);
-
-    if (io) {
-        if (io->flags & PIO_F_CONSOLE)
-            PIO_buf_setlinebuf(interp, l, io);
-        else
-            PIO_buf_setbuf(interp, l, io, PIO_UNBOUND);
-    }
-
-    return io;
-}
-
-/*
-
-=item C<static INTVAL PIO_buf_close>
-
-The buffer layer's C<Close> function.
-
-=cut
-
-*/
-
-static INTVAL
-PIO_buf_close(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer), 
ARGMOD(ParrotIO *io))
-{
-    ParrotIOLayer * const l = PIO_DOWNLAYER(layer);
-    PIO_buf_flush(interp, layer, io);
-
-    return PIO_close_down(interp, l, io);
-}
-
-/*
-
-=item C<static INTVAL PIO_buf_flush>
+=item C<INTVAL Parrot_io_flush_buffer>
 
-The buffer layer's C<Flush> function.
+Flush the I/O buffer for a given filehandle object.
 
 =cut
 
 */
 
-static INTVAL
-PIO_buf_flush(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer), 
ARGMOD(ParrotIO *io))
+INTVAL
+Parrot_io_flush_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle))
 {
     long wrote;
     size_t to_write;
     STRING fake;
+    unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
+    INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, 
filehandle);
+
     /*
      * 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)
+    if (!buffer_start
+        || (Parrot_io_get_flags(interp, filehandle) & (PIO_F_BLKBUF | 
PIO_F_LINEBUF)) == 0
+        || (buffer_flags & (PIO_BF_WRITEBUF | PIO_BF_READBUF)) == 0)
         return 0;
     /*
      * Write flush
      */
-    if (io->b.flags & PIO_BF_WRITEBUF) {
-        ParrotIOLayer * const l = layer;
-        to_write = io->b.next - io->b.startb;
+    if (buffer_flags & PIO_BF_WRITEBUF) {
+        to_write = buffer_next - buffer_start;
 
         /* Flush to next layer */
-        fake.strstart = (char *)io->b.startb;
+        fake.strstart = (char *)buffer_start;
         fake.bufused = to_write;
-        wrote = PIO_write_down(interp, PIO_DOWNLAYER(l), io, &fake);
+        wrote = PIO_WRITE(interp, filehandle, &fake);
         if (wrote == (long)to_write) {
-            io->b.next = io->b.startb;
+            Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
             /* Release buffer */
-            io->b.flags &= ~PIO_BF_WRITEBUF;
+            Parrot_io_set_buffer_flags(interp, filehandle, (buffer_flags & 
~PIO_BF_WRITEBUF));
             return 0;
         }
         else {
-            /* FIXME: I/O Error */
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                    "Attempt to flush invalid write buffer");
         }
     }
     /*
      * Read flush
      */
-    else if (io->b.flags & PIO_BF_READBUF) {
-        io->b.flags &= ~PIO_BF_READBUF;
-        io->b.next = io->b.startb;
+    else if (buffer_flags & PIO_BF_READBUF) {
+        Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
+        /* Release buffer */
+        Parrot_io_set_buffer_flags(interp, filehandle, (buffer_flags & 
~PIO_BF_READBUF));
     }
     return -1;
 }
 
 /*
 
-=item C<static size_t PIO_buf_fill_readbuf>
+=item C<size_t Parrot_io_fill_readbuf>
 
 The buffer layer's C<Fill> function.
 
@@ -426,37 +224,38 @@
 
 */
 
-static size_t
-PIO_buf_fill_readbuf(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io), ARGMOD(ParrotIOBuf *b))
+size_t
+Parrot_io_fill_readbuf(PARROT_INTERP, ARGMOD(PMC *filehandle))
 {
     size_t got;
-    PIOOFF_T pos = io->fpos;
+    PIOOFF_T pos = Parrot_io_get_file_position(interp, filehandle);
     STRING fake, *s;
-    fake.strstart = (char *)b->startb;
-    fake.bufused  = b->size;
+    fake.strstart = (char *)Parrot_io_get_buffer_start(interp, filehandle);
+    fake.bufused  = Parrot_io_get_buffer_size(interp, filehandle);
     s = &fake;
 
-    got = PIO_read_down(interp, PIO_DOWNLAYER(layer),
-                        io, &s);
+    got = PIO_READ(interp, filehandle, &s);
     /* buffer-filling does not change fileposition */
-    io->fpos = pos;
+    Parrot_io_set_file_position(interp, filehandle, pos);
 
     /* nothing to get */
     if (got == 0)
         return 0;
 
-    b->endb = b->startb + got;
-    b->next = b->startb;
+    Parrot_io_set_buffer_end(interp, filehandle,
+            (got + Parrot_io_get_buffer_start(interp, filehandle)));
+    Parrot_io_set_buffer_next(interp, filehandle,
+            Parrot_io_get_buffer_start(interp, filehandle));
 
-    b->flags |= PIO_BF_READBUF;
+    Parrot_io_set_buffer_flags(interp, filehandle,
+            (Parrot_io_set_buffer_flags(interp, filehandle) | PIO_BF_READBUF));
 
     return got;
 }
 
 /*
 
-=item C<static size_t PIO_buf_read>
+=item C<size_t Parrot_io_read_buffer>
 
 The buffer layer's C<Read> function.
 
@@ -464,27 +263,28 @@
 
 */
 
-static size_t
-PIO_buf_read(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io), ARGOUT(STRING **buf))
+size_t
+Parrot_io_read_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle),
+              ARGIN(STRING **buf))
 {
     ParrotIOLayer *l = layer;
-    ParrotIOBuf *b;
     unsigned char *out_buf;
     STRING *s;
     size_t len;
     size_t current = 0;
+    INTVAL buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
+    unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
+    unsigned char *buffer_end   = Parrot_io_get_buffer_end(interp, filehandle);
 
     /* write buffer flush */
-    if (io->b.flags & PIO_BF_WRITEBUF) {
-        PIO_buf_flush(interp, layer, io);
+    if (buffer_flags & PIO_BF_WRITEBUF) {
+        Parrot_io_flush_buffer(interp, filehandle);
     }
 
-    b = &io->b;
-
     /* line buffered read */
-    if (io->flags & PIO_F_LINEBUF) {
-        return PIO_buf_readline(interp, layer, io, buf);
+    if (Parrot_io_get_flags(interp, filehandle) & PIO_F_LINEBUF) {
+        return Parrot_io_readline_buffer(interp, filehandle);
     }
 
     if (*buf == NULL) {
@@ -498,20 +298,23 @@
     }
     out_buf = (unsigned char *)s->strstart;
     /* read Data from buffer */
-    if (b->flags & PIO_BF_READBUF) {
-        const size_t avail = b->endb - b->next;
+    if (buffer_flags & PIO_BF_READBUF) {
+        const size_t avail = buffer_end - buffer_next;
 
         current = avail < len ? avail : len;
-        memcpy(out_buf, b->next, current);
-        b->next += current;
-        io->fpos += current;
+        memcpy(out_buf, buffer_next, current);
+        buffer_next += current;
+        Parrot_io_set_buffer_next(interp, filehandle, buffer_next);
+        Parrot_io_set_file_position(interp, filehandle, (current +
+                Parrot_io_get_file_position(interp, filehandle)));
 
         /* buffer completed */
         if (current == avail) {
-            io->b.flags &= ~PIO_BF_READBUF;
-            /* XXX: Is the reset of next and endb really necessary ? */
-            io->b.endb = NULL;
-            io->b.next = io->b.startb;
+            Parrot_io_set_buffer_flags(interp, filehandle,
+                    (buffer_flags & ~PIO_BF_READBUF));
+            /* Reset next and end */
+            Parrot_io_set_buffer_end(interp, filehandle, NULL);
+            Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
         }
 
         if (len == current) {
@@ -526,44 +329,48 @@
     }
 
     /* (re)fill the readbuffer */
-    if (!(b->flags & PIO_BF_READBUF)) {
+    if (!(buffer_flags & PIO_BF_READBUF)) {
         size_t got;
-        if (len >= io->b.size) {
+        if (len >= Parrot_io_get_buffer_size(interp, filehandle)) {
             STRING fake;
             STRING *sf = &fake;
 
             fake.strstart = (char *)out_buf;
             fake.bufused  = len;
-            got = PIO_read_down(interp, PIO_DOWNLAYER(l), io, &sf);
+            got = PIO_READ(interp, filehandle, &sf);
             s->strlen = s->bufused = current + got;
-            io->fpos += got;
+            Parrot_io_set_file_position(interp, filehandle, (got +
+                    Parrot_io_get_file_position(interp, filehandle)));
             return current + got;
         }
 
-        got = PIO_buf_fill_readbuf(interp, l, io, b);
+        got = Parrot_io_fill_readbuf(interp, filehandle);
 
         len = len < got ? len : got;
     }
 
     /* read from the read_buffer */
-    memcpy(out_buf, io->b.next, len);
+    memcpy(out_buf, buffer_next, len);
     s->strlen = s->bufused = current + len;
-    io->b.next += len;
-    io->fpos += len;
+    buffer_next += len;
+    Parrot_io_set_buffer_next(interp, filehandle, buffer_next);
+    Parrot_io_set_file_position(interp, filehandle, (len +
+            Parrot_io_get_file_position(interp, filehandle)));
 
     /* is the buffer is completely empty ? */
-    if (io->b.next == io->b.endb) {
-        io->b.flags &= ~PIO_BF_READBUF;
-        /* XXX: Is the reset of next and encb really necessary ? */
-        io->b.endb = NULL;
-        io->b.next = io->b.startb;
+    if (buffer_next == buffer_end) {
+        Parrot_io_set_buffer_flags(interp, filehandle,
+                (buffer_flags & ~PIO_BF_READBUF));
+        /* Reset next and end */
+        Parrot_io_set_buffer_end(interp, filehandle, NULL);
+        Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
     }
     return current + len;
 }
 
 /*
 
-=item C<static size_t PIO_buf_peek>
+=item C<size_t Parrot_io_peek_buffer>
 
 RT#48260: Not yet documented!!!
 
@@ -571,46 +378,46 @@
 
 */
 
-static size_t
-PIO_buf_peek(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io), ARGOUT(STRING **buf))
+size_t
+Parrot_io_peek_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle),
+        ARGOUT(STRING **buf))
 {
-    ParrotIOLayer *l = layer;
-    ParrotIOBuf *b;
     size_t len = 1;
     size_t avail = 0;
 
-    STRING * const s = PIO_make_io_string(interp, buf, 1);
+    INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
+    unsigned char *buffer_end   = Parrot_io_get_buffer_end(interp, filehandle);
+
+    STRING * const s = Parrot_io_make_string(interp, buf, 1);
 
     /* write buffer flush */
-    if (io->b.flags & PIO_BF_WRITEBUF) {
-        PIO_buf_flush(interp, layer, io);
+    if (buffer_flags & PIO_BF_WRITEBUF) {
+        Parrot_io_flush_buffer(interp, filehandle);
     }
 
-    b = &io->b;
-
     /* read Data from buffer */
-    if (b->flags & PIO_BF_READBUF) {
-        avail = b->endb - b->next;
+    if (buffer_flags & PIO_BF_READBUF) {
+        avail = buffer_end - buffer_next;
 
         /* if we have data available, copy out the next byte */
         if (avail) {
 ret_string:
-            memcpy(s->strstart, b->next, len);
+            memcpy(s->strstart, buffer_next, len);
             s->bufused = s->strlen = len;
             return len;
         }
     }
 
     /* (re)fill the buffer */
-    if (! (b->flags & PIO_BF_READBUF)) {
+    if (! (buffer_flags & PIO_BF_READBUF)) {
         size_t got;
         /* exception if we're unbuffered */
-        if (io->b.size == 0)
+        if (buffer_size == 0)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Can't peek at unbuffered PIO");
+                "Can't peek at unbuffered I/O");
 
-        got = PIO_buf_fill_readbuf(interp, l, io, b);
+        got = Parrot_io_fill_readbuf(interp, filehandle, b);
         len = (len < got) ? len : got;
     }
 
@@ -620,23 +427,24 @@
 
 /*
 
-=item C<static size_t PIO_buf_readline>
+=item C<size_t Parrot_io_readline_buffer>
 
-This is called from C<PIO_buf_read()> to do line buffered reading if
+This is called from C<Parrot_io_read_buffer()> to do line buffered reading if
 that is what is required.
 
 =cut
 
 */
 
-static size_t
-PIO_buf_readline(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io), ARGOUT(STRING **buf))
+size_t
+Parrot_io_readline_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle), 
ARGOUT(STRING **buf))
 {
     size_t l;
     unsigned char *out_buf;
     unsigned char *buf_start;
-    ParrotIOBuf * const b = &io->b;
+    INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
+    unsigned char *buffer_end   = Parrot_io_get_buffer_end(interp, filehandle);
     size_t len;
     STRING *s;
 
@@ -647,15 +455,15 @@
     s->strlen = 0;
 
     /* fill empty buffer */
-    if (!(b->flags & PIO_BF_READBUF)) {
-        if (PIO_buf_fill_readbuf(interp, layer, io, b) == 0)
+    if (!(buffer_flags & PIO_BF_READBUF)) {
+        if (Parrot_io_fill_readbuf(interp, filehandle, b) == 0)
             return 0;
     }
 
-    buf_start = b->next;
-    for (l = 0; b->next < b->endb;) {
+    buf_start = buffer_next;
+    for (l = 0; buffer_next < buffer_end;) {
         l++;
-        if (IS_EOL(io, b->next++)) {
+        if (IS_EOL(io, buffer_next++)) {
             break;
         }
         /* if there is a buffer, readline is called by the read opcode
@@ -664,8 +472,8 @@
         if (s->bufused && l == s->bufused)
             break;
         /* buffer completed; copy out and refill */
-        if (b->next == b->endb) {
-            len = b->endb - buf_start;
+        if (buffer_next == buffer_end) {
+            len = buffer_end - buf_start;
             if (s->bufused < l) {
                 if (s->strstart) {
                     Parrot_reallocate_string(interp, s, l);
@@ -677,9 +485,9 @@
             out_buf = (unsigned char*)s->strstart + s->strlen;
             memcpy(out_buf, buf_start, len);
             s->strlen = s->bufused = l;
-            if (PIO_buf_fill_readbuf(interp, layer, io, b) == 0)
+            if (Parrot_io_fill_readbuf(interp, filehandle, b) == 0)
                 return l;
-            buf_start = b->startb;
+            buf_start = Parrot_io_get_buffer_start(interp, filehandle);;
         }
     }
     if (s->bufused < l) {
@@ -691,15 +499,17 @@
         }
     }
     out_buf = (unsigned char*)s->strstart + s->strlen;
-    len = b->next - buf_start;
+    len = buffer_next - buf_start;
     memcpy(out_buf, buf_start, len);
     s->strlen = s->bufused = l;
 
     /* check if buffer is finished */
-    if (b->next == b->endb) {
-        b->next = b->startb;
-        b->endb = NULL;
-        b->flags &= ~PIO_BF_READBUF;
+    if (buffer_next == buffer_end) {
+        Parrot_io_set_buffer_flags(interp, filehandle,
+                (buffer_flags & ~PIO_BF_READBUF));
+        Parrot_io_set_buffer_next(interp, filehandle,
+                Parrot_io_get_buffer_start(interp, filehandle));
+        Parrot_io_set_buffer_end(interp, filehandle, NULL);
     }
 
     return l;
@@ -707,7 +517,7 @@
 
 /*
 
-=item C<static size_t PIO_buf_write>
+=item C<size_t Parrot_io_write_buffer>
 
 The buffer layer's C<Write> function.
 
@@ -715,33 +525,38 @@
 
 */
 
-static size_t
-PIO_buf_write(PARROT_INTERP, ARGMOD(ParrotIOLayer *layer),
-        ARGMOD(ParrotIO *io), ARGIN(STRING *s))
+size_t
+Parrot_io_write_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle), ARGIN(STRING 
*s))
 {
     size_t avail;
     void * const buffer = s->strstart;
     size_t len = s->bufused;
     int need_flush;
 
+    INTVAL         buffer_flags = Parrot_io_get_buffer_flags(interp, 
filehandle);
+    unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
+    size_t         buffer_size  = Parrot_io_get_buffer_size(interp, 
filehandle);
+
     if (len <= 0)
         return 0;
-    if (io->b.flags & PIO_BF_WRITEBUF) {
-        avail = io->b.size - (io->b.next - io->b.startb);
+    if (buffer_flags & PIO_BF_WRITEBUF) {
+        avail = buffer_size - (buffer_next - buffer_start);
     }
-    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 if (buffer_flags & PIO_BF_READBUF) {
+        buffer_flags &= ~PIO_BF_READBUF;
+        Parrot_io_set_buffer_flags(interp, filehandle, buffer_flags);
+        Parrot_io_set_buffer_next(interp, filehandle, buffer_start);
+        avail = buffer_size;
     }
     else {
-        avail = io->b.size;
+        avail = buffersize;
     }
     /* If we are line buffered, check for newlines.
      * If any, we should flush
      */
     need_flush = 0;
-    if (io->flags & PIO_F_LINEBUF) {
+    if (Parrot_io_get_flags(interp, filehandle) & PIO_F_LINEBUF) {
         /* scan from end, it's likely that EOL is at end of string */
         const char *p = (char*)buffer + len - 1;
         size_t i;
@@ -758,13 +573,14 @@
      * just doing extra memcpys.
      * FIXME: This is badly optimized, will fixup later.
      */
-    if (need_flush || len >= io->b.size) {
+    if (need_flush || len >= buffer_size) {
         long wrote;
         /* Write through, skip buffer. */
-        PIO_buf_flush(interp, layer, io);
-        wrote = PIO_write_down(interp, PIO_DOWNLAYER(layer), io, s);
+        Parrot_io_flush_buffer(interp, filehandle);
+        wrote = PIO_WRITE(interp, filehandle, s);
         if (wrote == (long)len) {
-            io->fpos += wrote;
+            Parrot_io_set_file_position(interp, filehandle, (wrote +
+                        Parrot_io_get_file_position(interp, filehandle)));
             return wrote;
         }
         else {
@@ -772,31 +588,36 @@
         }
     }
     else if (avail > len) {
-        io->b.flags |= PIO_BF_WRITEBUF;
-        memcpy(io->b.next, buffer, len);
-        io->b.next += len;
-        io->fpos += len;
+        buffer_flags |= PIO_BF_WRITEBUF;
+        Parrot_io_set_buffer_flags(interp, filehandle, buffer_flags);
+        memcpy(buffer_next, buffer, len);
+        buffer_next += len;
+        Parrot_io_set_file_position(interp, filehandle, (len +
+                    Parrot_io_get_file_position(interp, filehandle)));
         return len;
     }
     else {
         const unsigned int diff = (int)(len - avail);
 
-        io->b.flags |= PIO_BF_WRITEBUF;
+        buffer_flags |= PIO_BF_WRITEBUF;
+        Parrot_io_set_buffer_flags(interp, filehandle, buffer_flags);
         /* Fill remainder, flush, then try to buffer more */
-        memcpy(io->b.next, buffer, avail);
-        io->b.next += avail;
-        io->fpos += avail;
-        PIO_buf_flush(interp, layer, io);
-        memcpy(io->b.startb, ((const char *)buffer + avail), diff);
-        io->b.next += diff;
-        io->fpos += diff;
+        memcpy(buffer_next, buffer, avail);
+        buffer_next += avail;
+        Parrot_io_set_file_position(interp, filehandle, (avail +
+                    Parrot_io_get_file_position(interp, filehandle)));
+        Parrot_io_flush_buffer(interp, filehandle);
+        memcpy(buffer_start, ((const char *)buffer + avail), diff);
+        buffer_next += diff;
+        Parrot_io_set_file_position(interp, filehandle, (diff +
+                    Parrot_io_get_file_position(interp, filehandle)));
         return len;
     }
 }
 
 /*
 
-=item C<static PIOOFF_T PIO_buf_seek>
+=item C<PIOOFF_T Parrot_io_seek_buffer>
 
 The buffer layer's C<Seek> function.
 
@@ -804,21 +625,25 @@
 
 */
 
-static PIOOFF_T
-PIO_buf_seek(PARROT_INTERP, ARGIN_NULLOK(ParrotIOLayer *l),
-        ARGMOD(ParrotIO *io), PIOOFF_T offset, INTVAL whence)
+PIOOFF_T
+Parrot_io_seek_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle),
+        PIOOFF_T offset, INTVAL whence)
 {
     PIOOFF_T newpos;
+    PIOOFF_T file_pos = Parrot_io_get_file_position(interp, filehandle);
+    unsigned char *buffer_start = Parrot_io_get_buffer_start(interp, 
filehandle);
+    unsigned char *buffer_next  = Parrot_io_get_buffer_next(interp, 
filehandle);
+    unsigned char *buffer_end   = Parrot_io_get_buffer_end(interp, filehandle);
 
     switch (whence) {
     case SEEK_SET:
         newpos = offset;
         break;
     case SEEK_CUR:
-        newpos = io->fpos + offset;
+        newpos = file_pos + offset;
         break;
     case SEEK_END:
-        newpos = PIO_seek_down(interp, PIO_DOWNLAYER(l), io, offset,
+        newpos = PIO_SEEK(interp, filehandle, offset,
                                whence);
         if (newpos == -1)
             return -1;
@@ -829,71 +654,21 @@
         return -1;
     }
 
-    if ((newpos < io->fpos - (io->b.next - io->b.startb))
-        || (newpos >= io->fpos + (io->b.endb - io->b.next))) {
-        PIO_buf_flush(interp, l, io);
-        newpos = PIO_seek_down(interp, PIO_DOWNLAYER(l), io, newpos, SEEK_SET);
+    if ((newpos < file_pos - (buffer_next - buffer_start))
+        || (newpos >= file_pos + (buffer_end - buffer_next))) {
+        Parrot_io_flush_buffer(interp, filehandle);
+        newpos = PIO_SEEK(interp, filehandle, newpos, SEEK_SET);
     }
     else {
-        io->b.next += newpos - io->fpos;
+        buffer_next += newpos - file_pos;
+        Parrot_io_set_buffer_next(interp, filehandle, buffer_next);
     }
 
-    io->lpos = io->fpos;
-    io->fpos = newpos;
+    Parrot_io_set_file_position(interp, filehandle, newpos);
 
-    return io->fpos;
+    return newpos;
 }
 
-/*
-
-=item C<static PIOOFF_T PIO_buf_tell>
-
-The buffer layer's C<Tell> function.
-
-=cut
-
-*/
-
-static PIOOFF_T
-PIO_buf_tell(SHIM_INTERP, SHIM(ParrotIOLayer *layer), ARGIN(ParrotIO *io))
-{
-    return io->fpos;
-}
-
-const 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_buf_flush,
-    PIO_buf_peek,
-    PIO_buf_seek,
-    PIO_buf_tell,
-    PIO_buf_setbuf,
-    PIO_buf_setlinebuf,
-    PIO_null_getcount,
-    PIO_null_fill,
-    PIO_null_eof,
-    0, /* no poll */
-    0, /* no socket */
-    0, /* no connect */
-    0, /* no send */
-    0, /* no recv */
-    0, /* no bind */
-    0, /* no listen */
-    0  /* no accept */
-};
 
 /*
 
@@ -901,19 +676,13 @@
 
 =head1 SEE ALSO
 
-F<src/io/io_passdown.c>,
-F<src/io/io_stdio.c>,
-F<src/io/io_unix.c>,
-F<src/io/io_win32.c>,
-F<src/io/io.c>,
+F<src/io/api.c>,
+F<src/io/unix.c>,
+F<src/io/win32.c>,
+F<src/io/portable.c>,
+F<src/io.c>,
 F<src/io/io_private.h>.
 
-=head1 HISTORY
-
-Initially written by Melvin Smith.
-
-Some ideas from AT&T SFIO.
-
 =cut
 
 */

Reply via email to