Well I'm working really slow, barely able to get in 50 lines tonight, work 
is crushing me.

Patch Comments:
        Implemented a few more calls in the Win32 layer (write/read/seek/tell)
        A few other minor tweaks.

-Melvin


Index: include/parrot/io.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/io.h,v
retrieving revision 1.6
diff -u -r1.6 io.h
--- include/parrot/io.h 14 Jan 2002 20:04:29 -0000      1.6
+++ include/parrot/io.h 18 Jan 2002 06:54:38 -0000
@@ -9,6 +9,7 @@
   *      Originally written by Melvin Smith
   *  Notes:
   *  References:
+ *      Perl6 RFCs (14,30,47,60,186,239,321,345,350)
   *      Some ideas and goals from Perl5.7 and Nick Ing-Simmons' work
   *      Some ideas from AT&T SFIO
   */
@@ -38,11 +39,11 @@
  # define O_ACCMODE 0003
  #endif

-/* Average block size of most systems (usually varies from 2k-8k),
- * later we can add some config to query it from the system at
- * build time (struct stat.st_blksize maybe).
- */
-#define PIO_BLKSIZE 4096
+#ifdef BLKSIZE
+# define PIO_BLKSIZE BLKSIZE
+#else
+# define PIO_BLKSIZE  8192
+#endif
  #define PIO_BUFSIZE 4096
  #define PIO_LINEBUFSIZE 256

@@ -93,18 +94,21 @@

  #ifdef WIN32
  typedef HANDLE PIOHANDLE;
+typedef LARGE_INTEGER PIOOFF_T;
  #else
  typedef int PIOHANDLE;
+typedef off_t PIOOFF_T;
  #endif

+extern PIOOFF_T piooffsetzero;

  struct _ParrotIO {
          PIOHANDLE       fd;             /* Low level OS descriptor      */
          UINTVAL         mode;           /* Read/Write/etc.              */
          UINTVAL         flags;          /* Da flags                     */
-        off_t           fsize;          /* Current file size            */
-        off_t           fpos;           /* Current real file pointer    */
-        off_t           lpos;           /* Last file position           */
+        PIOOFF_T        fsize;          /* Current file size            */
+        PIOOFF_T        fpos;           /* Current real file pointer    */
+        PIOOFF_T        lpos;           /* Last file position           */
          ParrotIOBuf     b;              /* Buffer structure             */
          ParrotIOLayer * stack;
          /* ParrotIOFilter * filters; */
@@ -192,10 +196,9 @@
                                          DummyCodeRef *);
          INTVAL          (*Flush)(theINTERP, ParrotIOLayer * layer,
                                  ParrotIO * io);
-        INTVAL          (*Seek)(theINTERP, ParrotIOLayer * layer,
-                                ParrotIO * io, off_t offset,
-                                        INTVAL whence);
-        off_t           (*Tell)(theINTERP, ParrotIOLayer * layer,
+        PIOOFF_T        (*Seek)(theINTERP, ParrotIOLayer * layer,
+                                ParrotIO * io, PIOOFF_T offset, INTVAL 
whence);
+        PIOOFF_T        (*Tell)(theINTERP, ParrotIOLayer * layer,
                                  ParrotIO * io);
          INTVAL          (*SetBuf)(theINTERP, ParrotIOLayer * layer,
                                  ParrotIO * io, size_t bufsize);
@@ -246,9 +249,13 @@
  #ifdef WIN32
  extern INTVAL           PIO_win32_isatty(PIOHANDLE fd);
  # define PIO_isatty(x)   PIO_win32_isatty(x)
+extern INTVAL           PIO_win32_getblksize(PIOHANDLE fd);
+# define PIO_getblksize(x)   PIO_win32_getblksize(x)
  #else
  extern INTVAL           PIO_unix_isatty(PIOHANDLE fd);
  # define PIO_isatty(x)   PIO_unix_isatty(x)
+extern INTVAL           PIO_unix_getblksize(PIOHANDLE fd);
+# define PIO_getblksize(x)   PIO_unix_getblksize(x)
  #endif

  extern ParrotIO * pio_stdin;
Index: io/TODO
===================================================================
RCS file: /cvs/public/parrot/io/TODO,v
retrieving revision 1.1
diff -u -r1.1 TODO
--- io/TODO     4 Jan 2002 03:57:38 -0000       1.1
+++ io/TODO     18 Jan 2002 06:54:38 -0000
@@ -1,6 +1,6 @@
  Add IO tables, right now IO's just float around.

-Finish pmc
+Finish PMC for IO object

  The "stdio" layer
        -buffering
@@ -23,5 +23,9 @@
  UTF layers (or should we not bother and do as a filter?)

  Sample programs and test suite
+
+AIO - On many platforms we must fake async IO, are we doing a background
+       thread/interp or an inline event queue function that is called
+       every N ops?

  Documentation! :)
