1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* Fill the buffer of a stream with data.
25 ** If n < 0, sffilbuf() attempts to fill the buffer if it's empty.
26 ** If n == 0, if the buffer is not empty, just return the first byte;
27 ** otherwise fill the buffer and return the first byte.
28 ** If n > 0, even if the buffer is not empty, try a read to get as
29 ** close to n as possible. n is reset to -1 if stack pops.
31 ** Written by Kiem-Phong Vo
35 int _sffilbuf(Sfio_t
* f
, reg
int n
)
38 Sfio_t
* f
; /* fill the read buffer of this stream */
39 reg
int n
; /* see above */
43 reg
int first
, local
, rcrv
, rc
, justseek
;
50 /* any peek data must be preserved across stacked streams */
51 rcrv
= f
->mode
&(SF_RC
|SF_RV
|SF_LOCK
);
54 justseek
= f
->bits
&SF_JUSTSEEK
; f
->bits
&= ~SF_JUSTSEEK
;
56 for(first
= 1;; first
= 0, (f
->mode
&= ~SF_LOCK
) )
58 if(SFMODE(f
,local
) != SF_READ
&& _sfmode(f
,SF_READ
,local
) < 0)
62 /* current extent of available data */
63 if((r
= f
->endb
-f
->next
) > 0)
64 { /* on first iteration, n is amount beyond current buffer;
65 afterward, n is the exact amount requested */
66 if((first
&& n
<= 0) || (!first
&& n
<= r
) ||
70 /* try shifting left to make room for new data */
71 if(!(f
->bits
&SF_MMAP
) && f
->next
> f
->data
&&
72 n
> (f
->size
- (f
->endb
-f
->data
)) )
75 /* try to maintain block alignment */
76 if(f
->blksz
> 0 && (f
->here
%f
->blksz
) == 0 )
77 { s
= ((r
+ f
->blksz
-1)/f
->blksz
)*f
->blksz
;
82 memcpy(f
->data
, f
->endb
-s
, s
);
83 f
->next
= f
->data
+ (s
-r
);
84 f
->endb
= f
->data
+ s
;
87 else if(!(f
->flags
&SF_STRING
) && !(f
->bits
&SF_MMAP
) )
88 f
->next
= f
->endb
= f
->endr
= f
->data
;
91 r
= n
> 0 ? n
: f
->size
;
92 else if(!(f
->flags
&SF_STRING
) )
93 { r
= f
->size
- (f
->endb
- f
->data
); /* available buffer */
95 { if(r
> n
&& f
->extent
< 0 && (f
->flags
&SF_SHARE
) )
96 r
= n
; /* read only as much as requested */
97 else if(justseek
&& n
<= f
->iosz
&& f
->iosz
<= f
->size
)
98 r
= f
->iosz
; /* limit buffer filling */
102 /* SFRD takes care of discipline read and stack popping */
105 if((r
= SFRD(f
,f
->endb
,r
,f
->disc
)) >= 0)
106 { r
= f
->endb
- f
->next
;
113 rcrv
= (n
== 0) ? (r
> 0 ? (int)(*f
->next
++) : EOF
) : (int)r
;