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