Index: io/io.c
===================================================================
RCS file: /cvs/public/parrot/io/io.c,v
retrieving revision 1.6
diff -u -r1.6 io.c
--- io/io.c     12 Jan 2002 15:34:27 -0000      1.6
+++ io/io.c     18 Jan 2002 06:54:39 -0000
@@ -32,6 +32,7 @@
  ParrotIO * pio_stdout;
  ParrotIO * pio_stderr;

+PIOOFF_T        piooffsetzero;

  PMC * new_io_pmc(theINTERP, ParrotIO * io) {
          PMC * new_pmc;
@@ -62,7 +63,7 @@
                  /* FIXME: Reuse old IO */
          }
          new_io = (ParrotIO *)malloc(sizeof(ParrotIO));
-        new_io->fpos = new_io->lpos = (off_t)-1;
+        new_io->fpos = new_io->lpos = piooffsetzero;
          new_io->flags = flags;
          new_io->mode = mode;
          new_io->stack = pio_default_stack;
Index: io/io_stdio.c
===================================================================
RCS file: /cvs/public/parrot/io/io_stdio.c,v
retrieving revision 1.6
diff -u -r1.6 io_stdio.c
--- io/io_stdio.c       14 Jan 2002 20:04:31 -0000      1.6
+++ io/io_stdio.c       18 Jan 2002 06:54:39 -0000
@@ -31,6 +31,7 @@
   * file.
   */

+INTVAL          PIO_stdio_init(theINTERP, ParrotIOLayer * layer);
  ParrotIO *      PIO_stdio_open(theINTERP, ParrotIOLayer * layer,
                        const char * path, UINTVAL flags);
  INTVAL          PIO_stdio_setbuf(theINTERP, ParrotIOLayer * layer,
@@ -49,12 +50,22 @@
                          ParrotIO * io, const void * buffer, size_t len);
  INTVAL          PIO_stdio_puts(theINTERP, ParrotIOLayer * l, ParrotIO * io,
                          const char * s);
-INTVAL          PIO_stdio_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
-                        off_t offset, INTVAL whence);
-off_t           PIO_stdio_tell(theINTERP, ParrotIOLayer * l,
+PIOOFF_T        PIO_stdio_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
+                        PIOOFF_T offset, INTVAL whence);
+PIOOFF_T        PIO_stdio_tell(theINTERP, ParrotIOLayer * l,
                          ParrotIO * io);


+INTVAL PIO_stdio_init(theINTERP, ParrotIOLayer * layer) {
+        if(pio_stdout)
+                PIO_stdio_setlinebuf(interpreter, layer, pio_stdout);
+        if(pio_stderr)
+                PIO_stdio_setbuf(interpreter, layer, pio_stderr, PIO_UNBOUND);
+        if(pio_stdin)
+                PIO_stdio_setbuf(interpreter, layer, pio_stdin, PIO_UNBOUND);
+        return 0;
+}
+

  ParrotIO * PIO_stdio_open(theINTERP, ParrotIOLayer * layer,
                        const char * path, UINTVAL flags) {
@@ -67,7 +78,7 @@
                           * We have an IO stream now setup stuff
                           * for our layer before returning it.
                           */
-                        PIO_stdio_setbuf(interpreter, l, io, PIO_BUFSIZE);
+                        PIO_stdio_setbuf(interpreter, l, io, PIO_UNBOUND);
                          return io;
                  }
                  l = PIO_DOWNLAYER(l);
@@ -94,7 +105,7 @@

          /* Choose an appropriate buffer size for caller */
          if( bufsize == PIO_UNBOUND ) {
-                b->size = PIO_BUFSIZE;
+                b->size = PIO_getblksize(io->fd);
          }
          else {
                  b->size = bufsize;
@@ -144,7 +155,7 @@
                                  PIO_stdio_setlinebuf(interpreter, l, io);
                          else
                                  PIO_stdio_setbuf(interpreter, l, io,
-                                                        PIO_BUFSIZE);
+                                                        PIO_UNBOUND);
                          return io;
                  }
                  l = PIO_DOWNLAYER(l);
@@ -230,8 +241,8 @@
  }


