12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249open!Core_kernelopen!Iobuf_intfmoduletypeAccessors_common=Accessors_commonmoduletypeAccessors_read=Accessors_readmoduletypeAccessors_write=Accessors_writemoduletypeConsuming_blit=Consuming_blittypenonrec('src,'dst)consuming_blito=('src,'dst)consuming_blitoletarch_sixtyfour=Sys.word_size=64moduleT=struct(* WHEN YOU CHANGE THIS, CHANGE iobuf_fields IN iobuf.h AS WELL!!! *)typet={mutablebuf:(Bigstring.t[@sexp.opaque](* The data in [buf] is at indices [lo], [lo+1], ... [hi-1]. *));mutablelo_min:int;mutablelo:int;mutablehi:int;mutablehi_max:int}[@@derivingfields,sexp_of]endopenTtypet_repr=T.ttype(-'read_write,+'seek)t=T.t[@@derivingsexp_of]type(_,_)t_with_shallow_sexp=T.t[@@derivingsexp_of]typeseek=Iobuf_intf.seek[@@derivingsexp_of]typeno_seek=Iobuf_intf.no_seek[@@derivingsexp_of]moduletypeBound=Iobuf_intf.Boundwithtype('d,'w)iobuf:=('d,'w)tletread_onlyt=tletno_seekt=tletfailtmessageasexp_of_a=(* Immediately convert the iobuf to sexp. Otherwise, the iobuf could be modified before
conversion and printing. Since we plan to use iobufs for pooled network buffers in
practice, this could be very confusing when debugging production systems. *)Error.raise(Error.createmessage(a,[%sexp_of:(_,_)t]t)(Tuple.T2.sexp_of_tsexp_of_aident));;moduleLo_bound=structletstaletiobuf=failiobuf"Iobuf.Lo_bound.restore got stale snapshot"t[%sexp_of:int];;typet=int[@@derivingcompare,sexp_of](* lo *)letwindowt=t.loletrestoretiobuf=ift<iobuf.lo_min||t>iobuf.hithenstaletiobuf;iobuf.lo<-t;;letlimitt=t.lo_minendmoduleHi_bound=structletstaletiobuf=failiobuf"Iobuf.Hi_bound.restore got stale snapshot"t[%sexp_of:int];;typet=int[@@derivingcompare,sexp_of](* hi *)letwindowt=t.hiletrestoretiobuf=ift>iobuf.hi_max||t<iobuf.lothenstaletiobuf;iobuf.hi<-t;;letlimitt=t.hi_maxendletlengtht=t.hi-t.loletlength_lot=t.lo-t.lo_minletlength_hit=t.hi_max-t.hiletis_emptyt=lengtht=0letrewindt=t.lo<-t.lo_minletresett=t.lo<-t.lo_min;t.hi<-t.hi_max;;letflip_lot=t.hi<-t.lo;t.lo<-t.lo_min;;letbounded_flip_lo_staletlo_min=failt"Iobuf.bounded_flip_lo got stale snapshot"lo_min[%sexp_of:Lo_bound.t];;letbounded_flip_lotlo_min=iflo_min<t.lo_min||lo_min>t.lothenbounded_flip_lo_staletlo_minelse(t.hi<-t.lo;t.lo<-lo_min);;letflip_hit=t.lo<-t.hi;t.hi<-t.hi_max;;letbounded_flip_hi_stalethi_max=failt"Iobuf.bounded_flip_hi got stale snapshot"hi_max[%sexp_of:Hi_bound.t];;letbounded_flip_hithi_max=ifhi_max>t.hi_max||hi_max<t.hithenbounded_flip_hi_stalethi_maxelse(t.lo<-t.hi;t.hi<-hi_max);;letcapacityt=t.hi_max-t.lo_minletinvariant__t=tryFields.Direct.itert~buf:(fun___->())~lo_min:(fun__lo_min->assert(lo_min>=0);assert(lo_min=t.hi_max-capacityt))~hi_max:(fun__hi_max->assert(hi_max>=t.lo);assert(hi_max=t.lo_min+capacityt))~lo:(fun__lo->assert(lo>=t.lo_min);assert(lo<=t.hi))~hi:(fun__hi->assert(hi>=t.lo);assert(hi<=t.hi_max))with|e->failt"Iobuf.invariant failed"e[%sexp_of:exn];;(* We want [check_range] inlined, so we don't want a string constant in there. *)letbad_range~pos~lent=failt"Iobuf got invalid range"(`pospos,`lenlen)[%sexp_of:[`posofint]*[`lenofint]][@@cold];;letcheck_ranget~pos~len=ifpos<0||len<0||len>lengtht-posthenbad_range~pos~lent[@@inlinealways];;letof_bigstring?pos?lenbuf=letstr_len=Bigstring.lengthbufinletpos=matchposwith|None->0|Somepos->ifpos<0||pos>str_lenthenraise_s[%sexp"Iobuf.of_bigstring got invalid pos",(pos:int),~~(str_len:int)];posinletlen=matchlenwith|None->str_len-pos|Somelen->letmax_len=str_len-posiniflen<0||len>max_lenthenraise_s[%sexp"Iobuf.of_bigstring got invalid pos",(len:int),~~(max_len:int)];leninletlo=posinlethi=pos+lenin{buf;lo_min=lo;lo;hi;hi_max=hi};;letsub_shared?(pos=0)?lent=letlen=matchlenwith|None->lengtht-pos|Somelen->lenincheck_ranget~pos~len;letlo=t.lo+posinlethi=lo+lenin{buf=t.buf;lo_min=lo;lo;hi;hi_max=hi};;letcopyt=of_bigstring(Bigstring.subt.buf~pos:t.lo~len:(lengtht))letclone{buf;lo_min;lo;hi;hi_max}={buf=Bigstring.copybuf;lo_min;lo;hi;hi_max};;letset_bounds_and_buffer_sub~pos~len~src~dst=check_rangesrc~pos~len;letlo=src.lo+posinlethi=lo+lenindst.lo_min<-lo;dst.lo<-lo;dst.hi<-hi;dst.hi_max<-hi;ifnot(phys_equaldst.bufsrc.buf)thendst.buf<-src.buf;;letset_bounds_and_buffer~src~dst=dst.lo_min<-src.lo_min;dst.lo<-src.lo;dst.hi<-src.hi;dst.hi_max<-src.hi_max;ifnot(phys_equaldst.bufsrc.buf)thendst.buf<-src.buf;;letnarrow_lot=t.lo_min<-t.loletnarrow_hit=t.hi_max<-t.hiletnarrowt=narrow_lot;narrow_hit;;letunsafe_resizet~len=t.hi<-t.lo+lenletresizet~len=iflen<0thenbad_ranget~len~pos:0;lethi=t.lo+leninifhi>t.hi_maxthenbad_ranget~len~pos:0;t.hi<-hi[@@inlinealways];;letprotect_window_and_boundst~f=letlo=t.loinlethi=t.hiinletlo_min=t.lo_mininlethi_max=t.hi_maxinletbuf=t.bufin(* also mutable *)tryt.lo_min<-lo;t.hi_max<-hi;letresult=ftint.lo<-lo;t.hi<-hi;t.lo_min<-lo_min;t.hi_max<-hi_max;t.buf<-buf;resultwith|exn->t.lo<-lo;t.hi<-hi;t.lo_min<-lo_min;t.hi_max<-hi_max;t.buf<-buf;raiseexn;;letprotect_window_and_bounds_1tx~f=letlo=t.loinlethi=t.hiinletlo_min=t.lo_mininlethi_max=t.hi_maxinletbuf=t.bufin(* also mutable *)tryt.lo_min<-lo;t.hi_max<-hi;letresult=ftxint.lo<-lo;t.hi<-hi;t.lo_min<-lo_min;t.hi_max<-hi_max;t.buf<-buf;resultwith|exn->t.lo<-lo;t.hi<-hi;t.lo_min<-lo_min;t.hi_max<-hi_max;t.buf<-buf;raiseexn;;letcreate~len=iflen<0thenraise_s[%sexp"Iobuf.create got negative len",(len:int)];of_bigstring(Bigstring.createlen);;letof_strings=of_bigstring(Bigstring.of_strings)letof_bytess=of_bigstring(Bigstring.of_bytess)letto_stringlike~(convert:?pos:int->?len:int->Bigstring.t->'a)=stage(fun?lent->(letlen=matchlenwith|Somelen->check_ranget~pos:0~len;len|None->lengthtinconvertt.buf~pos:t.lo~len:'a));;letto_string=to_stringlike~convert:Bigstring.to_string|>unstageletto_bytes=to_stringlike~convert:Bigstring.to_bytes|>unstage(* We used to do it like {v
let unsafe_with_range t ~pos f =
f t.buf ~pos:(t.lo + pos);
;;
let with_range t ~pos ~len f =
check_range t ~pos ~len;
unsafe_with_range t ~pos f;
;;
let inc_lo t amount = t.lo <- t.lo + amount
(** [unsafe_with_advance] and [unsafe_with_range] forego range checks for code that does
macro range checks, like we want to do in [Parachute_fix.Std.Protocol].
Esp. [Consume.Unsafe.int32_le] for unrolled character scanning. *)
let unsafe_with_advance t ~len f =
let result = unsafe_with_range t ~pos:0 f in
inc_lo t len;
result;
;;
let with_advance t ~len f =
check_range t ~pos:0 ~len;
unsafe_with_advance t ~len f;
;;
(* pulled out and type-constrained for inlining *)
let ignore_range (_ : Bigstring.t) ~pos:(_ : int) = ()
let advance t len = with_advance t ~len ignore_range
v} but higher order functions don't get inlined, even in simple uses like advance.
Therefor, we stick to first order. *)let[@inlinealways]unsafe_buf_post~pos=t.lo+posletbuf_pos_exnt~pos~len=check_ranget~pos~len;unsafe_buf_post~pos;;letunsafe_advancetn=t.lo<-t.lo+nletadvancetlen=check_ranget~len~pos:0;unsafe_advancetlen[@@inlinealways];;externalbigstring_unsafe_get:Bigstring.t->pos:int->char="%caml_ba_unsafe_ref_1"externalbigstring_unsafe_set:Bigstring.t->pos:int->char->unit="%caml_ba_unsafe_set_1"(* Note that we can get [buf.{pos}] inlined by ensuring that it's monomorphically typed,
but we can't always get the containing function inlined. *)(* Similarly, we need the following intermediate functions for the primitives to be
inlined into. (Not intuitive, but apparently necessary.) *)letbigstring_unsafe_getb~pos=bigstring_unsafe_getb~posletbigstring_unsafe_setb~posc=bigstring_unsafe_setb~poscmoduleChar_elt=structincludeCharletof_bool=function|true->'0'|false->'1';;endmoduleT_src=structtypet=T.t[@@derivingsexp_of]letcreate=createletlength=lengthlet[@inline]gettpos=bigstring_unsafe_gett.buf~pos:(buf_pos_exnt~len:1~pos)let[@inline]settposc=bigstring_unsafe_sett.buf~pos:(buf_pos_exnt~len:1~pos)c;;endmoduleBytes_dst=structincludeBytesletunsafe_blit~src~src_pos~dst~dst_pos~len=Bigstring.To_bytes.unsafe_blit~src:src.buf~src_pos:(unsafe_buf_possrc~pos:src_pos)~dst~dst_pos~len;;letcreate~len=createlenendmoduleString_dst=structletsubsrc~pos~len=Bigstring.To_string.subsrc.buf~pos:(buf_pos_exnsrc~pos~len)~len;;letsubo?(pos=0)?lensrc=letlen=matchlenwith|None->lengthsrc-pos|Somelen->leninBigstring.To_string.subosrc.buf~pos:(buf_pos_exnsrc~pos~len)~len;;endmoduleBigstring_dst=structincludeBigstringletunsafe_blit~src~src_pos~dst~dst_pos~len=Bigstring.unsafe_blit~src:src.buf~src_pos:(unsafe_buf_possrc~pos:src_pos)~dst~dst_pos~len;;letcreate~len=createlenendletcompactt=letlen=t.hi-t.loinBigstring.blit~src:t.buf~src_pos:t.lo~len~dst:t.buf~dst_pos:t.lo_min;t.lo<-t.lo_min+len;t.hi<-t.hi_max;;letbounded_compact_staletlo_minhi_max=failt"Iobuf.bounded_compact got stale snapshot"(lo_min,hi_max)[%sexp_of:Lo_bound.t*Hi_bound.t];;letbounded_compacttlo_minhi_max=letlen=t.hi-t.loinifhi_max>t.hi_max||hi_max<lo_min+len||lo_min<t.lo_minthenbounded_compact_staletlo_minhi_maxelse(Bigstring.blit~src:t.buf~src_pos:t.lo~len~dst:t.buf~dst_pos:lo_min;t.lo<-lo_min+len;t.hi<-hi_max);;letread_bin_protreadert~pos=letbuf_pos=unsafe_buf_post~posinletpos_ref=refbuf_posinleta=reader.Bin_prot.Type_class.readt.buf~pos_refinletlen=!pos_ref-buf_posincheck_ranget~pos~len;a,len;;moduleConsume=structtypesrc=(read,seek)tmoduleTo(Dst:sigtypet[@@derivingsexp_of]valcreate:len:int->tvallength:t->intvalget:t->int->charvalset:t->int->char->unitvalunsafe_blit:(T.t,t)Blit.blitend)=structincludeBase_for_tests.Test_blit.Make_distinct_and_test(Char_elt)(T_src)(Dst)letblit~src~dst~dst_pos~len=blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclen;;letblito~src?(src_len=lengthsrc)~dst?dst_pos()=blito~src~src_pos:0~src_len~dst?dst_pos();unsafe_advancesrcsrc_len;;letunsafe_blit~src~dst~dst_pos~len=unsafe_blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclen;;letsubsrc~len=letdst=subsrc~pos:0~leninunsafe_advancesrclen;dst;;letsubo?lensrc=letlen=matchlenwith|None->lengthsrc|Somelen->leninletdst=subo~pos:0~lensrcinunsafe_advancesrclen;dst;;endmoduleTo_bytes=To(Bytes_dst)moduleTo_bigstring=To(Bigstring_dst)moduleTo_string=structletsubsrc~len=letdst=String_dst.subsrc~len~pos:0inunsafe_advancesrclen;dst;;letsubo?lensrc=letlen=matchlenwith|None->lengthsrc|Somelen->leninletdst=String_dst.subo~pos:0~lensrcinunsafe_advancesrclen;dst;;endtypenonrec('a,'d,'w)t=('d,seek)t->'aconstraint'd=[>read]letuadvtnx=unsafe_advancetn;x[@@inlinealways];;letpostlen=buf_pos_exnt~pos:0~lenlettail_padded_fixed_string~padding~lent=uadvtlen(Bigstring.get_tail_padded_fixed_stringt.buf~pos:(postlen)~padding~len());;lethead_padded_fixed_string~padding~lent=uadvtlen(Bigstring.get_head_padded_fixed_stringt.buf~pos:(postlen)~padding~len());;letbytes~str_pos~lent=letdst=Bytes.create(len+str_pos)inTo_bytes.blit~src:t~dst~len~dst_pos:str_pos;dst;;letstring~str_pos~lent=Bytes.unsafe_to_string~no_mutation_while_string_reachable:(bytes~str_pos~lent);;letbigstring~str_pos~lent=letdst=Bigstring.create(len+str_pos)inTo_bigstring.blit~src:t~dst~len~dst_pos:str_pos;dst;;letbyteso?(str_pos=0)?lent=bytest~str_pos~len:(matchlenwith|None->lengtht|Somelen->len);;letstringo?(str_pos=0)?lent=stringt~str_pos~len:(matchlenwith|None->lengtht|Somelen->len);;letbigstringo?(str_pos=0)?lent=bigstringt~str_pos~len:(matchlenwith|None->lengtht|Somelen->len);;letbin_protreadert=leta,len=read_bin_protreadert~pos:0inuadvtlena;;openBigstringletlen=1let[@inlinealways]chart=uadvtlen(bigstring_unsafe_gett.buf~pos:(postlen))let[@inlinealways]uint8t=uadvtlen(unsafe_get_uint8t.buf~pos:(postlen))let[@inlinealways]int8t=uadvtlen(unsafe_get_int8t.buf~pos:(postlen))letlen=2let[@inlinealways]int16_bet=uadvtlen(unsafe_get_int16_bet.buf~pos:(postlen));;let[@inlinealways]int16_let=uadvtlen(unsafe_get_int16_let.buf~pos:(postlen));;let[@inlinealways]uint16_bet=uadvtlen(unsafe_get_uint16_bet.buf~pos:(postlen));;let[@inlinealways]uint16_let=uadvtlen(unsafe_get_uint16_let.buf~pos:(postlen));;letlen=4let[@inlinealways]int32_bet=uadvtlen(unsafe_get_int32_bet.buf~pos:(postlen));;let[@inlinealways]int32_let=uadvtlen(unsafe_get_int32_let.buf~pos:(postlen));;let[@inlinealways]uint32_bet=uadvtlen(unsafe_get_uint32_bet.buf~pos:(postlen));;let[@inlinealways]uint32_let=uadvtlen(unsafe_get_uint32_let.buf~pos:(postlen));;letlen=8let[@inlinealways]int64_be_exnt=uadvtlen(unsafe_get_int64_be_exnt.buf~pos:(postlen));;let[@inlinealways]int64_le_exnt=uadvtlen(unsafe_get_int64_le_exnt.buf~pos:(postlen));;let[@inlinealways]uint64_be_exnt=uadvtlen(unsafe_get_uint64_be_exnt.buf~pos:(postlen));;let[@inlinealways]uint64_le_exnt=uadvtlen(unsafe_get_uint64_le_exnt.buf~pos:(postlen));;let[@inlinealways]int64_t_bet=uadvtlen(unsafe_get_int64_t_bet.buf~pos:(postlen));;let[@inlinealways]int64_t_let=uadvtlen(unsafe_get_int64_t_let.buf~pos:(postlen));;let[@inlinealways]int64_be_trunct=uadvtlen(unsafe_get_int64_be_trunct.buf~pos:(postlen));;let[@inlinealways]int64_le_trunct=uadvtlen(unsafe_get_int64_le_trunct.buf~pos:(postlen));;endletwrite_bin_protwritert~posa=letlen=writer.Bin_prot.Type_class.sizeainletbuf_pos=buf_pos_exnt~pos~leninletstop_pos=writer.Bin_prot.Type_class.writet.buf~pos:buf_posainifstop_pos-buf_pos=lenthenlenelsefailt"Iobuf.write_bin_prot got unexpected number of bytes written (Bin_prot bug: \
Type_class.write disagrees with .size)"(`size_lenlen,`buf_posbuf_pos,`write_stop_posstop_pos)[%sexp_of:[`size_lenofint]*[`buf_posofint]*[`write_stop_posofint]];;(* [Itoa] provides a range of functions for integer to ASCII conversion, used by [Poke],
[Fill] and their [Unsafe] versions.
The implementation here is done in terms of negative decimals due to the properties of
[Int.min_value]. Since the result of [Int.(abs min_value)] is [Int.min_value], an
attempt to utilize a positive decimal loop by writing the sign and calling [Int.abs x]
fails. The converse, with [- Int.max_value] works for both cases. *)moduleItoa=struct(* [num_digits x] returns the number of digits in [x] for non-positive integers
([num_digits 0] is defined as 1).
The below tends to perform better than a binary search or [/= 10 while <> 0], likely
due to decimal values for our applications skewing towards smaller numbers. *)letnum_digitsx=ifx>-10then1elseifx>-100then2elseifx>-1000then3elseifx>-10000then4elseifx>-100000then5elseifx>-1000000then6elseifx>-10000000then7elseifx>-100000000then8elseifx>-1000000000then9elseifarch_sixtyfourthenifx>-1000000000*10then10elseifx>-1000000000*100then11elseifx>-1000000000*1000then12elseifx>-1000000000*10000then13elseifx>-1000000000*100000then14elseifx>-1000000000*1000000then15elseifx>-1000000000*10000000then16elseifx>-1000000000*100000000then17elseifx>-1000000000*1000000000then18else19else10;;let()=assert(String.length(Int.to_stringInt.min_value)<=19+1)(* Despite the div/mod by a constant optimizations, it's a slight savings to avoid a
second div/mod. Note also that passing in an [int ref], rather than creating the ref
locally here, results in allocation on the benchmarks. *)letunsafe_poke_negative_decimal_without_signt~pos~lenint=letint=refintinforpos=pos+len-1downtoposdoletx=!intinint:=!int/10;bigstring_unsafe_sett.buf~pos(Char.unsafe_of_int(48+(-x+(!int*10))))done;;letunsafe_poke_negative_decimalt~pos~lenint=bigstring_unsafe_sett.buf~pos'-';(* +1 and -1 to account for '-' *)unsafe_poke_negative_decimal_without_signt~pos:(pos+1)~len:(len-1)int;;letpoke_decimalt~posint=ifint<0then(letlen=1+num_digitsintinunsafe_poke_negative_decimalt~pos:(buf_pos_exnt~pos~len)~lenint;len)else(letlen=num_digits(-int)inunsafe_poke_negative_decimal_without_signt~pos:(buf_pos_exnt~pos~len)~len(-int);len);;letunsafe_poke_decimalt~posint=ifint<0then(letlen=1+num_digitsintinunsafe_poke_negative_decimalt~pos:(unsafe_buf_post~pos)~lenint;len)else(letlen=num_digits(-int)inunsafe_poke_negative_decimal_without_signt~pos:(unsafe_buf_post~pos)~len(-int);len);;endmoduleFill=structtypenonrec('a,'d,'w)t=(read_write,seek)t->'a->unitconstraint'd=[>read]letpostlen=buf_pos_exnt~pos:0~lenletuadv=unsafe_advancelettail_padded_fixed_string~padding~lentsrc=Bigstring.set_tail_padded_fixed_string~padding~lent.buf~pos:(postlen)src;uadvtlen;;lethead_padded_fixed_string~padding~lentsrc=Bigstring.set_head_padded_fixed_string~padding~lent.buf~pos:(postlen)src;uadvtlen;;letbytes~str_pos~lentsrc=Bigstring.From_bytes.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(postlen);uadvtlen;;letstring~str_pos~lentsrc=Bigstring.From_string.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(postlen);uadvtlen;;letbigstring~str_pos~lentsrc=Bigstring.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(postlen);uadvtlen;;letbyteso?(str_pos=0)?lentsrc=bytestsrc~str_pos~len:(matchlenwith|None->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lentsrc=stringtsrc~str_pos~len:(matchlenwith|None->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lentsrc=bigstringtsrc~str_pos~len:(matchlenwith|None->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_protwriterta=write_bin_protwritert~pos:0a|>uadvtopenBigstringletlen=1let[@inlinealways]chartc=bigstring_unsafe_sett.bufc~pos:(postlen);uadvtlen;;let[@inlinealways]uint8_truncti=unsafe_set_uint8t.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]int8_truncti=unsafe_set_int8t.bufi~pos:(postlen);uadvtlen;;letlen=2let[@inlinealways]int16_be_truncti=unsafe_set_int16_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]int16_le_truncti=unsafe_set_int16_let.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]uint16_be_truncti=unsafe_set_uint16_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]uint16_le_truncti=unsafe_set_uint16_let.bufi~pos:(postlen);uadvtlen;;letlen=4let[@inlinealways]int32_be_truncti=unsafe_set_int32_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]int32_le_truncti=unsafe_set_int32_let.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]uint32_be_truncti=unsafe_set_uint32_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]uint32_le_truncti=unsafe_set_uint32_let.bufi~pos:(postlen);uadvtlen;;letlen=8let[@inlinealways]int64_beti=unsafe_set_int64_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]int64_leti=unsafe_set_int64_let.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]uint64_be_truncti=unsafe_set_uint64_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]uint64_le_truncti=unsafe_set_uint64_let.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]int64_t_beti=unsafe_set_int64_t_bet.bufi~pos:(postlen);uadvtlen;;let[@inlinealways]int64_t_leti=unsafe_set_int64_t_let.bufi~pos:(postlen);uadvtlen;;letdecimalti=uadvt(Itoa.poke_decimalt~pos:0i)endmodulePeek=structtype'seeksrc=(read,'seek)tmoduleTo_bytes=Base_for_tests.Test_blit.Make_distinct_and_test(Char_elt)(T_src)(Bytes_dst)moduleTo_bigstring=Base_for_tests.Test_blit.Make_distinct_and_test(Char_elt)(T_src)(Bigstring_dst)moduleTo_string=String_dsttypenonrec('a,'d,'w)t=('d,'w)t->pos:int->'aconstraint'd=[>read]letspos=buf_pos_exn(* "safe position" *)lettail_padded_fixed_string~padding~lent~pos=Bigstring.get_tail_padded_fixed_stringt.buf~padding~len~pos:(spost~len~pos)();;lethead_padded_fixed_string~padding~lent~pos=Bigstring.get_head_padded_fixed_stringt.buf~padding~len~pos:(spost~len~pos)();;letbytes~str_pos~lent~pos=letdst=Bytes.create(len+str_pos)inBigstring.To_bytes.blit~src:t.buf~src_pos:(spost~len~pos)~len~dst~dst_pos:str_pos;dst;;letstring~str_pos~lent~pos=Bytes.unsafe_to_string~no_mutation_while_string_reachable:(bytes~str_pos~lent~pos);;letbigstring~str_pos~lent~pos=letdst=Bigstring.create(len+str_pos)inBigstring.blit~src:t.buf~src_pos:(spost~len~pos)~len~dst~dst_pos:str_pos;dst;;letbyteso?(str_pos=0)?lent~pos=bytest~pos~str_pos~len:(matchlenwith|None->lengtht-pos|Somelen->len);;letstringo?(str_pos=0)?lent~pos=stringt~pos~str_pos~len:(matchlenwith|None->lengtht-pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~pos=bigstringt~pos~str_pos~len:(matchlenwith|None->lengtht-pos|Somelen->len);;letbin_protreadert~pos=read_bin_protreadert~pos|>fstletindext?(pos=0)?(len=lengtht-pos)c=letpos=spost~len~posinOption.map(Bigstring.find~pos~lenct.buf)~f:(funx->x-t.lo);;openBigstringlet[@inlinealways]chart~pos=T_src.gettposletlen=1let[@inlinealways]uint8t~pos=unsafe_get_uint8t.buf~pos:(spost~len~pos)let[@inlinealways]int8t~pos=unsafe_get_int8t.buf~pos:(spost~len~pos)letlen=2let[@inlinealways]int16_bet~pos=unsafe_get_int16_bet.buf~pos:(spost~len~pos)let[@inlinealways]int16_let~pos=unsafe_get_int16_let.buf~pos:(spost~len~pos)let[@inlinealways]uint16_bet~pos=unsafe_get_uint16_bet.buf~pos:(spost~len~pos);;let[@inlinealways]uint16_let~pos=unsafe_get_uint16_let.buf~pos:(spost~len~pos);;letlen=4let[@inlinealways]int32_bet~pos=unsafe_get_int32_bet.buf~pos:(spost~len~pos)let[@inlinealways]int32_let~pos=unsafe_get_int32_let.buf~pos:(spost~len~pos)let[@inlinealways]uint32_bet~pos=unsafe_get_uint32_bet.buf~pos:(spost~len~pos);;let[@inlinealways]uint32_let~pos=unsafe_get_uint32_let.buf~pos:(spost~len~pos);;letlen=8let[@inlinealways]int64_be_exnt~pos=unsafe_get_int64_be_exnt.buf~pos:(spost~len~pos);;let[@inlinealways]int64_le_exnt~pos=unsafe_get_int64_le_exnt.buf~pos:(spost~len~pos);;let[@inlinealways]uint64_be_exnt~pos=unsafe_get_uint64_be_exnt.buf~pos:(spost~len~pos);;let[@inlinealways]uint64_le_exnt~pos=unsafe_get_uint64_le_exnt.buf~pos:(spost~len~pos);;let[@inlinealways]int64_t_bet~pos=unsafe_get_int64_t_bet.buf~pos:(spost~len~pos);;let[@inlinealways]int64_t_let~pos=unsafe_get_int64_t_let.buf~pos:(spost~len~pos);;let[@inlinealways]int64_be_trunct~pos=unsafe_get_int64_be_trunct.buf~pos:(spost~len~pos);;let[@inlinealways]int64_le_trunct~pos=unsafe_get_int64_le_trunct.buf~pos:(spost~len~pos);;endmodulePoke=structtypenonrec('a,'d,'w)t=(read_write,'w)t->pos:int->'a->unitconstraint'd=[>read]letspos=buf_pos_exn(* "safe position" *)lettail_padded_fixed_string~padding~lent~possrc=Bigstring.set_tail_padded_fixed_string~padding~lent.buf~pos:(spost~len~pos)src;;lethead_padded_fixed_string~padding~lent~possrc=Bigstring.set_head_padded_fixed_string~padding~lent.buf~pos:(spost~len~pos)src;;letbytes~str_pos~lent~possrc=Bigstring.From_bytes.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(spost~len~pos);;letstring~str_pos~lent~possrc=Bigstring.From_string.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(spost~len~pos);;letbigstring~str_pos~lent~possrc=Bigstring.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(spost~len~pos);;letbyteso?(str_pos=0)?lent~possrc=bytest~str_pos~possrc~len:(matchlenwith|None->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lent~possrc=stringt~str_pos~possrc~len:(matchlenwith|None->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~possrc=bigstringt~str_pos~possrc~len:(matchlenwith|None->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_prot_size=write_bin_protletbin_protwritert~posa=ignore(bin_prot_sizewritert~posa:int)openBigstringletlen=1let[@inlinealways]chart~posc=T_src.settposclet[@inlinealways]uint8_trunct~posi=unsafe_set_uint8t.buf~pos:(spost~len~pos)i;;let[@inlinealways]int8_trunct~posi=unsafe_set_int8t.buf~pos:(spost~len~pos)i;;letlen=2let[@inlinealways]int16_be_trunct~posi=unsafe_set_int16_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]int16_le_trunct~posi=unsafe_set_int16_let.buf~pos:(spost~len~pos)i;;let[@inlinealways]uint16_be_trunct~posi=unsafe_set_uint16_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]uint16_le_trunct~posi=unsafe_set_uint16_let.buf~pos:(spost~len~pos)i;;letlen=4let[@inlinealways]int32_be_trunct~posi=unsafe_set_int32_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]int32_le_trunct~posi=unsafe_set_int32_let.buf~pos:(spost~len~pos)i;;let[@inlinealways]uint32_be_trunct~posi=unsafe_set_uint32_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]uint32_le_trunct~posi=unsafe_set_uint32_let.buf~pos:(spost~len~pos)i;;letlen=8let[@inlinealways]int64_bet~posi=unsafe_set_int64_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]int64_let~posi=unsafe_set_int64_let.buf~pos:(spost~len~pos)i;;let[@inlinealways]uint64_be_trunct~posi=unsafe_set_uint64_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]uint64_le_trunct~posi=unsafe_set_uint64_let.buf~pos:(spost~len~pos)i;;let[@inlinealways]int64_t_bet~posi=unsafe_set_int64_t_bet.buf~pos:(spost~len~pos)i;;let[@inlinealways]int64_t_let~posi=unsafe_set_int64_t_let.buf~pos:(spost~len~pos)i;;letdecimal=Itoa.poke_decimalendmoduleBlit=structmoduleT_dst=structincludeT_srcletunsafe_blit~src~src_pos~dst~dst_pos~len=Bigstring.unsafe_blit~len~src:src.buf~src_pos:(unsafe_buf_possrc~pos:src_pos)~dst:dst.buf~dst_pos:(unsafe_buf_posdst~pos:dst_pos);;endincludeBase_for_tests.Test_blit.Make_and_test(Char_elt)(T_dst)(* Workaround the inability of the compiler to inline in the presence of functors. *)letunsafe_blit=T_dst.unsafe_blitletblit_maximal~src?(src_pos=0)~dst?(dst_pos=0)()=letlen=min(lengthsrc-src_pos)(lengthdst-dst_pos)inblit~src~src_pos~dst~dst_pos~len;len;;endmoduleBlit_consume=structletunsafe_blit~src~dst~dst_pos~len=Blit.unsafe_blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclen;;letblit~src~dst~dst_pos~len=Blit.blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclen;;letblito~src?(src_len=lengthsrc)~dst?(dst_pos=0)()=blit~src~dst~dst_pos~len:src_len;;letsubsrc~len=letdst=Blit.subsrc~pos:0~leninunsafe_advancesrclen;dst;;letsubo?lensrc=letlen=matchlenwith|None->lengthsrc|Somelen->leninsubsrc~len;;letblit_maximal~src~dst?(dst_pos=0)()=letlen=min(lengthsrc)(lengthdst-dst_pos)inblit~src~dst~dst_pos~len;len;;endmoduleBlit_fill=structletunsafe_blit~src~src_pos~dst~len=Blit.unsafe_blit~src~src_pos~dst~dst_pos:0~len;unsafe_advancedstlen;;letblit~src~src_pos~dst~len=Blit.blit~src~src_pos~dst~dst_pos:0~len;unsafe_advancedstlen;;letblito~src?(src_pos=0)?(src_len=lengthsrc-src_pos)~dst()=blit~src~src_pos~dst~len:src_len;;letblit_maximal~src?(src_pos=0)~dst()=letlen=min(lengthsrc-src_pos)(lengthdst)inblit~src~src_pos~dst~len;len;;endmoduleBlit_consume_and_fill=structletunsafe_blit~src~dst~len=ifphys_equalsrcdstthenadvancesrclenelse(Blit.unsafe_blit~src~src_pos:0~dst~dst_pos:0~len;unsafe_advancesrclen;unsafe_advancedstlen);;letblit~src~dst~len=ifphys_equalsrcdstthenadvancesrclenelse(Blit.blit~src~src_pos:0~dst~dst_pos:0~len;unsafe_advancesrclen;unsafe_advancedstlen);;letblito~src?(src_len=lengthsrc)~dst()=blit~src~dst~len:src_lenletblit_maximal~src~dst=letlen=min(lengthsrc)(lengthdst)in(* [len] is naturally validated to be correct; don't double-check it.
Sadly, we can't do this for the other [Blit_*] modules, as they can have
invalid [src_pos]/[dst_pos] values which a) have to be checked on their own
and b) can lead to the construction of unsafe [len] values. *)unsafe_blit~src~dst~len;len;;endletbin_prot_length_prefix_bytes=4letconsume_bin_prottbin_prot_reader=letresult=iflengtht<bin_prot_length_prefix_bytesthenerror"Iobuf.consume_bin_prot not enough data to read length"t[%sexp_of:(_,_)t]else(letmark=t.loinletv_len=Consume.int32_betinifv_len>lengthtthen(t.lo<-mark;error"Iobuf.consume_bin_prot not enough data to read value"(v_len,t)[%sexp_of:int*(_,_)t])elseOk(Consume.bin_protbin_prot_readert))inresult;;letfill_bin_prottwriterv=letv_len=writer.Bin_prot.Type_class.sizevinletneed=v_len+bin_prot_length_prefix_bytesinletresult=ifneed>lengthtthenerror"Iobuf.fill_bin_prot not enough space"(need,t)[%sexp_of:int*(_,_)t]else(Fill.int32_be_trunctv_len;Fill.bin_protwritertv;Ok())inresult;;moduleExpert=structletbuft=t.buflethi_maxt=t.hi_maxlethit=t.hiletlot=t.loletlo_mint=t.lo_minletset_buftbuf=t.buf<-bufletset_hi_maxthi_max=t.hi_max<-hi_maxletset_hithi=t.hi<-hiletset_lotlo=t.lo<-loletset_lo_mintlo_min=t.lo_min<-lo_minletto_bigstring_shared?pos?lent=letpos,len=Ordered_collection_common.get_pos_len_exn()?pos?len~total_length:(lengtht)inBigstring.sub_sharedt.buf~pos:(t.lo+pos)~len;;letreinitialize_of_bigstringt~pos~lenbuf=letstr_len=Bigstring.lengthbufinifpos<0||pos>str_lenthenraise_s[%message"Expert.reinitialize_of_bigstring got invalid pos"(pos:int)(str_len:int)];letmax_len=str_len-posiniflen<0||len>max_lenthenraise_s[%message"Expert.reinitialize_of_bigstring got invalid len"(len:int)(max_len:int)];letlo=posinlethi=pos+lenin(* avoid [caml_modify], if possible *)ifnot(phys_equalt.bufbuf)thent.buf<-buf;t.lo_min<-lo;t.lo<-lo;t.hi<-hi;t.hi_max<-hi;;let_remember_to_update_reinitialize_of_bigstring:(_,_)t->buf:Bigstring.t->lo_min:int->lo:int->hi:int->hi_max:int->unit=Fields.Direct.set_all_mutable_fields;;letset_bounds_and_buffer=set_bounds_and_bufferletset_bounds_and_buffer_sub=set_bounds_and_buffer_subletprotect_windowt~f=letlo=t.loinlethi=t.hiintryletresult=ftint.lo<-lo;t.hi<-hi;resultwith|exn->t.lo<-lo;t.hi<-hi;raiseexn;;endmoduleUnsafe=structmoduleConsume=struct(* copy of Consume with pos replaced by an unsafe version *)typesrc=Consume.srcmoduleTo_bytes=structincludeConsume.To_bytesletblit=unsafe_blitendmoduleTo_bigstring=structincludeConsume.To_bigstringletblit=unsafe_blitendmoduleTo_string=Consume.To_stringtype('a,'d,'w)t=('a,'d,'w)Consume.tletuadvtnx=unsafe_advancetn;x[@@inlinealways];;letupost=unsafe_buf_post~pos:0lettail_padded_fixed_string~padding~lent=uadvtlen(Bigstring.get_tail_padded_fixed_stringt.buf~pos:(upost)~padding~len());;lethead_padded_fixed_string~padding~lent=uadvtlen(Bigstring.get_head_padded_fixed_stringt.buf~pos:(upost)~padding~len());;letbytes=Consume.bytesletstring=Consume.stringletbigstring=Consume.bigstringletbyteso=Consume.bytesoletstringo=Consume.stringoletbigstringo=Consume.bigstringoletbin_prot=Consume.bin_protopenBigstringletlen=1let[@inlinealways]chart=uadvtlen(bigstring_unsafe_gett.buf~pos:(upost))let[@inlinealways]uint8t=uadvtlen(unsafe_get_uint8t.buf~pos:(upost))let[@inlinealways]int8t=uadvtlen(unsafe_get_int8t.buf~pos:(upost))letlen=2let[@inlinealways]int16_bet=uadvtlen(unsafe_get_int16_bet.buf~pos:(upost))let[@inlinealways]int16_let=uadvtlen(unsafe_get_int16_let.buf~pos:(upost))let[@inlinealways]uint16_bet=uadvtlen(unsafe_get_uint16_bet.buf~pos:(upost));;let[@inlinealways]uint16_let=uadvtlen(unsafe_get_uint16_let.buf~pos:(upost));;letlen=4let[@inlinealways]int32_bet=uadvtlen(unsafe_get_int32_bet.buf~pos:(upost))let[@inlinealways]int32_let=uadvtlen(unsafe_get_int32_let.buf~pos:(upost))let[@inlinealways]uint32_bet=uadvtlen(unsafe_get_uint32_bet.buf~pos:(upost));;let[@inlinealways]uint32_let=uadvtlen(unsafe_get_uint32_let.buf~pos:(upost));;letlen=8let[@inlinealways]int64_be_exnt=uadvtlen(unsafe_get_int64_be_exnt.buf~pos:(upost));;let[@inlinealways]int64_le_exnt=uadvtlen(unsafe_get_int64_le_exnt.buf~pos:(upost));;let[@inlinealways]uint64_be_exnt=uadvtlen(unsafe_get_uint64_be_exnt.buf~pos:(upost));;let[@inlinealways]uint64_le_exnt=uadvtlen(unsafe_get_uint64_le_exnt.buf~pos:(upost));;let[@inlinealways]int64_t_bet=uadvtlen(unsafe_get_int64_t_bet.buf~pos:(upost));;let[@inlinealways]int64_t_let=uadvtlen(unsafe_get_int64_t_let.buf~pos:(upost));;let[@inlinealways]int64_be_trunct=uadvtlen(unsafe_get_int64_be_trunct.buf~pos:(upost));;let[@inlinealways]int64_le_trunct=uadvtlen(unsafe_get_int64_le_trunct.buf~pos:(upost));;endmoduleFill=structtype('a,'d,'w)t=('a,'d,'w)Fill.t(* copy with unsafe pos *)letupost_len=unsafe_buf_post~pos:0letuadvtn=unsafe_advancetnlettail_padded_fixed_string~padding~lentsrc=Bigstring.set_tail_padded_fixed_string~padding~lent.buf~pos:(upostlen)src;uadvtlen;;lethead_padded_fixed_string~padding~lentsrc=Bigstring.set_head_padded_fixed_string~padding~lent.buf~pos:(upostlen)src;uadvtlen;;letbytes~str_pos~lentsrc=Bigstring.From_bytes.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(upostlen);uadvtlen;;letstring~str_pos~lentsrc=Bigstring.From_string.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(upostlen);uadvtlen;;letbigstring~str_pos~lentsrc=Bigstring.blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(upostlen);uadvtlen;;letbyteso?(str_pos=0)?lentsrc=bytestsrc~str_pos~len:(matchlenwith|None->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lentsrc=stringtsrc~str_pos~len:(matchlenwith|None->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lentsrc=bigstringtsrc~str_pos~len:(matchlenwith|None->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_prot=Fill.bin_protopenBigstringletlen=1let[@inlinealways]chartc=bigstring_unsafe_sett.bufc~pos:(upostlen);uadvtlen;;letlen=2let[@inlinealways]int16_be_truncti=unsafe_set_int16_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]int16_le_truncti=unsafe_set_int16_let.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]uint16_be_truncti=unsafe_set_uint16_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]uint16_le_truncti=unsafe_set_uint16_let.bufi~pos:(upostlen);uadvtlen;;letlen=4let[@inlinealways]int32_be_truncti=unsafe_set_int32_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]int32_le_truncti=unsafe_set_int32_let.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]uint32_be_truncti=unsafe_set_uint32_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]uint32_le_truncti=unsafe_set_uint32_let.bufi~pos:(upostlen);uadvtlen;;letlen=8let[@inlinealways]int64_beti=unsafe_set_int64_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]int64_leti=unsafe_set_int64_let.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]uint64_be_truncti=unsafe_set_uint64_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]uint64_le_truncti=unsafe_set_uint64_let.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]int64_t_beti=unsafe_set_int64_t_bet.bufi~pos:(upostlen);uadvtlen;;let[@inlinealways]int64_t_leti=unsafe_set_int64_t_let.bufi~pos:(upostlen);uadvtlen;;(* Bigstring int8 accessors are slow C calls. Use the fast char primitive. *)let[@inlinealways]uint8_truncti=chart(Char.unsafe_of_inti)let[@inlinealways]int8_truncti=chart(Char.unsafe_of_inti)letdecimalti=uadvt(Itoa.unsafe_poke_decimalt~pos:0i)endmodulePeek=structtype'seeksrc='seekPeek.srcmoduleTo_bytes=structincludePeek.To_bytesletblit=unsafe_blitendmoduleTo_bigstring=structincludePeek.To_bigstringletblit=unsafe_blitendmoduleTo_string=Peek.To_stringtype('a,'d,'w)t=('a,'d,'w)Peek.tletupos=unsafe_buf_poslettail_padded_fixed_string~padding~lent~pos=Bigstring.get_tail_padded_fixed_stringt.buf~padding~len~pos:(upost~pos)();;lethead_padded_fixed_string~padding~lent~pos=Bigstring.get_head_padded_fixed_stringt.buf~padding~len~pos:(upost~pos)();;letbytes~str_pos~lent~pos=letdst=Bytes.create(len+str_pos)inBigstring.To_bytes.unsafe_blit~src:t.buf~src_pos:(upost~pos)~len~dst~dst_pos:str_pos;dst;;letstring~str_pos~lent~pos=Bytes.unsafe_to_string~no_mutation_while_string_reachable:(bytes~str_pos~lent~pos);;letbigstring~str_pos~lent~pos=letdst=Bigstring.create(len+str_pos)inBigstring.unsafe_blit~src:t.buf~src_pos:(upost~pos)~len~dst~dst_pos:str_pos;dst;;letbyteso?(str_pos=0)?lent~pos=bytest~pos~str_pos~len:(matchlenwith|None->lengtht-pos|Somelen->len);;letstringo?(str_pos=0)?lent~pos=stringt~pos~str_pos~len:(matchlenwith|None->lengtht-pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~pos=bigstringt~pos~str_pos~len:(matchlenwith|None->lengtht-pos|Somelen->len);;letbin_prot=Peek.bin_protletindex=Peek.indexopenBigstringlet[@inlinealways]chart~pos=bigstring_unsafe_gett.buf~pos:(upost~pos)let[@inlinealways]uint8t~pos=unsafe_get_uint8t.buf~pos:(upost~pos)let[@inlinealways]int8t~pos=unsafe_get_int8t.buf~pos:(upost~pos)let[@inlinealways]int16_bet~pos=unsafe_get_int16_bet.buf~pos:(upost~pos)let[@inlinealways]int16_let~pos=unsafe_get_int16_let.buf~pos:(upost~pos)let[@inlinealways]uint16_bet~pos=unsafe_get_uint16_bet.buf~pos:(upost~pos)let[@inlinealways]uint16_let~pos=unsafe_get_uint16_let.buf~pos:(upost~pos)let[@inlinealways]int32_bet~pos=unsafe_get_int32_bet.buf~pos:(upost~pos)let[@inlinealways]int32_let~pos=unsafe_get_int32_let.buf~pos:(upost~pos)let[@inlinealways]uint32_bet~pos=unsafe_get_uint32_bet.buf~pos:(upost~pos)let[@inlinealways]uint32_let~pos=unsafe_get_uint32_let.buf~pos:(upost~pos)let[@inlinealways]int64_be_exnt~pos=unsafe_get_int64_be_exnt.buf~pos:(upost~pos);;let[@inlinealways]int64_le_exnt~pos=unsafe_get_int64_le_exnt.buf~pos:(upost~pos);;let[@inlinealways]uint64_be_exnt~pos=unsafe_get_uint64_be_exnt.buf~pos:(upost~pos);;let[@inlinealways]uint64_le_exnt~pos=unsafe_get_uint64_le_exnt.buf~pos:(upost~pos);;let[@inlinealways]int64_t_bet~pos=unsafe_get_int64_t_bet.buf~pos:(upost~pos);;let[@inlinealways]int64_t_let~pos=unsafe_get_int64_t_let.buf~pos:(upost~pos);;let[@inlinealways]int64_be_trunct~pos=unsafe_get_int64_be_trunct.buf~pos:(upost~pos);;let[@inlinealways]int64_le_trunct~pos=unsafe_get_int64_le_trunct.buf~pos:(upost~pos);;endmodulePoke=structtype('a,'d,'w)t=('a,'d,'w)Poke.tletupos=unsafe_buf_poslettail_padded_fixed_string~padding~lent~possrc=Bigstring.set_tail_padded_fixed_string~padding~lent.buf~pos:(upost~pos)src;;lethead_padded_fixed_string~padding~lent~possrc=Bigstring.set_head_padded_fixed_string~padding~lent.buf~pos:(upost~pos)src;;letbytes~str_pos~lent~possrc=Bigstring.From_bytes.unsafe_blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(upost~pos);;letstring~str_pos~lent~possrc=Bigstring.From_string.unsafe_blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(upost~pos);;letbigstring~str_pos~lent~possrc=Bigstring.unsafe_blit~src~src_pos:str_pos~len~dst:t.buf~dst_pos:(upost~pos);;letbyteso?(str_pos=0)?lent~possrc=bytest~str_pos~possrc~len:(matchlenwith|None->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lent~possrc=stringt~str_pos~possrc~len:(matchlenwith|None->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~possrc=bigstringt~str_pos~possrc~len:(matchlenwith|None->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_prot=Poke.bin_protletbin_prot_size=Poke.bin_prot_sizeopenBigstringlet[@inlinealways]chart~posc=bigstring_unsafe_sett.buf~pos:(upost~pos)clet[@inlinealways]uint8_trunct~posi=unsafe_set_uint8t.buf~pos:(upost~pos)i;;let[@inlinealways]int8_trunct~posi=unsafe_set_int8t.buf~pos:(upost~pos)ilet[@inlinealways]int16_be_trunct~posi=unsafe_set_int16_bet.buf~pos:(upost~pos)i;;let[@inlinealways]int16_le_trunct~posi=unsafe_set_int16_let.buf~pos:(upost~pos)i;;let[@inlinealways]uint16_be_trunct~posi=unsafe_set_uint16_bet.buf~pos:(upost~pos)i;;let[@inlinealways]uint16_le_trunct~posi=unsafe_set_uint16_let.buf~pos:(upost~pos)i;;let[@inlinealways]int32_be_trunct~posi=unsafe_set_int32_bet.buf~pos:(upost~pos)i;;let[@inlinealways]int32_le_trunct~posi=unsafe_set_int32_let.buf~pos:(upost~pos)i;;let[@inlinealways]uint32_be_trunct~posi=unsafe_set_uint32_bet.buf~pos:(upost~pos)i;;let[@inlinealways]uint32_le_trunct~posi=unsafe_set_uint32_let.buf~pos:(upost~pos)i;;let[@inlinealways]int64_bet~posi=unsafe_set_int64_bet.buf~pos:(upost~pos)i;;let[@inlinealways]int64_let~posi=unsafe_set_int64_let.buf~pos:(upost~pos)i;;let[@inlinealways]uint64_be_trunct~posi=unsafe_set_uint64_bet.buf~pos:(upost~pos)i;;let[@inlinealways]uint64_le_trunct~posi=unsafe_set_uint64_let.buf~pos:(upost~pos)i;;let[@inlinealways]int64_t_bet~posi=unsafe_set_int64_t_bet.buf~pos:(upost~pos)i;;let[@inlinealways]int64_t_let~posi=unsafe_set_int64_t_let.buf~pos:(upost~pos)i;;letdecimal=Itoa.unsafe_poke_decimalendendmoduleFor_hexdump=structmoduleT2=structtypenonrec('rw,'seek)t=('rw,'seek)tendmoduleWindow_indexable=structincludeT2letlengtht=lengthtletgettpos=Peek.chart~posendmoduleLimits_indexable=structincludeT2letlengtht=t.hi_max-t.lo_minletgettpos=Bigstring.gett.buf(t.lo_min+pos)endmoduleBuffer_indexable=structincludeT2letlengtht=Bigstring.lengtht.bufletgettpos=Bigstring.gett.bufposendmoduleWindow=Hexdump.Of_indexable2(Window_indexable)moduleLimits=Hexdump.Of_indexable2(Limits_indexable)moduleBuffer=Hexdump.Of_indexable2(Buffer_indexable)moduletypeRelative_indexable=sigvalname:stringvallo:(_,_)t->intvalhi:(_,_)t->intendmoduletypeCompound_indexable=sigincludeHexdump.S2withtype('rw,'seek)t:=('rw,'seek)tvalparts:(moduleRelative_indexable)listendmoduleMake_compound_hexdump(Compound:Compound_indexable)=structmoduleHexdump=structincludeT2letrelative_sequence?max_linest(moduleRelative:Relative_indexable)=letlo=Relative.lotinlethi=Relative.hitinCompound.Hexdump.to_sequence?max_lines~pos:lo~len:(hi-lo)t;;letto_sequence?max_linest=List.concat_mapCompound.parts~f:(fun(moduleRelative)->[Sequence.singleton(String.capitalizeRelative.name);relative_sequence?max_linest(moduleRelative)|>Sequence.map~f:(funline->" "^line)])|>Sequence.of_list|>Sequence.concat;;letto_string_hum?max_linest=to_sequence?max_linest|>Sequence.to_list|>String.concat~sep:"\n";;letsexp_of_t__t=List.mapCompound.parts~f:(fun(moduleRelative)->Relative.name,Sequence.to_list(relative_sequencet(moduleRelative)))|>[%sexp_of:(string*stringlist)list];;endendmoduleWindow_within_limits=structletname="window"letlot=t.lo-t.lo_minlethit=t.hi-t.lo_minendmoduleLimits_within_limits=structletname="limits"letlo_=0lethit=t.hi_max-t.lo_minendmoduleWindow_within_buffer=structletname="window"letlot=t.lolethit=t.hiendmoduleLimits_within_buffer=structletname="limits"letlot=t.lo_minlethit=t.hi_maxendmoduleBuffer_within_buffer=structletname="buffer"letlo_=0lethit=Bigstring.lengtht.bufendmoduleWindow_and_limits=Make_compound_hexdump(structincludeLimitsletparts=[(moduleWindow_within_limits:Relative_indexable);(moduleLimits_within_limits:Relative_indexable)];;end)moduleWindow_and_limits_and_buffer=Make_compound_hexdump(structincludeBufferletparts=[(moduleWindow_within_buffer:Relative_indexable);(moduleLimits_within_buffer:Relative_indexable);(moduleBuffer_within_buffer:Relative_indexable)];;end)endmoduleWindow=For_hexdump.WindowmoduleLimits=For_hexdump.LimitsmoduleDebug=For_hexdump.Window_and_limits_and_bufferincludeFor_hexdump.Window_and_limitsletto_string_hum=Hexdump.to_string_humletmemcmpab=letlen=lengthainletc=Int.comparelen(lengthb)inifc<>0thencelseBigstring.memcmp~pos1:a.loa.buf~pos2:b.lob.buf~len;;letmemsett~pos~lenc=Bigstring.memset~pos:(buf_pos_exnt~pos~len)~lent.bufcletzerot=memsett~pos:0~len:(lengtht)'\000'