123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148openPrintfleterrors=failwith("Bi_stream: "^s)letinput_int64ic=matchSys.word_sizewith64->letn=ref0infori=1to8don:=(!nlsl8)lor(input_byteic);done;if!n<0thenerror"Corrupted stream: excessive chunk length";!n|32->fori=1to4doifinput_byteic<>0thenerror"Chunk length exceeds supported range on this platform"done;letn=ref0infori=1to4don:=(!nlsl8)lor(input_byteic);done;if!n<0thenerror"Chunk length exceeds supported range on this platform";!n|n->error(sprintf"unsupported word size (%i)"n)letoutput_int64ocn=matchSys.word_sizewith64->letn=refninfori=1to8dooutput_charoc(char_of_int(!nlsr56));n:=!nlsl8done|32->output_stringoc"\000\000\000\000";letn=refninfori=1to4dooutput_charoc(char_of_int(!nlsr24));n:=!nlsl8done|n->error(sprintf"unsupported word size (%i)"n)letrecread_chunkof_stringic=matchinput_charicwith'\001'->letlen=input_int64iciniflen>Sys.max_string_lengththenerror(sprintf"Corrupted stream: excessive chunk length (%i bytes)"len);lets=Bytes.createleninreally_inputics0len;Some(of_string(Bytes.to_strings))|'\000'->None|c->error(sprintf"Corrupted stream: %C"c)letflattenst=leta=ref[||]inletpos=ref0inletrecnexti=if!pos>=Array.length!athen(matchStream.peekstwithNone->None|Somea'->Stream.junkst;a:=a';pos:=0;nexti)else(letx=(!a).(!pos)inincrpos;Somex)inStream.fromnextletread_streamof_stringic=flatten(Stream.from(funi->read_chunkof_stringic))letrev_array_of_listl=matchlwith[]->[||]|x::tl->letr=reftlinletlen=List.lengthlinleta=Array.makelenxinfori=len-2downto0domatch!rwithhd::tl->a.(i)<-hd;r:=tl;|[]->assertfalsedone;aletwrite_stream?(chunk_len=1024)to_stringocst=letn=ref0inletacc=ref[]inletflush_chunk()=leta=rev_array_of_list!accinacc:=[];n:=0;lets=to_stringainoutput_charoc'\001';output_int64oc(String.lengths);output_stringocsinStream.iter(funx->incrn;acc:=x::!acc;if!n>=chunk_lenthenflush_chunk())st;if!n>0thenflush_chunk();output_charoc'\000'lettestl=List.iter(funx->assert(x>=0&&x<=9))l;letto_stringa=String.concat""(List.mapstring_of_int(Array.to_lista))inletof_strings=Array.init(String.lengths)(funi->int_of_string(String.make1s.[i]))inletst=Stream.of_listlinletoc=open_out"test-stream.dat"inwrite_stream~chunk_len:2to_stringocst;close_outoc;letic=open_in"test-stream.dat"inletst'=read_streamof_stringicinletl'=ref[]inStream.iter(funi->l':=i::!l')st';close_inic;l=List.rev!l'