sl@0: /* FREAD.C
sl@0:  * 
sl@0:  * Portions Copyright (c) 1990-2005 Nokia Corporation and/or its subsidiary(-ies).
sl@0:  * All rights reserved.
sl@0:  */
sl@0: 
sl@0: /*
sl@0:  * Copyright (c) 1990 The Regents of the University of California.
sl@0:  * All rights reserved.
sl@0:  *
sl@0:  * Redistribution and use in source and binary forms are permitted
sl@0:  * provided that the above copyright notice and this paragraph are
sl@0:  * duplicated in all such forms and that any documentation,
sl@0:  * advertising materials, and other materials related to such
sl@0:  * distribution and use acknowledge that the software was developed
sl@0:  * by the University of California, Berkeley.  The name of the
sl@0:  * University may not be used to endorse or promote products derived
sl@0:  * from this software without specific prior written permission.
sl@0:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
sl@0:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
sl@0:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
sl@0:  */
sl@0: 
sl@0: /*
sl@0: FUNCTION
sl@0: <<fread>>---read array elements from a file
sl@0: 
sl@0: INDEX
sl@0: 	fread
sl@0: 
sl@0: ANSI_SYNOPSIS
sl@0: 	#include <stdio.h>
sl@0: 	size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>,
sl@0: 		     FILE *<[fp]>);
sl@0: 
sl@0: TRAD_SYNOPSIS
sl@0: 	#include <stdio.h>
sl@0: 	size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>)
sl@0: 	char *<[buf]>;
sl@0: 	size_t <[size]>;
sl@0: 	size_t <[count]>;
sl@0: 	FILE *<[fp]>;
sl@0: 
sl@0: DESCRIPTION
sl@0: <<fread>> attempts to copy, from the file or stream identified by
sl@0: <[fp]>, <[count]> elements (each of size <[size]>) into memory,
sl@0: starting at <[buf]>.   <<fread>> may copy fewer elements than
sl@0: <[count]> if an error, or end of file, intervenes.
sl@0: 
sl@0: <<fread>> also advances the file position indicator (if any) for
sl@0: <[fp]> by the number of @emph{characters} actually read.
sl@0: 
sl@0: RETURNS
sl@0: The result of <<fread>> is the number of elements it succeeded in
sl@0: reading.
sl@0: 
sl@0: PORTABILITY
sl@0: ANSI C requires <<fread>>.
sl@0: 
sl@0: Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
sl@0: <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
sl@0: */
sl@0: 
sl@0: #include <stdio.h>
sl@0: #include <string.h>
sl@0: #include "LOCAL.H"
sl@0: 
sl@0: /**
sl@0: Read block of data from a stream.
sl@0: Read count number of items each one with a size of size bytes from the stream
sl@0: and stores it in the specified buffer.
sl@0: Stream's postion indicator is increased by the number of bytes readed.
sl@0: Total amount of bytes read is (size x count).
sl@0: @return   The total number of items readed is returned.
sl@0: @param buf Pointer to the destination structure with a minimum size of (size*count) bytes. 
sl@0: @param size Size in bytes of each item to be read. 
sl@0: @param count Number of items, each one with a size of size bytes. 
sl@0: @param fp pointer to an open file.
sl@0: */
sl@0: EXPORT_C size_t
sl@0: fread (void *buf, size_t size, size_t count, FILE * fp)
sl@0: {
sl@0:   register size_t resid;
sl@0:   register char *p;
sl@0:   register int r;
sl@0:   size_t total;
sl@0: 
sl@0:   if ((resid = count * size) == 0)
sl@0:     return 0;
sl@0:   if (fp->_r < 0)
sl@0:     fp->_r = 0;
sl@0:   total = resid;
sl@0:   p = (char*)buf;
sl@0:   while ((int)resid > (r = fp->_r))
sl@0:     {
sl@0:       (void) memcpy ((void *) p, (void *) fp->_p, (size_t) r);
sl@0:       fp->_p += r;
sl@0:       /* fp->_r = 0 ... done in __srefill */
sl@0:       p += r;
sl@0:       resid -= r;
sl@0:       if (__srefill (fp))
sl@0: 	{
sl@0: 	  /* no more input: return partial result */
sl@0: 	  return (total - resid) / size;
sl@0: 	}
sl@0:     }
sl@0:   (void) memcpy ((void *) p, (void *) fp->_p, resid);
sl@0:   fp->_r -= resid;
sl@0:   fp->_p += resid;
sl@0:   return count;
sl@0: }