update for HEAD-2003091401
[reactos.git] / lib / msvcrt / stdio / fread.c
1 #include <msvcrt/stdio.h>
2 #include <msvcrt/stdlib.h>
3 #include <msvcrt/string.h>
4 #include <msvcrt/errno.h>
5 #include <msvcrt/internal/file.h>
6
7
8 /*
9  * @implemented
10  */
11 size_t fread(void *vptr, size_t size, size_t count, FILE *iop)
12 {
13   unsigned char *ptr = (unsigned char *)vptr;
14   size_t  to_read ,n_read;
15   int c, copy;
16
17   to_read = size * count;
18   
19   if (!OPEN4READING(iop))
20     {
21       __set_errno (EINVAL);
22       return 0;
23     }
24
25   if (!__validfp (iop) )
26     {
27       __set_errno (EINVAL);
28       return 0;
29     }
30   if (feof (iop) || ferror (iop))
31     return 0;
32
33   if (vptr == NULL || to_read == 0)
34     return 0;
35
36   if (iop->_base == NULL)
37   {
38     int c = _filbuf(iop);
39     if (c == EOF)
40       return 0;
41     *ptr++ = c;
42     if (--to_read == 0)
43       return 1;
44   }
45
46   if (iop->_cnt > 0 && to_read > 0)
47   {
48      copy = min(iop->_cnt, to_read);
49      memcpy(ptr, iop->_ptr, copy);
50      ptr += copy;
51      iop->_ptr += copy;
52      iop->_cnt -= copy;
53      to_read -= copy;
54      if (to_read == 0)
55        return count;
56   }
57
58   if (to_read > 0)
59   {
60
61     if (to_read >= iop->_bufsiz)
62     {
63        n_read = _read(fileno(iop), ptr, to_read);
64            if (n_read < 0)
65                   iop->_flag |= _IOERR;
66            else if (n_read == 0)
67                   iop->_flag |= _IOEOF;
68            else
69           to_read -= n_read;
70
71        // the file buffer is empty and there is no read ahead information anymore.
72        iop->_flag &= ~_IOAHEAD;
73     }
74     else
75     {
76        c = _filbuf(iop);
77        if (c != EOF)
78        {
79               *ptr++ = c;
80               to_read--;
81           copy = min(iop->_cnt, to_read);
82           memcpy(ptr, iop->_ptr, copy);
83           iop->_ptr += copy;
84           iop->_cnt -= copy;
85           to_read -= copy;
86        }
87     }
88   }
89   return count - (to_read/size);
90 }