Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file stream.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236(**************************************************************************)(* *)(* OCaml *)(* *)(* Daniel de Rauglaudre, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1997 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)type'at='acelloptionand'acell={mutablecount:int;mutabledata:'adata}and'adata=Sempty|Sconsof'a*'adata|Sappof'adata*'adata|Slazyof'adataLazy.t|Sgenof'agen|Sbuffio:buffio->chardataand'agen={mutablecurr:'aoptionoption;func:int->'aoption}andbuffio={ic:in_channel;buff:bytes;mutablelen:int;mutableind:int}exceptionFailureexceptionErrorofstringletcount=function|None->0|Some{count}->countletdata=function|None->Sempty|Some{data}->dataletfill_buffb=b.len<-inputb.icb.buff0(Bytes.lengthb.buff);b.ind<-0letrecget_data:typev.int->vdata->vdata=funcountd->matchdwith(* Returns either Sempty or Scons(a, _) even when d is a generator
or a buffer. In those cases, the item a is seen as extracted from
the generator/buffer.
The count parameter is used for calling `Sgen-functions'. *)Sempty|Scons(_,_)->d|Sapp(d1,d2)->beginmatchget_datacountd1withScons(a,d11)->Scons(a,Sapp(d11,d2))|Sempty->get_datacountd2|_->assertfalseend|Sgen{curr=SomeNone}->Sempty|Sgen({curr=Some(Somea)}asg)->g.curr<-None;Scons(a,d)|Sgeng->beginmatchg.funccountwithNone->g.curr<-Some(None);Sempty|Somea->Scons(a,d)(* Warning: anyone using g thinks that an item has been read *)end|Sbuffiob->ifb.ind>=b.lenthenfill_buffb;ifb.len==0thenSemptyelseletr=Bytes.unsafe_getb.buffb.indin(* Warning: anyone using g thinks that an item has been read *)b.ind<-succb.ind;Scons(r,d)|Slazyf->get_datacount(Lazy.forcef)letrecpeek_data:typev.vcell->voption=funs->(* consult the first item of s *)matchs.datawithSempty->None|Scons(a,_)->Somea|Sapp(_,_)->beginmatchget_datas.counts.datawithScons(a,_)asd->s.data<-d;Somea|Sempty->None|_->assertfalseend|Slazyf->s.data<-(Lazy.forcef);peek_datas|Sgen{curr=Somea}->a|Sgeng->letx=g.funcs.counting.curr<-Somex;x|Sbuffiob->ifb.ind>=b.lenthenfill_buffb;ifb.len==0thenbegins.data<-Sempty;NoneendelseSome(Bytes.unsafe_getb.buffb.ind)letpeek=function|None->None|Somes->peek_datasletrecjunk_data:typev.vcell->unit=funs->matchs.datawithScons(_,d)->s.count<-(succs.count);s.data<-d|Sgen({curr=Some_}asg)->s.count<-(succs.count);g.curr<-None|Sbuffiob->ifb.ind>=b.lenthenfill_buffb;ifb.len==0thens.data<-Semptyelse(s.count<-(succs.count);b.ind<-succb.ind)|_->matchpeek_dataswithNone->()|Some_->junk_datasletjunk=function|None->()|Somedata->junk_datadataletrecnget_datans=ifn<=0then[],s.data,0elsematchpeek_dataswithSomea->junk_datas;let(al,d,k)=nget_data(predn)sina::al,Scons(a,d),succk|None->[],s.data,0letnpeek_datans=let(al,d,len)=nget_datansins.count<-(s.count-len);s.data<-d;alletnpeekn=function|None->[]|Somed->npeek_datandletnexts=matchpeekswithSomea->junks;a|None->raiseFailureletemptys=matchpeekswithSome_->raiseFailure|None->()letiterfstrm=letrecdo_rec()=matchpeekstrmwithSomea->junkstrm;ignore(fa);do_rec()|None->()indo_rec()(* Stream building functions *)letfromf=Some{count=0;data=Sgen{curr=None;func=f}}letof_listl=Some{count=0;data=List.fold_right(funxl->Scons(x,l))lSempty}letof_strings=letcount=ref0infrom(fun_->(* We cannot use the index passed by the [from] function directly
because it returns the current stream count, with absolutely no
guarantee that it will start from 0. For example, in the case
of [Stream.icons 'c' (Stream.from_string "ab")], the first
access to the string will be made with count [1] already.
*)letc=!countinifc<String.lengthsthen(incrcount;Somes.[c])elseNone)letof_bytess=letcount=ref0infrom(fun_->letc=!countinifc<Bytes.lengthsthen(incrcount;Some(Bytes.getsc))elseNone)letof_channelic=Some{count=0;data=Sbuffio{ic=ic;buff=Bytes.create4096;len=0;ind=0}}(* Stream expressions builders *)letiappis=Some{count=0;data=Sapp(datai,datas)}leticonsis=Some{count=0;data=Scons(i,datas)}letisingi=Some{count=0;data=Scons(i,Sempty)}letlappfs=Some{count=0;data=Slazy(lazy(Sapp(data(f()),datas)))}letlconsfs=Some{count=0;data=Slazy(lazy(Scons(f(),datas)))}letlsingf=Some{count=0;data=Slazy(lazy(Scons(f(),Sempty)))}letsempty=Noneletslazyf=Some{count=0;data=Slazy(lazy(data(f())))}(* For debugging use *)letrecdump:typev.(v->unit)->vt->unit=funfs->print_string"{count = ";print_int(counts);print_string"; data = ";dump_dataf(datas);print_string"}";print_newline()anddump_data:typev.(v->unit)->vdata->unit=funf->functionSempty->print_string"Sempty"|Scons(a,d)->print_string"Scons (";fa;print_string", ";dump_datafd;print_string")"|Sapp(d1,d2)->print_string"Sapp (";dump_datafd1;print_string", ";dump_datafd2;print_string")"|Slazy_->print_string"Slazy"|Sgen_->print_string"Sgen"|Sbuffio_->print_string"Sbuffio"