1 /* $XConsortium: sffilbuf.c /main/3 1995/11/01 18:29:01 rswiston $ */
2 /***************************************************************
6 * THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
9 * Copyright (c) 1995 AT&T Corp. *
10 * All Rights Reserved *
12 * This software is licensed by AT&T Corp. *
13 * under the terms and conditions of the license in *
14 * http://www.research.att.com/orgs/ssr/book/reuse *
16 * This software was created by the *
17 * Software Engineering Research Department *
18 * AT&T Bell Laboratories *
20 * For further information contact *
21 * gsf@research.att.com *
23 ***************************************************************/
26 /* Fill the buffer of a stream with data.
27 ** If n < 0, sffilbuf() attempts to fill the buffer if it's empty.
28 ** If n == 0, if the buffer is not empty, just return the first byte;
29 ** otherwise fill the buffer and return the first byte.
30 ** If n > 0, even if the buffer is not empty, try a read to get as
31 ** close to n as possible. n is reset to -1 if stack pops.
33 ** Written by Kiem-Phong Vo (06/27/90)
37 _sffilbuf(reg Sfio_t* f, reg int n)
40 reg Sfio_t *f; /* fill the read buffer of this stream */
41 reg int n; /* see above */
44 reg int r, local, rcrv, rc;
48 /* any peek data must be preserved across stacked streams */
49 rcrv = f->mode&(SF_RC|SF_RV|SF_LOCK);
52 for(;; f->mode &= ~SF_LOCK)
54 if(SFMODE(f,local) != SF_READ && _sfmode(f,SF_READ,local) < 0)
58 /* current extent of available data */
59 if((r = f->endb-f->next) > 0)
60 { if(n <= 0 || (f->flags&SF_STRING))
63 /* shift left to make room for new data */
64 if(!(f->flags&SF_MMAP) && n > (f->size - (f->endb-f->data)) )
65 { memcpy((char*)f->data,(char*)f->next,r);
66 f->endb = (f->next = f->data)+r;
69 else if(!(f->flags&(SF_STRING|SF_MMAP)) )
70 f->next = f->endb = f->endr = f->data;
73 r = n > 0 ? n : f->size;
74 else if(!(f->flags&SF_STRING) )
75 { /* make sure we read no more than required */
76 r = f->size - (f->endb - f->data);
77 if(n > 0 && r > n && f->extent < 0 && (f->flags&SF_SHARE))
81 /* SFRD takes care of discipline read and stack popping */
84 if((r = SFRD(f,f->endb,r,f->disc)) >= 0)
85 { r = f->endb - f->next;
91 return (n == 0) ? (r > 0 ? (int)(*f->next++) : EOF) : r;