diff --git a/reactos/lib/msvcrt/stdio/fread.c b/reactos/lib/msvcrt/stdio/fread.c index 96a39684af2..d5f3369bb00 100644 --- a/reactos/lib/msvcrt/stdio/fread.c +++ b/reactos/lib/msvcrt/stdio/fread.c @@ -7,8 +7,9 @@ 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; @@ -29,25 +30,58 @@ size_t fread(void *vptr, size_t size, size_t count, FILE *iop) if (vptr == NULL || to_read == 0) return 0; - while(iop->_cnt > 0 && to_read > 0 ) + if (iop->_base == NULL) + { + int c = _filbuf(iop); + if (c == EOF) + return 0; + *ptr++ = c; + if (--to_read == 0) + return 1; + } + + 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; + } + + if (to_read > 0) + { + + if (to_read >= iop->_bufsiz) { - to_read--; - *ptr++ = getc(iop); + 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; } - - // if the buffer is dirty it will have to be written now - // otherwise the file pointer won't match anymore. - - fflush(iop); - - // check to see if this will work with in combination with ungetc - - n_read = _read(fileno(iop), ptr, to_read); - if ( n_read != -1 ) - 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); } diff --git a/reactos/lib/msvcrt/stdio/fwrite.c b/reactos/lib/msvcrt/stdio/fwrite.c index 87d01d1a486..c5f573ed0a1 100644 --- a/reactos/lib/msvcrt/stdio/fwrite.c +++ b/reactos/lib/msvcrt/stdio/fwrite.c @@ -3,12 +3,17 @@ #include #include #include +#define NDEBUG +#include 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)) @@ -28,24 +33,79 @@ size_t fwrite(const void *vptr, size_t size, size_t count, FILE *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); }