123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246moduleShared=structtypet={buf:Bytes.t;mutablepos:int;pos_end:int;}letof_bytesbuf={buf;pos=0;pos_end=Bytes.lengthbuf}letof_bytes_subbuf~pos~pos_end={buf;pos;pos_end}letremainingb=b.pos_end-b.posexternalbswap_16:int->int="%bswap16"externalbswap_32:int32->int32="%bswap_int32"externalbswap_64:int64->int64="%bswap_int64"endmoduleWrite=structincludeSharedletrecwrite_fullyfdbufpospos_end=ifpos=pos_endthen()elseletwritten=Unix.writefdbufpos(pos_end-pos)inwrite_fullyfdbuf(pos+written)pos_endletwrite_fdfdb=write_fullyfdb.buf0b.posletput_raw_8biv=Bytes.unsafe_setbi(Char.unsafe_chrv)externalput_raw_16:Bytes.t->int->int->unit="%caml_bytes_set16u"externalput_raw_32:Bytes.t->int->int32->unit="%caml_bytes_set32u"externalput_raw_64:Bytes.t->int->int64->unit="%caml_bytes_set64u"exceptionOverflowofintlet[@inlinenever]overflowb=Overflowb.poslet[@inlinealways]put_8bv=letpos=b.posinletpos'=b.pos+1inifpos'>b.pos_endthenraise(overflowb)else(put_raw_8b.bufposv;b.pos<-pos')let[@inlinealways]put_16bv=letpos=b.posinletpos'=b.pos+2inifpos'>b.pos_endthenraise(overflowb)else(put_raw_16b.bufpos(ifSys.big_endianthenbswap_16velsev);b.pos<-pos')let[@inlinealways]put_32bv=letpos=b.posinletpos'=b.pos+4inifpos'>b.pos_endthenraise(overflowb)else(put_raw_32b.bufpos(ifSys.big_endianthenbswap_32velsev);b.pos<-pos')let[@inlinealways]put_64bv=letpos=b.posinletpos'=b.pos+8inifpos'>b.pos_endthenraise(overflowb)else(put_raw_64b.bufpos(ifSys.big_endianthenbswap_64velsev);b.pos<-pos')let[@inlinealways]put_floatbf=put_64b(Int64.bits_of_floatf)letput_stringbs=letslen=matchString.index_opts'\000'with|Somei->i|None->String.lengthsinifb.pos+slen+1>b.pos_endthenraise(overflowb);Bytes.blit_strings0b.bufb.posslen;Bytes.unsafe_setb.buf(b.pos+slen)'\000';b.pos<-b.pos+slen+1let[@inlinenever]put_vint_bigbv=ifv=vland0xffffthen(put_8b253;put_16bv)elseifv=vland0xffffffffthen(put_8b254;put_32b(Int32.of_intv))else(put_8b255;put_64b(Int64.of_intv))let[@inlinealways]put_vintbv=if0<=v&&v<=252thenput_8bvelseput_vint_bigbvtypeposition_8=inttypeposition_16=inttypeposition_32=inttypeposition_64=inttypeposition_float=intlet[@inlinealways]skip_8b=letpos=b.posinletpos'=b.pos+1inifpos'>b.pos_endthenraise(overflowb);b.pos<-pos';poslet[@inlinealways]skip_16b=letpos=b.posinletpos'=b.pos+2inifpos'>b.pos_endthenraise(overflowb);b.pos<-pos';poslet[@inlinealways]skip_32b=letpos=b.posinletpos'=b.pos+4inifpos'>b.pos_endthenraise(overflowb);b.pos<-pos';poslet[@inlinealways]skip_64b=letpos=b.posinletpos'=b.pos+8inifpos'>b.pos_endthenraise(overflowb);b.pos<-pos';posletskip_float=skip_64letupdate_8bposv=assert(pos+1<=b.pos_end);put_raw_8b.bufposvletupdate_16bposv=assert(pos+2<=b.pos_end);put_raw_16b.bufposvletupdate_32bposv=assert(pos+4<=b.pos_end);put_raw_32b.bufposvletupdate_64bposv=assert(pos+8<=b.pos_end);put_raw_64b.bufposvletupdate_floatbposf=update_64bpos(Int64.bits_of_floatf)endmoduleRead=structincludeSharedletrecread_intofdbufoff=ifoff=Bytes.lengthbufthen{buf;pos=0;pos_end=off}elsebeginassert(0<=off&&off<=Bytes.lengthbuf);letn=Unix.readfdbufoff(Bytes.lengthbuf-off)inifn=0then(* EOF *){buf;pos=0;pos_end=off}else(* Short read *)read_intofdbuf(off+n)endletread_fdfdbuf=read_intofdbuf0letrefill_fdfdb=letlen=remainingbinBytes.blitb.bufb.posb.buf0len;read_intofdb.buflenletsplitblen=letlen=min(remainingb)lenin{bwithpos_end=b.pos+len},{bwithpos=b.pos+len}letempty={buf=Bytes.make0'?';pos=0;pos_end=0}externalget_raw_16:Bytes.t->int->int="%caml_bytes_get16u"externalget_raw_32:Bytes.t->int->int32="%caml_bytes_get32u"externalget_raw_64:Bytes.t->int->int64="%caml_bytes_get64u"exceptionUnderflowofintlet[@inlinenever]underflowb=Underflowb.poslet[@inlinealways]get_8b=letpos=b.posinletpos'=b.pos+1inifpos'>b.pos_endthenraise(underflowb);b.pos<-pos';Char.code(Bytes.unsafe_getb.bufpos)let[@inlinealways]get_16b=letpos=b.posinletpos'=b.pos+2inifpos'>b.pos_endthenraise(underflowb);b.pos<-pos';ifSys.big_endianthenbswap_16(get_raw_16b.bufpos)elseget_raw_16b.bufposlet[@inlinealways]get_32b=letpos=b.posinletpos'=b.pos+4inifpos'>b.pos_endthenraise(underflowb);b.pos<-pos';ifSys.big_endianthenbswap_32(get_raw_32b.bufpos)elseget_raw_32b.bufposlet[@inlinealways]get_64b=letpos=b.posinletpos'=b.pos+8inifpos'>b.pos_endthenraise(underflowb);b.pos<-pos';ifSys.big_endianthenbswap_64(get_raw_64b.bufpos)elseget_raw_64b.bufposlet[@inlinealways]get_floatb=Int64.float_of_bits(get_64b)letget_stringb=letstart=b.posinwhileget_8b<>0do()done;letlen=b.pos-1-startinBytes.sub_stringb.bufstartlenlet[@inlinenever]get_vint_bigbc=matchcwith|253->get_16b|254->Int32.to_int(get_32b)|255->Int64.to_int(get_64b)|_->assertfalselet[@inlinealways]get_vintb=matchget_8bwith|cwhenc<253->c|c->get_vint_bigbcendlet()=Printexc.register_printer(function|Write.Overflown->Some("Buffer overflow at position "^string_of_intn)|Read.Underflown->Some("Buffer underflow at position "^string_of_intn)|_->None)