X-Git-Url: https://pd.if.org/git/?p=pdclib.old;a=blobdiff_plain;f=functions%2Fstdio%2Ffwrite.c;h=d0efadb207df354eabdca050be5819c1756a370d;hp=97bbbd50f22ace32cceb9ecad23813fee6dd4f32;hb=0082c47404ecdeb00e08e1aedbea0f8402cfc906;hpb=e5456e3c2697c4e17fc9aa3439f2e305517b4d96 diff --git a/functions/stdio/fwrite.c b/functions/stdio/fwrite.c index 97bbbd5..d0efadb 100644 --- a/functions/stdio/fwrite.c +++ b/functions/stdio/fwrite.c @@ -1,482 +1,80 @@ -// ---------------------------------------------------------------------------- -// $Id$ -// ---------------------------------------------------------------------------- -// Public Domain C Library - http://pdclib.sourceforge.net -// This code is Public Domain. Use, modify, and redistribute at will. -// ---------------------------------------------------------------------------- +/* $Id$ */ -size_t fwrite( const void * restrict ptr, size_t size, size_t nelem, FILE * restrict stream ) { /* TODO */ }; +/* fwrite( const void *, size_t, size_t, FILE * ) -/* PDPC code - unreviewed, verbatim. -Read the note in fopen.c. -#ifndef __MVS__ -size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - size_t towrite; - size_t elemWritten; -#ifdef __OS2__ - ULONG actualWritten; - APIRET rc; -#endif -#ifdef __MSDOS__ - size_t actualWritten; - int errind; -#endif - - if (nmemb == 1) - { - towrite = size; - } - else if (size == 1) - { - towrite = nmemb; - } - else - { - towrite = size * nmemb; - } - if (towrite < stream->szfbuf) - { - stream->quickBin = 0; - if ((stream->bufTech == _IONBF) && !stream->textMode) - { - stream->quickBin = 1; - } - } - if (!stream->quickBin) - { - fwriteSlow(ptr, size, nmemb, stream, towrite, &elemWritten); - return (elemWritten); - } - else - { -#ifdef __OS2__ - rc = DosWrite(stream->hfile, (VOID *)ptr, towrite, &actualWritten); - if (rc != 0) - { - stream->errorInd = 1; - actualWritten = 0; - errno = rc; - } -#endif -#ifdef __MSDOS__ - actualWritten = __write(stream->hfile, - ptr, - towrite, - &errind); - if (errind) - { - stream->errorInd = 1; - actualWritten = 0; - errno = actualWritten; - } -#endif - if (nmemb == 1) - { - if (actualWritten == size) - { - elemWritten = 1; - } - else - { - elemWritten = 0; - } - } - else if (size == 1) - { - elemWritten = actualWritten; - } - else - { - elemWritten = actualWritten / size; - } - stream->bufStartR += actualWritten; - return (elemWritten); - } -} + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ -static void fwriteSlow(const void *ptr, - size_t size, - size_t nmemb, - FILE *stream, - size_t towrite, - size_t *elemWritten) -{ - size_t actualWritten; - - /* Normally, on output, there will never be a situation where - the write buffer is full, but it hasn't been written out. - If we find this to be the case, then it is because we have - done an fseek, and didn't know whether we were going to do - a read or a write after it, so now that we know, we switch - the buffer to being set up for write. We could use a flag, - but I thought it would be better to just put some magic - code in with a comment */ - if (stream->upto == stream->endbuf) - { - stream->bufStartR += (stream->endbuf - stream->fbuf); - stream->upto = stream->fbuf; - stream->mode = __WRITE_MODE; - } - if ((stream->textMode) || (stream->bufTech == _IOLBF)) - { - fwriteSlowT(ptr, stream, towrite, &actualWritten); - } - else - { - fwriteSlowB(ptr, stream, towrite, &actualWritten); - } - if (nmemb == 1) - { - if (actualWritten == size) - { - *elemWritten = 1; - } - else - { - *elemWritten = 0; - } - } - else if (size == 1) - { - *elemWritten = actualWritten; - } - else - { - *elemWritten = actualWritten / size; - } - return; -} +#include +#ifndef REGTEST +#include <_PDCLIB_io.h> +#include <_PDCLIB_glue.h> -/* can still be called on binary files, if the binary file is - line buffered */ +#include +#include -static void fwriteSlowT(const void *ptr, - FILE *stream, - size_t towrite, - size_t *actualWritten) +size_t _PDCLIB_fwrite_unlocked( const void *restrict vptr, + size_t size, size_t nmemb, + FILE * _PDCLIB_restrict stream ) { - char *p; - char *tptr; - char *oldp; - size_t diffp; - size_t rem; - int fin; -#ifdef __OS2__ - ULONG tempWritten; - APIRET rc; -#endif -#ifdef __MSDOS__ - size_t tempWritten; - int errind; -#endif + if ( _PDCLIB_prepwrite( stream ) == EOF ) + { + return 0; + } - *actualWritten = 0; - tptr = (char *)ptr; - p = tptr; - oldp = p; - p = (char *)memchr(oldp, '\n', towrite - (size_t)(oldp - tptr)); - while (p != NULL) + const char *restrict ptr = vptr; + size_t nmemb_i; + for ( nmemb_i = 0; nmemb_i < nmemb; ++nmemb_i ) { - diffp = (size_t)(p - oldp); - fin = 0; - while (!fin) + for ( size_t size_i = 0; size_i < size; ++size_i ) { - rem = (size_t)(stream->endbuf - stream->upto); - if (diffp < rem) - { - memcpy(stream->upto, oldp, diffp); - stream->upto += diffp; - *actualWritten += diffp; - fin = 1; - } - else + char c = ptr[ nmemb_i * size + size_i ]; + stream->buffer[ stream->bufidx++ ] = c; + + if ( stream->bufidx == stream->bufsize || ( c == '\n' && stream->status & _IOLBF ) ) { - memcpy(stream->upto, oldp, rem); - oldp += rem; - diffp -= rem; -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - stream->fbuf, - stream->szfbuf, - &tempWritten); - if (rc != 0) - { - stream->errorInd = 1; - return; - } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - stream->fbuf, - stream->szfbuf, - &errind); - if (errind) - { - stream->errorInd = 1; - return; - } -#endif - else + if ( _PDCLIB_flushbuffer( stream ) == EOF ) { - *actualWritten += rem; - stream->upto = stream->fbuf; - stream->bufStartR += tempWritten; + /* Returning number of objects completely buffered */ + return nmemb_i; } } } - rem = (size_t)(stream->endbuf - stream->upto); - if (rem < 2) - { -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - stream->fbuf, - (size_t)(stream->upto - stream->fbuf), - &tempWritten); - if (rc != 0) - { - stream->errorInd = 1; - errno = rc; - return; - } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - stream->fbuf, - (size_t)(stream->upto - stream->fbuf), - &errind); - if (errind) - { - stream->errorInd = 1; - errno = tempWritten; - return; - } -#endif - stream->upto = stream->fbuf; - stream->bufStartR += tempWritten; - } - if (stream->textMode) - { - memcpy(stream->upto, "\r\n", 2); - stream->upto += 2; - } - else - { - memcpy(stream->upto, "\n", 1); - stream->upto += 1; - } - *actualWritten += 1; - oldp = p + 1; - p = (char *)memchr(oldp, '\n', towrite - (size_t)(oldp - tptr)); - } - - if ((stream->bufTech == _IOLBF) - && (stream->upto != stream->fbuf) - && (oldp != tptr)) - { -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - stream->fbuf, - (size_t)(stream->upto - stream->fbuf), - &tempWritten); - if (rc != 0) - { - stream->errorInd = 1; - errno = rc; - return; - } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - stream->fbuf, - (size_t)(stream->upto - stream->fbuf), - &errind); - if (errind) - { - stream->errorInd = 1; - errno = tempWritten; - return; - } -#endif - stream->upto = stream->fbuf; - stream->bufStartR += tempWritten; - } - diffp = towrite - *actualWritten; - while (diffp != 0) - { - rem = (size_t)(stream->endbuf - stream->upto); - if (diffp < rem) - { - memcpy(stream->upto, oldp, diffp); - stream->upto += diffp; - *actualWritten += diffp; - } - else + if ( stream->status & _IONBF ) { - memcpy(stream->upto, oldp, rem); -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - stream->fbuf, - stream->szfbuf, - &tempWritten); - if (rc != 0) + if ( _PDCLIB_flushbuffer( stream ) == EOF ) { - stream->errorInd = 1; - errno = rc; - return; + /* Returning number of objects completely buffered */ + return nmemb_i; } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - stream->fbuf, - stream->szfbuf, - &errind); - if (errind) - { - stream->errorInd = 1; - errno = tempWritten; - return; - } -#endif - else - { - *actualWritten += rem; - stream->upto = stream->fbuf; - } - stream->bufStartR += tempWritten; - oldp += rem; } - diffp = towrite - *actualWritten; } - if ((stream->bufTech == _IONBF) - && (stream->upto != stream->fbuf)) - { -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - stream->fbuf, - (size_t)(stream->upto - stream->fbuf), - &tempWritten); - if (rc != 0) - { - stream->errorInd = 1; - errno = rc; - return; - } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - stream->fbuf, - (size_t)(stream->upto - stream->fbuf), - &errind); - if (errind) - { - stream->errorInd = 1; - errno = tempWritten; - return; - } -#endif - stream->upto = stream->fbuf; - stream->bufStartR += tempWritten; - } - return; + return nmemb_i; } -/* whilst write requests are smaller than a buffer, we do not turn - on quickbin */ - -static void fwriteSlowB(const void *ptr, - FILE *stream, - size_t towrite, - size_t *actualWritten) +size_t fwrite( const void * _PDCLIB_restrict ptr, + size_t size, size_t nmemb, + FILE * _PDCLIB_restrict stream ) { - size_t spare; -#ifdef __OS2__ - ULONG tempWritten; - APIRET rc; -#endif -#ifdef __MSDOS__ - size_t tempWritten; - int errind; -#endif + _PDCLIB_flockfile( stream ); + size_t r = _PDCLIB_fwrite_unlocked( ptr, size, nmemb, stream ); + _PDCLIB_funlockfile( stream ); + return r; +} - spare = (size_t)(stream->endbuf - stream->upto); - if (towrite < spare) - { - memcpy(stream->upto, ptr, towrite); - *actualWritten = towrite; - stream->upto += towrite; - return; - } - memcpy(stream->upto, ptr, spare); -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - stream->fbuf, - stream->szfbuf, - &tempWritten); - if (rc != 0) - { - stream->errorInd = 1; - errno = rc; - return; - } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - stream->fbuf, - stream->szfbuf, - &errind); - if (errind) - { - stream->errorInd = 1; - errno = tempWritten; - return; - } #endif - *actualWritten = spare; - stream->upto = stream->fbuf; - stream->bufStartR += tempWritten; - if (towrite > stream->szfbuf) - { - stream->quickBin = 1; -#ifdef __OS2__ - rc = DosWrite(stream->hfile, - (char *)ptr + *actualWritten, - towrite - *actualWritten, - &tempWritten); - if (rc != 0) - { - stream->errorInd = 1; - errno = rc; - return; - } -#endif -#ifdef __MSDOS__ - tempWritten = __write(stream->hfile, - (char *)ptr + *actualWritten, - towrite - *actualWritten, - &errind); - if (errind) - { - stream->errorInd = 1; - errno = tempWritten; - return; - } -#endif - *actualWritten += tempWritten; - stream->bufStartR += tempWritten; - } - else - { - memcpy(stream->fbuf, - (char *)ptr + *actualWritten, - towrite - *actualWritten); - stream->upto += (towrite - *actualWritten); - *actualWritten = towrite; - } - stream->bufStartR += *actualWritten; - return; + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by fread(). */ + return TEST_RESULTS; } + #endif -*/ +