-INTVAL PIO_stdio_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
-                        off_t offset, INTVAL whence) {
+PIOOFF_T PIO_stdio_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
+                        PIOOFF_T offset, INTVAL whence) {
          int hardseek = 0;

          if( io->flags&PIO_F_SHARED ||
@@ -243,22 +254,19 @@
           * Try to satisfy seek request in buffer if possible,
           * else make IO request.
           */
-
-        io->fpos = lseek(io->fd, offset, whence);
+        internal_exception(IO_NOT_IMPLEMENTED, "Seek not implemented");
          return io->fpos;
  }


-off_t PIO_stdio_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io) {
-        off_t p;
-        p = lseek(io->fd, (off_t)0, SEEK_CUR);
-        return p;
+PIOOFF_T PIO_stdio_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io) {
+        return io->fpos;
  }



  ParrotIOLayerAPI        pio_stdio_layer_api = {
-        PIO_base_init,
+        PIO_stdio_init,
          PIO_base_new_layer,
          PIO_base_delete_layer,
          NULL,
Index: io/io_unix.c
===================================================================
RCS file: /cvs/public/parrot/io/io_unix.c,v
retrieving revision 1.3
diff -u -r1.3 io_unix.c
--- io/io_unix.c        12 Jan 2002 15:34:27 -0000      1.3
+++ io/io_unix.c        18 Jan 2002 06:54:40 -0000
@@ -52,9 +52,9 @@
                          ParrotIO * io, const void * buffer, size_t len);
  INTVAL          PIO_unix_puts(theINTERP, ParrotIOLayer * l, ParrotIO * io,
                          const char * s);
-INTVAL          PIO_unix_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
-                        off_t offset, INTVAL whence);
-off_t           PIO_unix_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io);
+PIOOFF_T        PIO_unix_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
+                        PIOOFF_T offset, INTVAL whence);
+PIOOFF_T        PIO_unix_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io);


  UINTVAL flags_to_unix(UINTVAL flags) {
@@ -236,6 +236,38 @@
          return isatty(fd);
  }

+/*
+ * Various ways of determining block size. If passed a descriptor
+ * we can use fstat() and the stat buf if available, or the BLKSIZE
+ * constant if available at compile time.
+ */
+INTVAL PIO_unix_getblksize(PIOHANDLE fd) {
+        if(fd >= 0) {
+                /* Try to get the block size of a regular file */
+#if 0
+                /*
+                 * Is it even worth adding non-portable code here
+                 * or should we just estimate a nice buffer size?
+                 * Some systems have st_blksize, some don't.
+                 */
+                {
+                        struct stat sbuf;
+                        int err;
+                        err = fstat(fd, &sbuf);
+                        if(err == 0) {
+                               return sbuf.st_blksize;
+                        }
+                }
+#endif
+        }
+        /* Try to determine it from general means. */
+#ifdef BLKSIZE
+        return BLKSIZE;
+#else
+        return PIO_BLKSIZE;
+#endif
+}
+
  /* At lowest layer all we can do for flush is ask kernel to sync().
   */
  void PIO_unix_flush(theINTERP, ParrotIOLayer * layer, ParrotIO * io) {
@@ -332,16 +364,16 @@
  /*
   * Hard seek
   */
-INTVAL PIO_unix_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
-                        off_t offset, INTVAL whence) {
+PIOOFF_T PIO_unix_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
+                        PIOOFF_T offset, INTVAL whence) {
          io->fpos = lseek(io->fd, offset, whence);
          return io->fpos;
  }


-off_t PIO_unix_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io) {
-        off_t p;
-        p = lseek(io->fd, (off_t)0, SEEK_CUR);
+PIOOFF_T PIO_unix_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io) {
+        PIOOFF_T p;
+        p = lseek(io->fd, (PIOOFF_T)0, SEEK_CUR);
          return p;
  }

Index: io/io_win32.c
===================================================================
RCS file: /cvs/public/parrot/io/io_win32.c,v
retrieving revision 1.4
diff -u -r1.4 io_win32.c
--- io/io_win32.c       14 Jan 2002 20:04:31 -0000      1.4
+++ io/io_win32.c       18 Jan 2002 06:54:41 -0000
@@ -49,9 +49,9 @@
                          ParrotIO * io, const void * buffer, size_t len);
  INTVAL          PIO_win32_puts(theINTERP, ParrotIOLayer * l, ParrotIO * io,
                          const char * s);
-INTVAL          PIO_win32_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
-                        off_t offset, INTVAL whence);
-off_t           PIO_win32_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io);
+PIOOFF_T        PIO_win32_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
+                        PIOOFF_T offset, INTVAL whence);
+PIOOFF_T        PIO_win32_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io);


  /* Convert to platform specific bit open flags */
