12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667[%%import"config.h"]moduleBigstring_in_this_directory=Bigstringopen!ImportmoduleBigstring=Bigstring_in_this_directorymoduleUnix=Core_unixletarch_sixtyfour=Sys.word_size=64moduleT=structtypet=(* WHEN YOU CHANGE THIS, CHANGE iobuf_fields IN iobuf.h AS WELL!!! *){mutablebuf:Bigstring.tsexp_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]endopenTtype(-'read_write,+'seek)t=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. *)failwithsmessage(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.loletis_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))withe->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]];[@@inlinenever];;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_lenthenfailwiths"Iobuf.of_bigstring got invalid pos"(pos,`str_lenstr_len)([%sexp_of:int*[`str_lenofint]]);posinletlen=matchlenwith|None->str_len-pos|Somelen->letmax_len=str_len-posiniflen<0||len>max_lenthenfailwiths"Iobuf.of_bigstring got invalid len"(len,`max_lenmax_len)([%sexp_of:int*[`max_lenofint]]);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;};;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_hitletunsafe_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;resultwithexn->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;resultwithexn->t.lo<-lo;t.hi<-hi;t.lo_min<-lo_min;t.hi_max<-hi_max;t.buf<-buf;raiseexn;;letcreate~len=iflen<0thenfailwiths"Iobuf.create got negative len"len[%sexp_of:int];of_bigstring(Bigstring.createlen);;;letto_string?lent=letlen=matchlenwith|Somelen->check_ranget~pos:0~len;len|None->lengthtinBigstring.to_stringt.buf~pos:t.lo~lenletof_strings=of_bigstring(Bigstring.of_strings)letto_bytest=Bigstring.to_bytest.buf~pos:t.lo~len:(lengtht)letof_bytess=of_bigstring(Bigstring.of_bytess)(* 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~posletunsafe_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=functiontrue->'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)cendmoduleBytes_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~lenletcreate~len=createlenendmoduleString_dst=structletsubsrc~pos~len=Bigstring.To_string.subsrc.buf~pos:(buf_pos_exnsrc~pos~len)~lenletsubo?(pos=0)?lensrc=letlen=matchlenwithNone->lengthsrc-pos|Somelen->leninBigstring.To_string.subosrc.buf~pos:(buf_pos_exnsrc~pos~len)~lenendmoduleBigstring_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~lenletcreate~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)=structincludeTest_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_advancesrclenletblito~src?(src_len=lengthsrc)~dst?dst_pos()=blito~src~src_pos:0~src_len~dst?dst_pos();unsafe_advancesrcsrc_lenletunsafe_blit~src~dst~dst_pos~len=unsafe_blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclenletsubsrc~len=letdst=subsrc~pos:0~leninunsafe_advancesrclen;dstletsubo?lensrc=letlen=matchlenwithNone->lengthsrc|Somelen->leninletdst=subo~pos:0~lensrcinunsafe_advancesrclen;dstendmoduleTo_bytes=To(Bytes_dst)moduleTo_bigstring=To(Bigstring_dst)moduleTo_string=structincludeTo_bytesletsubsrc~len=letdst=String_dst.subsrc~len~pos:0inunsafe_advancesrclen;dstletsubo?lensrc=letlen=matchlenwithNone->lengthsrc|Somelen->leninletdst=String_dst.subo~pos:0~lensrcinunsafe_advancesrclen;dstendtypenonrec('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:(matchlenwithNone->lengtht|Somelen->len);;letstringo?(str_pos=0)?lent=stringt~str_pos~len:(matchlenwithNone->lengtht|Somelen->len);;letbigstringo?(str_pos=0)?lent=bigstringt~str_pos~len:(matchlenwithNone->lengtht|Somelen->len);;letbin_protreadert=let(a,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*1000000000then18else19else10let()=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)));doneletunsafe_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)intletpoke_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:(matchlenwithNone->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lentsrc=stringtsrc~str_pos~len:(matchlenwithNone->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lentsrc=bigstringtsrc~str_pos~len:(matchlenwithNone->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_protwriterta=write_bin_protwritert~pos:0a|>uadvtopenBigstringletlen=1let[@inlinealways]chartc=bigstring_unsafe_sett.bufc~pos:(postlen);uadvtlenlet[@inlinealways]uint8_truncti=unsafe_set_uint8t.bufi~pos:(postlen);uadvtlenlet[@inlinealways]int8_truncti=unsafe_set_int8t.bufi~pos:(postlen);uadvtlenletlen=2let[@inlinealways]int16_be_truncti=unsafe_set_int16_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]int16_le_truncti=unsafe_set_int16_let.bufi~pos:(postlen);uadvtlenlet[@inlinealways]uint16_be_truncti=unsafe_set_uint16_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]uint16_le_truncti=unsafe_set_uint16_let.bufi~pos:(postlen);uadvtlenletlen=4let[@inlinealways]int32_be_truncti=unsafe_set_int32_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]int32_le_truncti=unsafe_set_int32_let.bufi~pos:(postlen);uadvtlenlet[@inlinealways]uint32_be_truncti=unsafe_set_uint32_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]uint32_le_truncti=unsafe_set_uint32_let.bufi~pos:(postlen);uadvtlenletlen=8let[@inlinealways]int64_beti=unsafe_set_int64_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]int64_leti=unsafe_set_int64_let.bufi~pos:(postlen);uadvtlenlet[@inlinealways]uint64_be_truncti=unsafe_set_uint64_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]uint64_le_truncti=unsafe_set_uint64_let.bufi~pos:(postlen);uadvtlenlet[@inlinealways]int64_t_beti=unsafe_set_int64_t_bet.bufi~pos:(postlen);uadvtlenlet[@inlinealways]int64_t_leti=unsafe_set_int64_t_let.bufi~pos:(postlen);uadvtlenletdecimalti=uadvt(Itoa.poke_decimalt~pos:0i)endmodulePeek=structtypesrc=(read,no_seek)tmoduleTo_bytes=Test_blit.Make_distinct_and_test(Char_elt)(T_src)(Bytes_dst)moduleTo_bigstring=Test_blit.Make_distinct_and_test(Char_elt)(T_src)(Bigstring_dst)moduleTo_string=structincludeTo_bytesincludeString_dstendtypenonrec('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:(matchlenwithNone->lengtht-pos|Somelen->len);;letstringo?(str_pos=0)?lent~pos=stringt~pos~str_pos~len:(matchlenwithNone->lengtht-pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~pos=bigstringt~pos~str_pos~len:(matchlenwithNone->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:(matchlenwithNone->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lent~possrc=stringt~str_pos~possrc~len:(matchlenwithNone->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~possrc=bigstringt~str_pos~possrc~len:(matchlenwithNone->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_protwritert~posa=write_bin_protwritert~posa|>(ignore:int->unit)openBigstringletlen=1let[@inlinealways]chart~posc=T_src.settposclet[@inlinealways]uint8_trunct~posi=unsafe_set_uint8t.buf~pos:(spost~len~pos)ilet[@inlinealways]int8_trunct~posi=unsafe_set_int8t.buf~pos:(spost~len~pos)iletlen=2let[@inlinealways]int16_be_trunct~posi=unsafe_set_int16_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]int16_le_trunct~posi=unsafe_set_int16_let.buf~pos:(spost~len~pos)ilet[@inlinealways]uint16_be_trunct~posi=unsafe_set_uint16_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]uint16_le_trunct~posi=unsafe_set_uint16_let.buf~pos:(spost~len~pos)iletlen=4let[@inlinealways]int32_be_trunct~posi=unsafe_set_int32_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]int32_le_trunct~posi=unsafe_set_int32_let.buf~pos:(spost~len~pos)ilet[@inlinealways]uint32_be_trunct~posi=unsafe_set_uint32_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]uint32_le_trunct~posi=unsafe_set_uint32_let.buf~pos:(spost~len~pos)iletlen=8let[@inlinealways]int64_bet~posi=unsafe_set_int64_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]int64_let~posi=unsafe_set_int64_let.buf~pos:(spost~len~pos)ilet[@inlinealways]uint64_be_trunct~posi=unsafe_set_uint64_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]uint64_le_trunct~posi=unsafe_set_uint64_let.buf~pos:(spost~len~pos)ilet[@inlinealways]int64_t_bet~posi=unsafe_set_int64_t_bet.buf~pos:(spost~len~pos)ilet[@inlinealways]int64_t_let~posi=unsafe_set_int64_t_let.buf~pos:(spost~len~pos)iletdecimal=Itoa.poke_decimalendmoduleBlit=structtype'rwt_no_seek=('rw,no_seek)tmoduleT_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)endincludeTest_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_blitendmoduleBlit_consume=structletunsafe_blit~src~dst~dst_pos~len=Blit.unsafe_blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclenletblit~src~dst~dst_pos~len=Blit.blit~src~src_pos:0~dst~dst_pos~len;unsafe_advancesrclenletblito~src?(src_len=lengthsrc)~dst?(dst_pos=0)()=blit~src~dst~dst_pos~len:src_lenletsubsrc~len=letdst=Blit.subsrc~pos:0~leninunsafe_advancesrclen;dstletsubo?lensrc=letlen=matchlenwithNone->lengthsrc|Somelen->leninsubsrc~lenendmoduleBlit_fill=structletunsafe_blit~src~src_pos~dst~len=Blit.unsafe_blit~src~src_pos~dst~dst_pos:0~len;unsafe_advancedstlenletblit~src~src_pos~dst~len=Blit.blit~src~src_pos~dst~dst_pos:0~len;unsafe_advancedstlenletblito~src?(src_pos=0)?(src_len=lengthsrc-src_pos)~dst()=blit~src~src_pos~dst~len:src_lenendmoduleBlit_consume_and_fill=structletunsafe_blit~src~dst~len=ifphys_equalsrcdstthenadvancesrclenelsebeginBlit.unsafe_blit~src~src_pos:0~dst~dst_pos:0~len;unsafe_advancesrclen;unsafe_advancedstlenendletblit~src~dst~len=ifphys_equalsrcdstthenadvancesrclenelsebeginBlit.blit~src~src_pos:0~dst~dst_pos:0~len;unsafe_advancesrclen;unsafe_advancedstlenendletblito~src?(src_len=lengthsrc)~dst()=blit~src~dst~len:src_lenendletbin_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])elsebeginletmark=t.loinletv_len=Consume.int32_betinifv_len>lengthtthenbegint.lo<-mark;error"Iobuf.consume_bin_prot not enough data to read value"(v_len,t)([%sexp_of:int*(_,_)t]);endelseOk(Consume.bin_protbin_prot_readert)endinresult;;;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])elsebeginFill.int32_be_trunctv_len;Fill.bin_protwritertv;Ok();endinresult;;;moduleExpert=structletbuft=t.buflethi_maxt=t.hi_maxlethit=t.hiletlot=t.loletlo_mint=t.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;;letto_iovec_shared?pos?lent=letpos,len=Ordered_collection_common.get_pos_len_exn()?pos?len~total_length:(lengtht)inUnix.IOVec.of_bigstringt.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_fieldsletset_bounds_and_buffer~src~dst=set_bounds_and_buffer~src~dstletset_bounds_and_buffer_sub~pos~len~src~dst=(set_bounds_and_buffer_sub[@inlined])~pos~len~src~dstendtypeok_or_eof=Ok|Eof[@@derivingcompare,sexp_of]moduleFile_descr=Iobuf_intf.Unix.File_descrletinputtch=matchBigstring.inputcht.buf~pos:t.lo~len:(lengtht)with|n->unsafe_advancetn;Ok|exceptionBigstring.IOError(n,End_of_file)->unsafe_advancetn;Eof;;letreadtfd=matchBigstring.readfdt.buf~pos:t.lo~len:(lengtht)with|n->unsafe_advancetn;Ok|exceptionBigstring.IOError(n,End_of_file)->unsafe_advancetn;Eof;;letread_assume_fd_is_nonblockingtfd=letnread=Bigstring.read_assume_fd_is_nonblockingfdt.buf~pos:t.lo~len:(lengtht)inifSyscall_result.Int.is_oknreadthenunsafe_advancet(Syscall_result.Int.ok_exnnread);Syscall_result.ignore_ok_valuenread;;letpread_assume_fd_is_nonblockingtfd~offset=letnread=Bigstring.pread_assume_fd_is_nonblockingfd~offsett.buf~pos:t.lo~len:(lengtht)inunsafe_advancetnread;;letrecvfrom_assume_fd_is_nonblockingtfd=letnread,sockaddr=Bigstring.recvfrom_assume_fd_is_nonblockingfdt.buf~pos:t.lo~len:(lengtht)inunsafe_advancetnread;sockaddr;;[%%ifdefJSC_RECVMMSG](* Allocate and pre-populate the [struct mmsghdr]s and associated [struct iovec]s. Reusing
this context reduces the cost of calls to [recvmmsg] considerably if the iobuf array is
large. *)moduleRecvmmsg_context=structtypectxexternalunsafe_ctx:([>write],seek)tarray->ctx="iobuf_recvmmsg_ctx"letctxts=ifArray.for_allts~f:(funt->lengtht=capacityt)thenunsafe_ctxtselsefailwiths"Recvmmsg_context.create: all buffers must be reset"ts[%sexp_of:(_,_)tarray];;(* we retain a reference to the underlying bigstrings, in the event that callers
mistakenly use set_bounds_and_buffer. Since we've cached the underlying memory
referenced by the bigstring, we want to prevent it from being garbage collected and
released. *)typenonrect={iobufs:(read_write,seek)tarray;bstrs:Bigstring.tarray;ctx:ctx;}letcreateiobufs={iobufs;bstrs=Array.mapiobufs~f:(funiobuf->iobuf.buf);ctx=ctxiobufs;}endexternalunsafe_recvmmsg_assume_fd_is_nonblocking:File_descr.t->(read_write,seek)tarray->Recvmmsg_context.ctx->Unix.Syscall_result.Int.t="iobuf_recvmmsg_assume_fd_is_nonblocking_stub"[@@noalloc]letrecvmmsg_assume_fd_is_nonblockingfd{Recvmmsg_context.iobufs;ctx;_}=unsafe_recvmmsg_assume_fd_is_nonblockingfdiobufsctx;;letrecvmmsg_assume_fd_is_nonblocking=(* We link with [--wrap recvmmsg]. If we have compiled on a machine with recvmmsg
(e.g., CentOS 6) but then run on a machine without (e.g., CentOS 5), our wrapped
[recvmmsg] always returns -1 and sets errno to ENOSYS. *)matchUnix.Syscall_result.Int.to_result(letfd=File_descr.of_int(-1)inrecvmmsg_assume_fd_is_nonblockingfd(Recvmmsg_context.create[||]))with|ErrorENOSYS->Or_error.unimplemented"Iobuf.recvmmsg_assume_fd_is_nonblocking"|_->Okrecvmmsg_assume_fd_is_nonblocking;;[%%else](* not JSC_RECVMMSG *)moduleRecvmmsg_context=structtypet=unitletcreate=ignoreendletrecvmmsg_assume_fd_is_nonblocking=Or_error.unimplemented"Iobuf.recvmmsg_assume_fd_is_nonblocking";;[%%endif](* JSC_RECVMMSG *)letunsafe_senttresult=ifSyscall_result.Int.is_okresultthen(unsafe_advancet(Syscall_result.Int.ok_exnresult);Syscall_result.unit)elseSyscall_result.Int.reinterpret_error_exnresult(* Don't use [Or_error.map]. The natural usage results in a partially applied function,
which is slower to call. *)letsend_nonblocking_no_sigpipe()=matchBigstring.send_nonblocking_no_sigpipewith|Error_ase->e|Oksend->Ok(funtfd->unsafe_sentt(sendfdt.buf~pos:t.lo~len:(lengtht)));;letsendto_nonblocking_no_sigpipe()=matchBigstring.sendto_nonblocking_no_sigpipewith|Error_ase->e|Oksendto->Ok(funtfdaddr->unsafe_sentt(sendtofdt.buf~pos:t.lo~len:(lengtht)addr));;letoutputtch=letnwritten=Bigstring.outputcht.buf~pos:t.lo~len:(lengtht)inunsafe_advancetnwritten;;letwritetfd=letnwritten=Bigstring.writefdt.buf~pos:t.lo~len:(lengtht)inunsafe_advancetnwritten;;letwrite_assume_fd_is_nonblockingtfd=(* This is safe because of the invariant of [t] that the window is within the buffer
(unless the user has violated the invariant with an unsafe operation). *)letnwritten=Bigstring.unsafe_write_assume_fd_is_nonblockingfdt.buf~pos:t.lo~len:(lengtht)inunsafe_advancetnwritten;;letpwrite_assume_fd_is_nonblockingtfd~offset=letnwritten=Bigstring.pwrite_assume_fd_is_nonblockingfd~offsett.buf~pos:t.lo~len:(lengtht)inunsafe_advancetnwritten;;moduleUnsafe=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:(matchlenwithNone->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lentsrc=stringtsrc~str_pos~len:(matchlenwithNone->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lentsrc=bigstringtsrc~str_pos~len:(matchlenwithNone->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_prot=Fill.bin_protopenBigstringletlen=1let[@inlinealways]chartc=bigstring_unsafe_sett.bufc~pos:(upostlen);uadvtlenletlen=2let[@inlinealways]int16_be_truncti=unsafe_set_int16_bet.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]int16_le_truncti=unsafe_set_int16_let.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]uint16_be_truncti=unsafe_set_uint16_bet.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]uint16_le_truncti=unsafe_set_uint16_let.bufi~pos:(upostlen);uadvtlenletlen=4let[@inlinealways]int32_be_truncti=unsafe_set_int32_bet.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]int32_le_truncti=unsafe_set_int32_let.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]uint32_be_truncti=unsafe_set_uint32_bet.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]uint32_le_truncti=unsafe_set_uint32_let.bufi~pos:(upostlen);uadvtlenletlen=8let[@inlinealways]int64_beti=unsafe_set_int64_bet.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]int64_leti=unsafe_set_int64_let.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]uint64_be_truncti=unsafe_set_uint64_bet.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]uint64_le_truncti=unsafe_set_uint64_let.bufi~pos:(upostlen);uadvtlenlet[@inlinealways]int64_t_beti=unsafe_set_int64_t_bet.bufi~pos:(upostlen);uadvtlenlet[@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=structtypesrc=Peek.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:(matchlenwithNone->lengtht-pos|Somelen->len);;letstringo?(str_pos=0)?lent~pos=stringt~pos~str_pos~len:(matchlenwithNone->lengtht-pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~pos=bigstringt~pos~str_pos~len:(matchlenwithNone->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:(matchlenwithNone->Bytes.lengthsrc-str_pos|Somelen->len);;letstringo?(str_pos=0)?lent~possrc=stringt~str_pos~possrc~len:(matchlenwithNone->String.lengthsrc-str_pos|Somelen->len);;letbigstringo?(str_pos=0)?lent~possrc=bigstringt~str_pos~possrc~len:(matchlenwithNone->Bigstring.lengthsrc-str_pos|Somelen->len);;letbin_prot=Poke.bin_protopenBigstringlet[@inlinealways]chart~posc=bigstring_unsafe_sett.buf~pos:(upost~pos)clet[@inlinealways]uint8_trunct~posi=unsafe_set_uint8t.buf~pos:(upost~pos)ilet[@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)ilet[@inlinealways]int16_le_trunct~posi=unsafe_set_int16_let.buf~pos:(upost~pos)ilet[@inlinealways]uint16_be_trunct~posi=unsafe_set_uint16_bet.buf~pos:(upost~pos)ilet[@inlinealways]uint16_le_trunct~posi=unsafe_set_uint16_let.buf~pos:(upost~pos)ilet[@inlinealways]int32_be_trunct~posi=unsafe_set_int32_bet.buf~pos:(upost~pos)ilet[@inlinealways]int32_le_trunct~posi=unsafe_set_int32_let.buf~pos:(upost~pos)ilet[@inlinealways]uint32_be_trunct~posi=unsafe_set_uint32_bet.buf~pos:(upost~pos)ilet[@inlinealways]uint32_le_trunct~posi=unsafe_set_uint32_let.buf~pos:(upost~pos)ilet[@inlinealways]int64_bet~posi=unsafe_set_int64_bet.buf~pos:(upost~pos)ilet[@inlinealways]int64_let~posi=unsafe_set_int64_let.buf~pos:(upost~pos)ilet[@inlinealways]uint64_be_trunct~posi=unsafe_set_uint64_bet.buf~pos:(upost~pos)ilet[@inlinealways]uint64_le_trunct~posi=unsafe_set_uint64_let.buf~pos:(upost~pos)ilet[@inlinealways]int64_t_bet~posi=unsafe_set_int64_t_bet.buf~pos:(upost~pos)ilet[@inlinealways]int64_t_let~posi=unsafe_set_int64_t_let.buf~pos:(upost~pos)iletdecimal=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)tletto_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.concatletto_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_hum