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