home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / fwrite.c < prev    next >
C/C++ Source or Header  |  1992-10-12  |  3KB  |  142 lines

  1. /* from Dale Schumacher's dLibs */
  2.  
  3. #include <stddef.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <limits.h>
  7. #include <assert.h>
  8. #include <string.h>
  9. #include "lib.h"
  10.  
  11. extern short __FRW_BIN__;
  12.  
  13. size_t    fwrite(_data, size, count, fp)
  14. const void *_data;
  15. size_t size;
  16. size_t count;
  17. register FILE *fp;
  18. {
  19.     const char *data=_data;
  20.     register size_t n, m;
  21.     register long l = 0;
  22.     long space;
  23.     unsigned int f = fp->_flag;
  24.     const char *restart_buf;
  25.     int have_nl;
  26.     int wrote_cr;
  27.     int line_flush;
  28.  
  29.     if( (f & _IORW) || __FRW_BIN__ )
  30.     {
  31.         fp->_flag |= _IOWRT;
  32.         f = (fp->_flag &= ~(_IOREAD | _IOEOF));
  33.     }
  34.  
  35.     if(!(f & _IOWRT)            /* not opened for write? */
  36.     || (f & (_IOERR | _IOEOF)))        /* error/eof conditions? */
  37.         return(0);
  38.  
  39.     assert ((data != NULL));
  40.     assert ((size != 0));
  41.     n =  count * size;
  42.     assert ( n <= (size_t)LONG_MAX);  /* otherwise impl will not work */
  43.  
  44.     if( f&_IOBIN ) {
  45.       space = fp->_bsiz - fp->_cnt;
  46.       while(n > 0)
  47.       {
  48.           m = (n > space)? space: n;
  49.           bcopy(data, fp->_ptr, m);
  50.           fp->_ptr += m;
  51.           fp->_cnt += m;
  52.           space -= m;
  53.           if(space == 0)
  54.           {
  55.           if(fflush(fp))
  56.               return 0;
  57.           space = fp->_bsiz;
  58.           if(f & _IORW)
  59.               fp->_flag |= _IOWRT; /* fflush resets this */
  60.           }
  61.           l += m;
  62.           data += m;
  63.           n -= m;
  64.           if(n < space)
  65.           continue;
  66.           if((m = _write(fp->_file, data, (unsigned long)n )) != (long)n)
  67.           {
  68.           fp->_flag |= _IOERR;
  69.           return 0;
  70.           }
  71.           l += m;
  72.           break;
  73.       }
  74.     } else {
  75.       have_nl=1;
  76.       wrote_cr=0;
  77.       line_flush=0;
  78.       /* this relies on having at least one byte buffer,
  79.          otherwise we'll hang up when trying to write CRLF */
  80.       while(n > 0)
  81.       {
  82.           space = fp->_bsiz - fp->_cnt;
  83.           restart_buf=data;
  84.           while( space>0 && n>0 ) {
  85.         if( *data=='\n' ) {
  86.           if( !wrote_cr ) {
  87.             if( f&_IOLBF ) line_flush=1;
  88.             *fp->_ptr++='\r';
  89.             wrote_cr=1;
  90.             have_nl=1;
  91.                 l--;    /* compensate for the increment below */
  92.           } else {
  93.             *fp->_ptr++='\n';
  94.             data++;
  95.             wrote_cr=0;
  96.             n--;
  97.           }
  98.         } else {
  99.           *fp->_ptr++=*data++;
  100.           n--;
  101.         }
  102.         space--;
  103.         fp->_cnt++;
  104.         l++;
  105.           }
  106.  
  107.           if( space==0 ) {
  108.         if( have_nl ) {
  109.           if(fflush(fp))
  110.               return 0;
  111.           if(f & _IORW)
  112.               fp->_flag |= _IOWRT; /* fflush resets this */
  113.           have_nl=0;
  114.         } else {
  115.         /* this will probably happen in nonbuffered mode only:
  116.            try to write as much data in one go as possible */
  117.           fp->_cnt=0;
  118.           fp->_ptr=fp->_base;
  119.           while( n && *data!='\n' ) {
  120.             n--;
  121.             data++;
  122.           }
  123.           if( (m=_write(fp->_file, restart_buf, data-restart_buf ))
  124.               != data-restart_buf ) {
  125.             fp->_flag |= _IOERR;
  126.             return 0;
  127.           }
  128.           l+=m;
  129.         }
  130.           }
  131.       }
  132.       if( line_flush ) {
  133.          if(fflush(fp))
  134.          return 0;
  135.          if(f & _IORW)
  136.          fp->_flag |= _IOWRT; /* fflush resets this */
  137.       }
  138.     }
  139.  
  140.     return((l > 0) ? ((size_t)l / size) : 0);
  141. }
  142.