bjh         99/10/19 08:24:22

  Modified:    src/lib/apr/file_io/os2 open.c pipe.c readwrite.c seek.c
  Log:
  OS/2: First take at adding buffered file I/O support. Only reads tested so 
far.
  
  Revision  Changes    Path
  1.9       +11 -0     apache-2.0/src/lib/apr/file_io/os2/open.c
  
  Index: open.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/open.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- open.c    1999/10/18 14:55:19     1.8
  +++ open.c    1999/10/19 15:24:19     1.9
  @@ -83,6 +83,7 @@
       dafile->isopen = FALSE;
       dafile->validstatus = FALSE;
       dafile->eof_hit = FALSE;
  +    dafile->buffer = NULL;
       
       if ((flag & APR_READ) && (flag & APR_WRITE)) {
           mflags |= OPEN_ACCESS_READWRITE;
  @@ -131,6 +132,14 @@
       
       dafile->isopen = TRUE;
       dafile->fname = ap_pstrdup(cntxt, fname);
  +    dafile->filePtr = 0;
  +    dafile->bufpos = 0;
  +    dafile->dataRead = 0;
  +    dafile->direction = 0;
  +
  +    if (dafile->buffered)
  +        dafile->buffer = ap_palloc(cntxt, APR_FILE_BUFSIZE);
  +
       ap_register_cleanup(dafile->cntxt, dafile, file_cleanup, 
ap_null_cleanup);
       return APR_SUCCESS;
   }
  @@ -185,6 +194,8 @@
           (*file)->cntxt = cont;
       }
       (*file)->filedes = *dafile;
  +    (*file)->isopen = TRUE;
  +    (*file)->buffered = FALSE;
       return APR_SUCCESS;
   }    
   
  
  
  
  1.5       +2 -0      apache-2.0/src/lib/apr/file_io/os2/pipe.c
  
  Index: pipe.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/pipe.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- pipe.c    1999/10/12 06:14:41     1.4
  +++ pipe.c    1999/10/19 15:24:19     1.5
  @@ -75,6 +75,7 @@
       (*in)->filedes = filedes[0];
       (*in)->fname = ap_pstrdup(cont, "PIPE");
       (*in)->isopen = TRUE;
  +    (*in)->buffered = FALSE;
       ap_register_cleanup(cont, *in, file_cleanup, ap_null_cleanup);
   
       (*out) = (struct file_t *)ap_palloc(cont, sizeof(struct file_t));
  @@ -82,6 +83,7 @@
       (*out)->filedes = filedes[1];
       (*out)->fname = ap_pstrdup(cont, "PIPE");
       (*out)->isopen = TRUE;
  +    (*out)->buffered = FALSE;
       ap_register_cleanup(cont, *out, file_cleanup, ap_null_cleanup);
   
       return APR_SUCCESS;
  
  
  
  1.5       +114 -28   apache-2.0/src/lib/apr/file_io/os2/readwrite.c
  
  Index: readwrite.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/readwrite.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- readwrite.c       1999/10/19 01:59:48     1.4
  +++ readwrite.c       1999/10/19 15:24:19     1.5
  @@ -62,35 +62,77 @@
   
   ap_status_t ap_read(struct file_t *thefile, void *buf, ap_ssize_t *nbytes)
   {
  -    ULONG rc;
  +    ULONG rc = 0;
       ULONG bytesread;
   
       if (!thefile->isopen) {
           *nbytes = 0;
           return APR_EBADF;
       }
  -
  -    rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
   
  -    if (rc) {
  -        *nbytes = 0;
  +    if (thefile->buffered) {
  +        char *pos = (char *)buf;
  +        ULONG blocksize;
  +        ULONG size = *nbytes;
  +
  +        if (thefile->direction == 1) {
  +            ap_flush(thefile);
  +            thefile->bufpos = 0;
  +            thefile->direction = 0;
  +            thefile->dataRead = 0;
  +        }
  +
  +        while (rc == 0 && size > 0) {
  +            if (thefile->bufpos >= thefile->dataRead) {
  +                rc = DosRead(thefile->filedes, thefile->buffer, 
APR_FILE_BUFSIZE, &thefile->dataRead );
  +                if (thefile->dataRead == 0)
  +                    break;
  +                thefile->filePtr += thefile->dataRead;
  +                thefile->bufpos = 0;
  +            }
  +
  +            blocksize = size > thefile->dataRead - thefile->bufpos ? 
thefile->dataRead - thefile->bufpos : size;
  +            memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
  +            thefile->bufpos += blocksize;
  +            pos += blocksize;
  +            size -= blocksize;
  +        }
  +
  +        *nbytes = rc == 0 ? pos - (char *)buf : 0;
  +        
  +        // if an error occurred report it
  +        // if we read some data but hit EOF before reading 'size' bytes, 
return Ok (0)
  +        // if we hit EOF with no data read, return -1
  +        if (size && rc == 0 && pos == (char *)buf) {
  +            thefile->eof_hit = TRUE;
  +            *_errno() = APR_EOF;
  +            return APR_EOF;
  +        }
           return os2errno(rc);
  +    } else {
  +        rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
  +
  +        if (rc) {
  +            *nbytes = 0;
  +            return os2errno(rc);
  +        }
  +
  +        *nbytes = bytesread;
  +        
  +        if (bytesread == 0) {
  +            thefile->eof_hit = TRUE;
  +            return APR_EOF;
  +        }
  +
  +        return APR_SUCCESS;
       }
  -    
  -    if (bytesread == 0) {
  -        thefile->eof_hit = TRUE;
  -        return APR_EOF;
  -    }
  -    
  -    *nbytes = bytesread;
  -    return APR_SUCCESS;
   }
   
   
   
   ap_status_t ap_write(struct file_t *thefile, void *buf, ap_ssize_t *nbytes)
   {
  -    ULONG rc;
  +    ULONG rc = 0;
       ULONG byteswritten;
   
       if (!thefile->isopen) {
  @@ -98,16 +140,44 @@
           return APR_EBADF;
       }
   
  -    rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
  +    if (thefile->buffered) {
  +        char *pos = (char *)buf;
  +        int blocksize;
  +        int size = *nbytes;
  +
  +        if ( thefile->direction == 0 ) {
  +            // Position file pointer for writing at the offset we are 
logically reading from
  +            ULONG offset = thefile->filePtr - thefile->dataRead + 
thefile->bufpos;
  +            if (offset != thefile->filePtr)
  +                DosSetFilePtr(thefile->filedes, offset, FILE_BEGIN, 
&thefile->filePtr );
  +            thefile->bufpos = thefile->dataRead = 0;
  +            thefile->direction = 1;
  +        }
  +
  +        while (rc == 0 && size > 0) {
  +            if (thefile->bufpos == APR_FILE_BUFSIZE)   // write buffer is 
full
  +                ap_flush(thefile);
  +
  +            blocksize = size > APR_FILE_BUFSIZE - thefile->bufpos ? 
APR_FILE_BUFSIZE - thefile->bufpos : size;
  +            memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
  +            thefile->bufpos += blocksize;
  +            pos += blocksize;
  +            size -= blocksize;
  +        }
   
  -    if (rc) {
  -        *nbytes = 0;
           return os2errno(rc);
  +    } else {
  +        rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
  +
  +        if (rc) {
  +            *nbytes = 0;
  +            return os2errno(rc);
  +        }
  +
  +        *nbytes = byteswritten;
  +        thefile->validstatus = FALSE;
  +        return APR_SUCCESS;
       }
  -    
  -    *nbytes = byteswritten;
  -    thefile->validstatus = FALSE;
  -    return APR_SUCCESS;
   }
   
   
  @@ -176,16 +246,17 @@
   ap_status_t ap_getc(char *ch, ap_file_t *thefile)
   {
       ULONG rc;
  -    ULONG bytesread;
  +    int bytesread;
   
       if (!thefile->isopen) {
           return APR_EBADF;
       }
   
  -    rc = DosRead(thefile->filedes, ch, 1, &bytesread);
  +    bytesread = 1;
  +    rc = ap_read(thefile, ch, &bytesread);
   
       if (rc) {
  -        return os2errno(rc);
  +        return rc;
       }
       
       if (bytesread == 0) {
  @@ -210,10 +281,25 @@
   
   ap_status_t ap_flush(ap_file_t *thefile)
   {
  -    /* There isn't anything to do if we aren't buffering the output
  -     * so just return success.
  -     */
  -    return APR_SUCCESS; 
  +    if (thefile->buffered) {
  +        ULONG written = 0;
  +        int rc = 0;
  +
  +        if (thefile->direction == 1 && thefile->bufpos) {
  +            rc = DosWrite(thefile->filedes, thefile->buffer, 
thefile->bufpos, &written);
  +            thefile->filePtr += written;
  +
  +            if (rc == 0)
  +                thefile->bufpos = 0;
  +        }
  +
  +        return os2errno(rc);
  +    } else {
  +        /* There isn't anything to do if we aren't buffering the output
  +         * so just return success.
  +         */
  +        return APR_SUCCESS;
  +    }
   }
   
   
  
  
  
  1.2       +58 -6     apache-2.0/src/lib/apr/file_io/os2/seek.c
  
  Index: seek.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/seek.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- seek.c    1999/08/17 15:59:36     1.1
  +++ seek.c    1999/10/19 15:24:20     1.2
  @@ -64,25 +64,77 @@
   
   int os2errno( ULONG oserror );
   
  +
  +
  +static ap_status_t setptr(struct file_t *thefile, unsigned long pos )
  +{
  +    long newbufpos;
  +    ULONG rc;
  +
  +    if (thefile->direction == 1) {
  +        ap_flush(thefile);
  +        thefile->bufpos = thefile->direction = thefile->dataRead = 0;
  +    }
  +
  +    newbufpos = pos - (thefile->filePtr - thefile->dataRead);
  +    if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
  +        thefile->bufpos = newbufpos;
  +        rc = 0;
  +    } else {
  +        rc = DosSetFilePtr(thefile->filedes, pos, FILE_BEGIN, 
&thefile->filePtr );
  +
  +        if ( !rc )
  +            thefile->bufpos = thefile->dataRead = 0;
  +    }
  +
  +    return os2errno(rc);
  +}
  +
  +
  +
   ap_status_t ap_seek(struct file_t *thefile, ap_seek_where_t where, ap_off_t 
*offset)
   {
       if (!thefile->isopen) {
           return APR_EBADF;
       }
  -    
  -    switch (where) {
  +
  +    if (thefile->buffered) {
  +        int rc = EINVAL;
  +        ap_ssize_t filesize;
  +
  +        switch (where) {
  +        case APR_SET:
  +            rc = setptr(thefile, *offset);
  +            break;
  +
  +        case APR_CUR:
  +            rc = setptr(thefile, thefile->filePtr - thefile->dataRead + 
thefile->bufpos + *offset);
  +            break;
  +
  +        case APR_END:
  +            rc = ap_get_filesize(&filesize, thefile);
  +            if (rc == APR_SUCCESS)
  +                rc = setptr(thefile, filesize - *offset);
  +            break;
  +        }
  +
  +        *offset = thefile->filePtr + thefile->bufpos;
  +        return rc;
  +    } else {
  +        switch (where) {
           case APR_SET:
               where = FILE_BEGIN;
               break;
  -            
  +
           case APR_CUR:
               where = FILE_CURRENT;
               break;
  -            
  +
           case APR_END:
               where = FILE_END;
               break;
  +        }
  +
  +        return os2errno(DosSetFilePtr(thefile->filedes, *offset, where, 
(ULONG *)&offset));
       }
  -            
  -    return os2errno(DosSetFilePtr(thefile->filedes, *offset, where, (ULONG 
*)&offset));
   }
  
  
  

Reply via email to