size_t fread(void *vptr, size_t size, size_t count, FILE *iop)
{
- char *ptr = (char *)vptr;
+ unsigned char *ptr = (unsigned char *)vptr;
size_t to_read ,n_read;
+ int c, copy;
to_read = size * count;
if (vptr == NULL || to_read == 0)
return 0;
- while(iop->_cnt > 0 && to_read > 0 )
- {
- to_read--;
- *ptr++ = getc(iop);
- }
-
- // if the buffer is dirty it will have to be written now
- // otherwise the file pointer won't match anymore.
-
- fflush(iop);
+ if (iop->_base == NULL)
+ {
+ int c = _filbuf(iop);
+ if (c == EOF)
+ return 0;
+ *ptr++ = c;
+ if (--to_read == 0)
+ return 1;
+ }
- // check to see if this will work with in combination with ungetc
+ if (iop->_cnt > 0 && to_read > 0)
+ {
+ copy = min(iop->_cnt, to_read);
+ memcpy(ptr, iop->_ptr, copy);
+ ptr += copy;
+ iop->_ptr += copy;
+ iop->_cnt -= copy;
+ to_read -= copy;
+ if (to_read == 0)
+ return count;
+ }
- n_read = _read(fileno(iop), ptr, to_read);
- if ( n_read != -1 )
- to_read -= n_read;
+ if (to_read > 0)
+ {
- // the file buffer is empty and there is no read ahead information anymore.
- iop->_flag &= ~_IOAHEAD;
+ if (to_read >= iop->_bufsiz)
+ {
+ n_read = _read(fileno(iop), ptr, to_read);
+ if (n_read < 0)
+ iop->_flag |= _IOERR;
+ else if (n_read == 0)
+ iop->_flag |= _IOEOF;
+ else
+ to_read -= n_read;
+ // the file buffer is empty and there is no read ahead information anymore.
+ iop->_flag &= ~_IOAHEAD;
+ }
+ else
+ {
+ c = _filbuf(iop);
+ if (c != EOF)
+ {
+ *ptr++ = c;
+ to_read--;
+ copy = min(iop->_cnt, to_read);
+ memcpy(ptr, iop->_ptr, copy);
+ iop->_ptr += copy;
+ iop->_cnt -= copy;
+ to_read -= copy;
+ }
+ }
+ }
return count - (to_read/size);
}
#include <msvcrt/string.h>
#include <msvcrt/errno.h>
#include <msvcrt/internal/file.h>
+#define NDEBUG
+#include <msvcrt/msvcrtdbg.h>
size_t fwrite(const void *vptr, size_t size, size_t count, FILE *iop)
{
size_t to_write, n_written;
- char *ptr = (char *)vptr;
+ unsigned char *ptr = (unsigned char *)vptr;
+ int copy;
+
+ DPRINT("fwrite(%x, %d, %d, %x)\n", vptr, size, count, iop);
to_write = size*count;
if (!OPEN4WRITING(iop))
if (vptr == NULL || to_write == 0)
return 0;
- while(iop->_cnt > 0 && to_write > 0)
- {
- to_write--;
- putc(*ptr++,iop);
- }
+ if (iop->_base == NULL && !(iop->_flag&_IONBF))
+ {
+ if (EOF == _flsbuf(*ptr++, iop))
+ return 0;
+ if (--to_write == 0)
+ return 1;
+ }
- // if the buffer is dirty it will have to be written now
- // otherwise the file pointer won't match anymore.
- fflush(iop);
+ if (iop->_flag & _IOLBF)
+ {
+ while (to_write > 0)
+ {
+ if (EOF == putc(*ptr++, iop))
+ {
+ iop->_flag |= _IOERR;
+ break;
+ }
+ to_write--;
+ }
+ }
+ else
+ {
+ if (iop->_cnt > 0 && to_write > 0)
+ {
+ copy = min(iop->_cnt, to_write);
+ memcpy(iop->_ptr, ptr, copy);
+ ptr += copy;
+ iop->_ptr += copy;
+ iop->_cnt -= copy;
+ to_write -= copy;
+ iop->_flag |= _IODIRTY;
+ }
- n_written = _write(fileno(iop), ptr,to_write);
- if (n_written != -1)
- to_write -= n_written;
+ if (to_write > 0)
+ {
+ // if the buffer is dirty it will have to be written now
+ // otherwise the file pointer won't match anymore.
+ fflush(iop);
+ if (to_write >= iop->_bufsiz)
+ {
+ while (to_write > 0)
+ {
+ n_written = _write(fileno(iop), ptr, to_write);
+ if (n_written <= 0)
+ {
+ iop->_flag |= _IOERR;
+ break;
+ }
+ to_write -= n_written;
+ ptr += n_written;
+ }
- // check to see if this will work with in combination with ungetc
+ // check to see if this will work with in combination with ungetc
- // the file buffer is empty and there is no read ahead information anymore.
- iop->_flag &= ~_IOAHEAD;
+ // the file buffer is empty and there is no read ahead information anymore.
+ iop->_flag &= ~_IOAHEAD;
+ }
+ else
+ {
+ if (EOF != _flsbuf(*ptr++, iop))
+ {
+ if (--to_write > 0)
+ {
+ memcpy(iop->_ptr, ptr, to_write);
+ iop->_ptr += to_write;
+ iop->_cnt -= to_write;
+ iop->_flag |= _IODIRTY;
+ return count;
+ }
+ }
+ }
+ }
+ }
return count - (to_write/size);
}