@@ -105,6 +105,12 @@
  }


+INTVAL PIO_win32_getblksize(PIOHANDLE fd) {
+        /* Hard coded for now */
+        return PIO_BLKSIZE;
+}
+
+
  ParrotIO * PIO_win32_open(theINTERP, ParrotIOLayer * layer,
                        const char * spath, UINTVAL flags) {
          int type;
@@ -172,38 +178,54 @@
          return 0;
  }

+
  void PIO_win32_flush(theINTERP, ParrotIOLayer * layer, ParrotIO * io) {
+        /* No op */
  }


  size_t PIO_win32_read(theINTERP, ParrotIOLayer * layer, ParrotIO * io,
                                void * buffer, size_t len) {
-        return 0;
+        DWORD countread;
+        if(ReadFile(io->fd, (LPVOID)buffer, (DWORD)len, &countread, NULL))
+                return countread;
+        else {
+                if(GetLastError() != NO_ERROR) {
+                        /* FIXME : An error occured */
+                } else if(len > 0) {
+                        /* FIXME : Set EOF if bytes were requested */
+                }
+                return 0;
+        }
+        return -1;
  }


  size_t PIO_win32_write(theINTERP, ParrotIOLayer * layer, ParrotIO * io,
                        const void * buffer, size_t len) {
-        return 0;
+        LPCTSTR msg;
+        DWORD countwrote = 0;
+        if(WriteFile(io->fd, (LPCSTR)buffer, (DWORD)len, &countwrote, NULL))
+                return countwrote;
+        /* FIXME: Set error flag */
+        return -1;
  }


  /*
- * puts tries WriteConsole first, then WriteFile, whereas
- * write calls WriteFile only.
+ * puts() tries WriteConsole() first, then WriteFile(), whereas
+ * write() calls WriteFile() only. I've also read that WriteFile
+ * will call WriteConsole if the handle is the right type (console) so
+ * I suppose this is saving a function call since puts is probably
+ * used for consoles a lot.
   */
  INTVAL PIO_win32_puts(theINTERP, ParrotIOLayer * l, ParrotIO * io,
                                  const char * s) {
-        LPCTSTR msg;
-        DWORD len, wrote;
-        if((msg = (LPCTSTR)s) != NULL) {
-                len = _tcslen(msg);
-                if(!WriteConsole(io->fd, msg, len, &wrote, NULL)
-                        && !WriteFile(io->fd, msg, len * sizeof(TCHAR),
-                                &wrote, NULL))
-                        return -1;
-                return wrote;
-        }
+        DWORD len, countwrote;
+        len = _tcslen((LPCSTR)s);
+        if(WriteConsole(io->fd, (LPCSTR)s, len, &countwrote, NULL)
+                || WriteFile(io->fd, (LPCSTR)s, len, &countwrote, NULL))
+                return countwrote;
          return -1;
  }

@@ -211,23 +233,26 @@
  /*
   * Hard seek
   */
-INTVAL PIO_win32_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
-                        off_t offset, INTVAL whence) {
-/*        io->fpos = lseek(io->fd, offset, whence);
-        return io->fpos;
-*/
-               internal_exception( IO_NOT_IMPLEMENTED, "Seek not yet implemented on 
HANDLEs");
-               return 0;
+PIOOFF_T PIO_win32_seek(theINTERP, ParrotIOLayer * l, ParrotIO * io,
+                        PIOOFF_T offset, INTVAL whence) {
+        PIOOFF_T p;
+        p.LowPart = SetFilePointer(io->fd, offset.LowPart, &offset.HighPart,
+                                FILE_CURRENT);
+        if(p.LowPart == 0xFFFFFFFF && (GetLastError() != NO_ERROR)) {
+                /* FIXME: Error - exception */
+        }
+        io->fpos = p;
+        return p;
  }


-off_t PIO_win32_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io) {
-/*        off_t p;
-        p = lseek(io->fd, (off_t)0, SEEK_CUR);
+PIOOFF_T PIO_win32_tell(theINTERP, ParrotIOLayer * l, ParrotIO * io) {
+        PIOOFF_T p = piooffsetzero;
+        p.LowPart = SetFilePointer(io->fd, 0, &p.HighPart, FILE_CURRENT);
+        if(p.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+                /* FIXME: Error - exception */
+        }
          return p;
-*/
-               internal_exception( IO_NOT_IMPLEMENTED, "Seek not yet implemented on 
HANDLEs");
-               return 0;
  }



Reply via email to