1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-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 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
22 * Routines to implement fast character input
37 * open stream <f> for fast character input
39 int fcfopen(register Sfio_t
* f
)
45 _Fcin
.fcbuff
= _Fcin
.fcptr
;
48 if(!(buff
=(char*)sfreserve(f
,SF_UNBOUND
,SF_LOCKR
)))
52 _Fcin
.fcptr
= _Fcin
.fcbuff
= &_Fcin
.fcchar
;
54 _Fcin
._fcfile
= (Sfio_t
*)0;
60 _Fcin
.fcoff
= sftell(f
);;
61 buff
= (char*)sfreserve(f
,SF_UNBOUND
,SF_LOCKR
);
62 _Fcin
.fclast
= (_Fcin
.fcptr
=_Fcin
.fcbuff
=(unsigned char*)buff
)+n
;
70 * With _Fcin.fcptr>_Fcin.fcbuff, the stream pointer is advanced and
71 * If _Fcin.fclast!=0, performs an sfreserve() for the next buffer.
72 * If a notify function has been set, it is called
73 * If last is non-zero, and the stream is a file, 0 is returned when
74 * the previous character is a 0 byte.
80 register unsigned char *last
=_Fcin
.fclast
, *ptr
=_Fcin
.fcptr
;
83 /* see whether pointer has passed null byte */
84 if(ptr
>_Fcin
.fcbuff
&& *--ptr
==0)
92 if( ptr
<last
&& ptr
>_Fcin
.fcbuff
&& *(ptr
-1)==0)
97 _Fcin
.fcptr
= ptr
= last
;
99 if((n
= ptr
-_Fcin
.fcbuff
) && _Fcin
.fcfun
)
100 (*_Fcin
.fcfun
)(f
,(const char*)_Fcin
.fcbuff
,n
,_Fcin
.context
);
101 sfread(f
, (char*)_Fcin
.fcbuff
, n
);
106 else if(fcfopen(f
) < 0)
108 return(*_Fcin
.fcptr
++);
112 * Synchronize and close the current stream
116 register unsigned char *ptr
;
119 if((ptr
=_Fcin
.fcptr
)>_Fcin
.fcbuff
&& *(ptr
-1)==0)
122 *_Fcin
.fclast
= _Fcin
.fcchar
;
129 * Set the notify function that is called for each fcfill()
131 void fcnotify(void (*fun
)(Sfio_t
*,const char*,int,void*),void* context
)
134 _Fcin
.context
= context
;
138 # define extern __EXPORT__
142 extern void fcsave(Fcin_t
*fp
)
148 extern void fcrestore(Fcin_t
*fp
)
155 unsigned char buff
[2*MB_LEN_MAX
];
159 int fcmbstate(const char *state
, int *s
, int *len
)
161 static struct Extra extra
;
162 register int i
, c
, n
;
165 if((c
= mbsize(extra
.next
)) < 0)
167 if((_Fcin
.fcleft
-= c
) <=0)
169 _Fcin
.fcptr
= (unsigned char*)fcfirst() - _Fcin
.fcleft
;
174 *s
= state
[*extra
.next
++];
179 c
= mbchar(extra
.next
);
184 switch(*len
= mbsize(_Fcin
.fcptr
))
187 if(_Fcin
._fcfile
&& (n
=(_Fcin
.fclast
-_Fcin
.fcptr
)) < MB_LEN_MAX
)
189 memcpy(extra
.buff
, _Fcin
.fcptr
, n
);
190 _Fcin
.fcptr
= _Fcin
.fclast
;
191 for(i
=n
; i
< MB_LEN_MAX
+n
; i
++)
193 if((extra
.buff
[i
] = fcgetc(c
))==0)
197 extra
.next
= extra
.buff
;
198 return(fcmbstate(state
,s
,len
));
204 *s
= state
[c
=fcget()];
207 c
= mbchar(_Fcin
.fcptr
);