3
/* Read n bytes from a stream into a buffer
5
** Written by Kiem-Phong Vo.
9
ssize_t sfread(reg Sfio_t* f, Void_t* buf, reg size_t n)
11
ssize_t sfread(f,buf,n)
12
reg Sfio_t* f; /* read from this stream. */
13
Void_t* buf; /* buffer to read into */
14
reg size_t n; /* number of bytes to be read. */
19
reg int local, justseek;
21
SFMTXSTART(f, (ssize_t)(-1));
24
justseek = f->bits&SF_JUSTSEEK; f->bits &= ~SF_JUSTSEEK;
27
SFMTXRETURN(f, (ssize_t)(-1) );
29
/* release peek lock */
31
{ if(!(f->mode&SF_READ) )
32
SFMTXRETURN(f, (ssize_t)(-1));
35
{ if(((uchar*)buf + f->val) != f->next &&
36
(!f->rsrv || f->rsrv->data != (uchar*)buf) )
37
SFMTXRETURN(f, (ssize_t)(-1));
42
{ if((uchar*)buf != f->next)
43
SFMTXRETURN(f, (ssize_t)(-1));
46
{ /* actually read the data now */
49
n = (r = read(f->file,f->data,n)) < 0 ? 0 : r;
59
s = begs = (uchar*)buf;
60
for(;; f->mode &= ~SF_LOCK)
61
{ /* check stream mode */
62
if(SFMODE(f,local) != SF_READ && _sfmode(f,SF_READ,local) < 0)
63
{ n = s > begs ? s-begs : (size_t)(-1);
64
SFMTXRETURN(f, (ssize_t)n);
69
if((r = f->endb - f->next) > 0) /* has buffered data */
73
memcpy(s, f->next, r);
79
if(n <= 0) /* all done */
82
if(!(f->flags&SF_STRING) && !(f->bits&SF_MMAP) )
83
{ f->next = f->endb = f->data;
85
/* exact IO is desirable for these cases */
87
((f->flags&SF_SHARE) && f->extent < 0) )
89
else if(justseek && n <= f->iosz && f->iosz <= f->size)
90
r = f->iosz; /* limit buffering */
91
else r = f->size; /* full buffering */
93
/* if read almost full size, then just do it direct */
94
if(r > (ssize_t)n && (r - r/8) <= (ssize_t)n)
97
/* read directly to user's buffer */
98
if(r == (ssize_t)n && (r = SFRD(f,s,r,f->disc)) >= 0)
101
if(r == 0 || n == 0) /* eof or eob */
109
f->bits |= SF_JUSTSEEK;
110
if(SFFILBUF(f,-1) <= 0)