1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
4 // Public Domain C Library - http://pdclib.sourceforge.net
5 // This code is Public Domain. Use, modify, and redistribute at will.
6 // ----------------------------------------------------------------------------
8 size_t fwrite( const void * restrict ptr, size_t size, size_t nelem, FILE * restrict stream ) { /* TODO */ };
10 /* PDPC code - unreviewed, verbatim.
11 Read the note in fopen.c.
13 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
36 towrite = size * nmemb;
38 if (towrite < stream->szfbuf)
41 if ((stream->bufTech == _IONBF) && !stream->textMode)
46 if (!stream->quickBin)
48 fwriteSlow(ptr, size, nmemb, stream, towrite, &elemWritten);
54 rc = DosWrite(stream->hfile, (VOID *)ptr, towrite, &actualWritten);
63 actualWritten = __write(stream->hfile,
71 errno = actualWritten;
76 if (actualWritten == size)
87 elemWritten = actualWritten;
91 elemWritten = actualWritten / size;
93 stream->bufStartR += actualWritten;
98 static void fwriteSlow(const void *ptr,
105 size_t actualWritten;
107 /* Normally, on output, there will never be a situation where
108 the write buffer is full, but it hasn't been written out.
109 If we find this to be the case, then it is because we have
110 done an fseek, and didn't know whether we were going to do
111 a read or a write after it, so now that we know, we switch
112 the buffer to being set up for write. We could use a flag,
113 but I thought it would be better to just put some magic
114 code in with a comment */
115 if (stream->upto == stream->endbuf)
117 stream->bufStartR += (stream->endbuf - stream->fbuf);
118 stream->upto = stream->fbuf;
119 stream->mode = __WRITE_MODE;
121 if ((stream->textMode) || (stream->bufTech == _IOLBF))
123 fwriteSlowT(ptr, stream, towrite, &actualWritten);
127 fwriteSlowB(ptr, stream, towrite, &actualWritten);
131 if (actualWritten == size)
142 *elemWritten = actualWritten;
146 *elemWritten = actualWritten / size;
152 /* can still be called on binary files, if the binary file is
155 static void fwriteSlowT(const void *ptr,
158 size_t *actualWritten)
179 p = (char *)memchr(oldp, '\n', towrite - (size_t)(oldp - tptr));
182 diffp = (size_t)(p - oldp);
186 rem = (size_t)(stream->endbuf - stream->upto);
189 memcpy(stream->upto, oldp, diffp);
190 stream->upto += diffp;
191 *actualWritten += diffp;
196 memcpy(stream->upto, oldp, rem);
200 rc = DosWrite(stream->hfile,
206 stream->errorInd = 1;
211 tempWritten = __write(stream->hfile,
217 stream->errorInd = 1;
223 *actualWritten += rem;
224 stream->upto = stream->fbuf;
225 stream->bufStartR += tempWritten;
229 rem = (size_t)(stream->endbuf - stream->upto);
233 rc = DosWrite(stream->hfile,
235 (size_t)(stream->upto - stream->fbuf),
239 stream->errorInd = 1;
245 tempWritten = __write(stream->hfile,
247 (size_t)(stream->upto - stream->fbuf),
251 stream->errorInd = 1;
256 stream->upto = stream->fbuf;
257 stream->bufStartR += tempWritten;
259 if (stream->textMode)
261 memcpy(stream->upto, "\r\n", 2);
266 memcpy(stream->upto, "\n", 1);
271 p = (char *)memchr(oldp, '\n', towrite - (size_t)(oldp - tptr));
274 if ((stream->bufTech == _IOLBF)
275 && (stream->upto != stream->fbuf)
279 rc = DosWrite(stream->hfile,
281 (size_t)(stream->upto - stream->fbuf),
285 stream->errorInd = 1;
291 tempWritten = __write(stream->hfile,
293 (size_t)(stream->upto - stream->fbuf),
297 stream->errorInd = 1;
302 stream->upto = stream->fbuf;
303 stream->bufStartR += tempWritten;
306 diffp = towrite - *actualWritten;
309 rem = (size_t)(stream->endbuf - stream->upto);
312 memcpy(stream->upto, oldp, diffp);
313 stream->upto += diffp;
314 *actualWritten += diffp;
318 memcpy(stream->upto, oldp, rem);
320 rc = DosWrite(stream->hfile,
326 stream->errorInd = 1;
332 tempWritten = __write(stream->hfile,
338 stream->errorInd = 1;
345 *actualWritten += rem;
346 stream->upto = stream->fbuf;
348 stream->bufStartR += tempWritten;
351 diffp = towrite - *actualWritten;
353 if ((stream->bufTech == _IONBF)
354 && (stream->upto != stream->fbuf))
357 rc = DosWrite(stream->hfile,
359 (size_t)(stream->upto - stream->fbuf),
363 stream->errorInd = 1;
369 tempWritten = __write(stream->hfile,
371 (size_t)(stream->upto - stream->fbuf),
375 stream->errorInd = 1;
380 stream->upto = stream->fbuf;
381 stream->bufStartR += tempWritten;
386 /* whilst write requests are smaller than a buffer, we do not turn
389 static void fwriteSlowB(const void *ptr,
392 size_t *actualWritten)
404 spare = (size_t)(stream->endbuf - stream->upto);
407 memcpy(stream->upto, ptr, towrite);
408 *actualWritten = towrite;
409 stream->upto += towrite;
412 memcpy(stream->upto, ptr, spare);
414 rc = DosWrite(stream->hfile,
420 stream->errorInd = 1;
426 tempWritten = __write(stream->hfile,
432 stream->errorInd = 1;
437 *actualWritten = spare;
438 stream->upto = stream->fbuf;
439 stream->bufStartR += tempWritten;
440 if (towrite > stream->szfbuf)
442 stream->quickBin = 1;
444 rc = DosWrite(stream->hfile,
445 (char *)ptr + *actualWritten,
446 towrite - *actualWritten,
450 stream->errorInd = 1;
456 tempWritten = __write(stream->hfile,
457 (char *)ptr + *actualWritten,
458 towrite - *actualWritten,
462 stream->errorInd = 1;
467 *actualWritten += tempWritten;
468 stream->bufStartR += tempWritten;
473 (char *)ptr + *actualWritten,
474 towrite - *actualWritten);
475 stream->upto += (towrite - *actualWritten);
476 *actualWritten = towrite;
478 stream->bufStartR += *actualWritten;