Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  Implementation of fread() - read data from stream.
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. #include "variety.h"
  33. #include <stdio.h>
  34. #include <unistd.h>
  35. #include "fileacc.h"
  36. #include <string.h>
  37. #include <errno.h>
  38. #include "rtdata.h"
  39. #include "seterrno.h"
  40. #include "qread.h"
  41. #include "streamio.h"
  42.  
  43.  
  44. #define DOS_EOF_CHAR    0x1a
  45.  
  46. extern int  __fill_buffer( FILE * );    /* located in fgetc */
  47.  
  48.  
  49. _WCRTLINK size_t fread( void *_buf, size_t size, size_t n, FILE *fp )
  50. {
  51.     char    *buf = _buf;
  52.     size_t  len_read;
  53.  
  54.     _ValidFile( fp, 0 );
  55.     _AccessFile( fp );
  56.     if( (fp->_flag & _READ) == 0 ) {
  57.         __set_errno( EBADF );
  58.         fp->_flag |= _SFERR;
  59.         _ReleaseFile( fp );
  60.         return( 0 );
  61.     }
  62.  
  63. #if 0
  64.     /*** If the buffer is _DIRTY, resync it before reading ***/
  65.     if( fp->_flag & (_WRITE | _UNGET) ) {
  66.         if( fp->_flag & _DIRTY ) {
  67.             fseek( fp, 0, SEEK_CUR );
  68.         }
  69.     }
  70. #endif
  71.  
  72.     n *= size;
  73.     if( n == 0 ) {
  74.         _ReleaseFile( fp );
  75.         return( n );
  76.     }
  77.     if( _FP_BASE(fp) == NULL ) {
  78.         __ioalloc( fp );                        /* allocate buffer */
  79.     }
  80.     len_read = 0;
  81. #if !defined( __UNIX__ )
  82.     if( fp->_flag & _BINARY )
  83. #endif
  84.     {
  85.         size_t bytes_left = n, bytes;
  86.         for( ;; ) {
  87.             if( fp->_cnt != 0 ) {
  88.                 bytes = fp->_cnt;
  89.                 if( bytes > bytes_left ) {
  90.                     bytes = bytes_left;
  91.                 }
  92.                 memcpy( buf, fp->_ptr, bytes );
  93.                 fp->_ptr += bytes;
  94.                 buf += bytes;
  95.                 fp->_cnt -= bytes;
  96.                 bytes_left -= bytes;
  97.                 len_read += bytes;
  98.             }
  99.             if( bytes_left == 0 ) break;
  100.  
  101.             /* if user's buffer is larger than our buffer, OR
  102.                _IONBF is set, then read directly into user's buffer. */
  103.  
  104.             if( (bytes_left >= fp->_bufsize) || (fp->_flag & _IONBF) ) {
  105.                 bytes = bytes_left;
  106.                 fp->_ptr = _FP_BASE(fp);
  107.                 fp->_cnt = 0;
  108.                 if( !(fp->_flag & _IONBF) ) {
  109.                     /* if more than a sector, set to multiple of sector size*/
  110.                     if( bytes > 512 ) {
  111.                         bytes &= -512;
  112.                     }
  113.                 }
  114.                 n = __qread( fileno(fp), buf, bytes );
  115.                 if( n == -1 ) {
  116.                     fp->_flag |= _SFERR;
  117.                     break;
  118.                 } else if( n == 0 ) {
  119.                     fp->_flag |= _EOF;
  120.                     break;
  121.                 }
  122.                 buf += n;
  123.                 bytes_left -= n;
  124.                 len_read += n;
  125.             } else {
  126.                 if( __fill_buffer( fp ) == 0 )  break;
  127.             }
  128.         } /* end for */
  129. #if !defined(__UNIX__)
  130.     } else {
  131.         for( ;; ) {
  132.             int c;
  133.  
  134.             // ensure non-empty buffer
  135.             if( fp->_cnt == 0 ) {
  136.                 if( __fill_buffer( fp ) == 0 ) break;
  137.             }
  138.             // get character
  139.             --fp->_cnt;
  140.             c = *fp->_ptr++ & 0xff;
  141.             // perform new-line translation
  142.             if( c == '\r' ) {
  143.                 // ensure non-empty buffer
  144.                 if( fp->_cnt == 0 ) {
  145.                     if( __fill_buffer( fp ) == 0 ) break;
  146.                 }
  147.                 // get character
  148.                 --fp->_cnt;
  149.                 c = *fp->_ptr++ & 0xff;
  150.             }
  151.             // check for DOS end of file marker
  152.             if( c == DOS_EOF_CHAR ) {
  153.                 fp->_flag |= _EOF;
  154.                 break;
  155.             }
  156.             // store chracter
  157.             buf[len_read] = (char)c;
  158.             ++len_read;
  159.             if( len_read == n ) break;
  160.         }
  161. #endif
  162.     }
  163.     _ReleaseFile( fp );
  164.     return( len_read / size );
  165. }
  166.