Reverted latest changes.
[reactos.git] / reactos / lib / msvcrt / stdio / fwrite.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 #define NDEBUG
7 #include <msvcrt/msvcrtdbg.h>
8
9
10 size_t fwrite(const void *vptr, size_t size, size_t count, FILE *iop)
11 {
12 size_t to_write, n_written;
13 unsigned char *ptr = (unsigned char *)vptr;
14 int copy;
15
16 DPRINT("fwrite(%x, %d, %d, %x)\n", vptr, size, count, iop);
17
18 to_write = size*count;
19 if (!OPEN4WRITING(iop))
20 {
21 __set_errno (EINVAL);
22 return 0;
23 }
24
25 if (iop == NULL)
26 {
27 __set_errno (EINVAL);
28 return 0;
29 }
30
31 if (ferror (iop))
32 return 0;
33 if (vptr == NULL || to_write == 0)
34 return 0;
35
36 if (iop->_base == NULL && !(iop->_flag&_IONBF))
37 {
38 if (EOF == _flsbuf(*ptr++, iop))
39 return 0;
40 if (--to_write == 0)
41 return 1;
42 }
43
44 if (iop->_flag & _IOLBF)
45 {
46 while (to_write > 0)
47 {
48 if (EOF == putc(*ptr++, iop))
49 {
50 iop->_flag |= _IOERR;
51 break;
52 }
53 to_write--;
54 }
55 }
56 else
57 {
58 if (iop->_cnt > 0 && to_write > 0)
59 {
60 copy = min(iop->_cnt, to_write);
61 memcpy(iop->_ptr, ptr, copy);
62 ptr += copy;
63 iop->_ptr += copy;
64 iop->_cnt -= copy;
65 to_write -= copy;
66 iop->_flag |= _IODIRTY;
67 }
68
69 if (to_write > 0)
70 {
71 // if the buffer is dirty it will have to be written now
72 // otherwise the file pointer won't match anymore.
73 fflush(iop);
74 if (to_write >= iop->_bufsiz)
75 {
76 while (to_write > 0)
77 {
78 n_written = _write(fileno(iop), ptr, to_write);
79 if (n_written <= 0)
80 {
81 iop->_flag |= _IOERR;
82 break;
83 }
84 to_write -= n_written;
85 ptr += n_written;
86 }
87
88 // check to see if this will work with in combination with ungetc
89
90 // the file buffer is empty and there is no read ahead information anymore.
91 iop->_flag &= ~_IOAHEAD;
92 }
93 else
94 {
95 if (EOF != _flsbuf(*ptr++, iop))
96 {
97 if (--to_write > 0)
98 {
99 memcpy(iop->_ptr, ptr, to_write);
100 iop->_ptr += to_write;
101 iop->_cnt -= to_write;
102 iop->_flag |= _IODIRTY;
103 return count;
104 }
105 }
106 }
107 }
108 }
109
110 return count - (to_write/size);
111 }