home *** CD-ROM | disk | FTP | other *** search
- /* from Dale Schumacher's dLibs */
-
- #include <stddef.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <limits.h>
- #include <assert.h>
- #include <string.h>
- #include "lib.h"
-
- size_t fwrite(_data, size, count, fp)
- const void *_data;
- size_t size;
- size_t count;
- register FILE *fp;
- {
- const char *data=_data;
- register size_t n, m;
- register long l = 0;
- long space;
- unsigned int f = fp->_flag;
- const char *restart_buf;
- int have_nl;
- int wrote_cr;
- int line_flush;
-
- if(f & _IORW)
- {
- fp->_flag |= _IOWRT;
- f = (fp->_flag &= ~(_IOREAD | _IOEOF));
- }
-
- if(!(f & _IOWRT) /* not opened for write? */
- || (f & (_IOERR | _IOEOF))) /* error/eof conditions? */
- return(0);
-
- assert ((data != NULL));
- assert ((size != 0));
- n = count * size;
- assert ( n <= (size_t)LONG_MAX); /* otherwise impl will not work */
-
- if( f&_IOBIN ) {
- space = fp->_bsiz - fp->_cnt;
- while(n > 0)
- {
- m = (n > space)? space: n;
- bcopy(data, fp->_ptr, m);
- fp->_ptr += m;
- fp->_cnt += m;
- space -= m;
- if(space == 0)
- {
- if(fflush(fp))
- return 0;
- space = fp->_bsiz;
- if(f & _IORW)
- fp->_flag |= _IOWRT; /* fflush resets this */
- }
- l += m;
- data += m;
- n -= m;
- if(n < space)
- continue;
- if((m = _write(fp->_file, data, (unsigned long)n )) != (long)n)
- {
- fp->_flag |= _IOERR;
- return 0;
- }
- l += m;
- break;
- }
- } else {
- have_nl=1;
- wrote_cr=0;
- line_flush=0;
- /* this relies on having at least one byte buffer,
- otherwise we'll hang up when trying to write CRLF */
- while(n > 0)
- {
- space = fp->_bsiz - fp->_cnt;
- restart_buf=data;
- while( space>0 && n>0 ) {
- if( *data=='\n' ) {
- if( !wrote_cr ) {
- if( f&_IOLBF ) line_flush=1;
- *fp->_ptr++='\r';
- wrote_cr=1;
- have_nl=1;
- l--; /* compensate for the increment below */
- } else {
- *fp->_ptr++='\n';
- data++;
- wrote_cr=0;
- n--;
- }
- } else {
- *fp->_ptr++=*data++;
- n--;
- }
- space--;
- fp->_cnt++;
- l++;
- }
-
- if( space==0 ) {
- if( have_nl ) {
- if(fflush(fp))
- return 0;
- if(f & _IORW)
- fp->_flag |= _IOWRT; /* fflush resets this */
- have_nl=0;
- } else {
- /* this will probably happen in nonbuffered mode only:
- try to write as much data in one go as possible */
- fp->_cnt=0;
- fp->_ptr=fp->_base;
- while( n && *data!='\n' ) {
- n--;
- data++;
- }
- if( (m=_write(fp->_file, restart_buf, data-restart_buf ))
- != data-restart_buf ) {
- fp->_flag |= _IOERR;
- return 0;
- }
- l+=m;
- }
- }
- }
- if( line_flush ) {
- if(fflush(fp))
- return 0;
- if(f & _IORW)
- fp->_flag |= _IOWRT; /* fflush resets this */
- }
- }
-
- return((l > 0) ? ((size_t)l / size) : 0);
- }
-