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)
   
  
  
  


Reply via email to