Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file read.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675(* Read_ml: reading values from the binary protocol using (mostly) OCaml. *)(* Note: the code is this file is carefully written to avoid unnecessary allocations. When
touching this code, be sure to run the benchmarks to check for regressions. *)#include"int_codes.mlh"openBigarrayopenCommontype'areader=buf->pos_ref:pos_ref->'atype('a,'b)reader1='areader->'breadertype('a,'b,'c)reader2='areader->('b,'c)reader1type('a,'b,'c,'d)reader3='areader->('b,'c,'d)reader2externalunsafe_get:buf->int->char="%caml_ba_unsafe_ref_1";;externalunsafe_get8:buf->int->int="%caml_ba_unsafe_ref_1";;letunsafe_get8_signedbufpos=letc=unsafe_get8bufposinifc>=128thenc-256elsec;;letarch_sixtyfour=Sys.word_size=64letarch_big_endian=Sys.big_endianletmax_int_int32=ifarch_sixtyfourthenInt32.max_intelseInt32.of_intmax_intletmin_int_int32=ifarch_sixtyfourthenInt32.max_intelseInt32.of_intmin_intletmax_int_int64=Int64.of_intmax_intletmin_int_int64=Int64.of_intmin_intletsafe_int_of_int32posx=ifarch_sixtyfourthenInt32.to_intxelseifx>=min_int_int32&&x<=max_int_int32thenInt32.to_intxelseraise_read_errorReadError.Int_overflowpos;;letsafe_int_of_int64posx=ifx>=min_int_int64&&x<=max_int_int64thenInt64.to_intxelseraise_read_errorReadError.Int_overflowpos;;letsafe_nativeint_of_int64=ifarch_sixtyfourthenfun_posx->Int64.to_nativeintxelsefunposx->ifx>=Int64.of_nativeintNativeint.min_int&&x<=Int64.of_nativeintNativeint.max_intthenInt64.to_nativeintxelseraise_read_errorReadError.Int_overflowpos;;externalunsafe_get16:buf->int->int="%caml_bigstring_get16u";;externalunsafe_get32:buf->int->int32="%caml_bigstring_get32u";;externalunsafe_get64:buf->int->int64="%caml_bigstring_get64u";;externalbswap16:int->int="%bswap16";;externalbswap32:int32->int32="%bswap_int32";;externalbswap64:int64->int64="%bswap_int64";;letunsafe_get16be_unsigned=ifarch_big_endianthenunsafe_get16elsefunbufpos->unsafe_get16bufpos|>bswap16letunsafe_get32be=ifarch_big_endianthenunsafe_get32elsefunbufpos->unsafe_get32bufpos|>bswap32letunsafe_get64be=ifarch_big_endianthenunsafe_get64elsefunbufpos->unsafe_get64bufpos|>bswap64letunsafe_get16le_unsigned=ifarch_big_endianthenfunbufpos->unsafe_get16bufpos|>bswap16elseunsafe_get16letunsafe_get32le=ifarch_big_endianthenfunbufpos->unsafe_get32bufpos|>bswap32elseunsafe_get32letunsafe_get64le=ifarch_big_endianthenfunbufpos->unsafe_get64bufpos|>bswap64elseunsafe_get64letunsafe_get16le_signedbufpos=letx=unsafe_get16le_unsignedbufposinifx>32767thenx-65536elsex;;letbin_read_unitbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;ifunsafe_getbufpos='\000'thenpos_ref:=pos+1elseraise_read_errorReadError.Unit_codeposletbin_read_boolbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\000'->pos_ref:=pos+1;false|'\001'->pos_ref:=pos+1;true|_->raise_read_errorReadError.Bool_codeposletsafe_bin_read_neg_int8buf~pos_ref~pos=letnext=pos+1incheck_nextbufnext;letn=unsafe_get8_signedbufposinifn>=0thenraise_read_errorReadError.Neg_int8!pos_ref;pos_ref:=next;nletsafe_bin_read_int16buf~pos_ref~pos=letnext=pos+2incheck_nextbufnext;pos_ref:=next;(* Can be above next line (no errors possible with 16bit).
This should improve the generated code. *)unsafe_get16le_signedbufposletsafe_bin_read_int32buf~pos_ref~pos=letnext=pos+4incheck_nextbufnext;pos_ref:=next;(* No error possible either. *)unsafe_get32lebufposletsafe_bin_read_int64buf~pos_ref~pos=letnext=pos+8incheck_nextbufnext;pos_ref:=next;(* No error possible either. *)unsafe_get64lebufposletsafe_bin_read_int32_as_intbuf~pos_ref~pos=letnext=pos+4incheck_nextbufnext;letn=unsafe_get32lebufposinletn=safe_int_of_int32!pos_refninpos_ref:=next;nletsafe_bin_read_int64_as_intbuf~pos_ref~pos=letnext=pos+8incheck_nextbufnext;letn=unsafe_get64lebufposinletn=safe_int_of_int64!pos_refninpos_ref:=next;nletsafe_bin_read_int32_as_int64buf~pos_ref~pos=letnext=pos+4incheck_nextbufnext;pos_ref:=next;letn=unsafe_get32lebufposinInt64.of_int32nletsafe_bin_read_int32_as_nativeintbuf~pos_ref~pos=letnext=pos+4incheck_nextbufnext;pos_ref:=next;letn=unsafe_get32lebufposinNativeint.of_int32nletsafe_bin_read_int64_as_nativeintbuf~pos_ref~pos=letnext=pos+8incheck_nextbufnext;letn=unsafe_get64lebufposinletn=safe_nativeint_of_int64posninpos_ref:=next;nletsafe_bin_read_nat0_16buf~pos_ref~pos=letnext=pos+2incheck_nextbufnext;pos_ref:=next;Nat0.unsafe_of_int(unsafe_get16le_unsignedbufpos)letsafe_bin_read_nat0_32=ifarch_sixtyfourthenletmask_32bit=Int64.to_int0xffff_ffffLinfunbuf~pos_ref~pos->letnext=pos+4incheck_nextbufnext;pos_ref:=next;letn=Int32.to_int(unsafe_get32lebufpos)inifn>=0thenNat0.unsafe_of_intnelse(* Erase the upper bits that were set to 1 during the int32 -> int conversion. *)Nat0.unsafe_of_int(nlandmask_32bit)elsefunbuf~pos_ref~pos->letnext=pos+4incheck_nextbufnext;letn=unsafe_get32lebufposinifn>=0l&&n<=max_int_int32thenbeginletn=Nat0.unsafe_of_int(Int32.to_intn)inpos_ref:=next;nendelseraise_read_errorReadError.Nat0_overflow!pos_refletsafe_bin_read_nat0_64buf~pos_ref~pos=letnext=pos+8incheck_nextbufnext;letn=unsafe_get64lebufposinifn>=0L&&n<=max_int_int64thenbeginletn=Nat0.unsafe_of_int(Int64.to_intn)inpos_ref:=next;nendelseraise_read_errorReadError.Nat0_overflow!pos_refletbin_read_nat0buf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\x00'..'\x7f'asch->pos_ref:=pos+1;Nat0.unsafe_of_int(Char.codech)|CODE_INT16->safe_bin_read_nat0_16buf~pos_ref~pos:(pos+1)|CODE_INT32->safe_bin_read_nat0_32buf~pos_ref~pos:(pos+1)|CODE_INT64->ifarch_sixtyfourthensafe_bin_read_nat0_64buf~pos_ref~pos:(pos+1)elseraise_read_errorReadError.Nat0_overflowpos|_->raise_read_errorReadError.Nat0_codepos;;letbin_read_bytesbuf~pos_ref=letstart_pos=!pos_refinletlen=(bin_read_nat0buf~pos_ref:>int)iniflen>Sys.max_string_lengththenraise_read_errorReadError.String_too_longstart_pos;letpos=!pos_refinletnext=pos+lenincheck_nextbufnext;pos_ref:=next;letstr=Bytes.createleninunsafe_blit_buf_bytes~src_pos:posbuf~dst_pos:0str~len;strletbin_read_stringbuf~pos_ref=letstr=bin_read_bytesbuf~pos_refinBytes.unsafe_to_stringstrletbin_read_charbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;pos_ref:=pos+1;unsafe_getbufposletbin_read_intbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\x00'..'\x7f'asch->pos_ref:=pos+1;Char.codech|CODE_NEG_INT8->safe_bin_read_neg_int8buf~pos_ref~pos:(pos+1)|CODE_INT16->safe_bin_read_int16buf~pos_ref~pos:(pos+1)|CODE_INT32->safe_bin_read_int32_as_intbuf~pos_ref~pos:(pos+1)|CODE_INT64->ifarch_sixtyfourthensafe_bin_read_int64_as_intbuf~pos_ref~pos:(pos+1)elseraise_read_errorReadError.Int_overflowpos|_->raise_read_errorReadError.Int_codepos;;letbin_read_floatbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;letnext=pos+8incheck_nextbufnext;pos_ref:=next;(* No error possible either. *)Int64.float_of_bits(unsafe_get64lebufpos);;letbin_read_int32buf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\x00'..'\x7f'asch->pos_ref:=pos+1;Int32.of_int(Char.codech)|CODE_NEG_INT8->Int32.of_int(safe_bin_read_neg_int8buf~pos_ref~pos:(pos+1))|CODE_INT16->Int32.of_int(safe_bin_read_int16buf~pos_ref~pos:(pos+1))|CODE_INT32->safe_bin_read_int32buf~pos_ref~pos:(pos+1)|_->raise_read_errorReadError.Int32_codepos;;letbin_read_int64buf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\x00'..'\x7f'asch->pos_ref:=pos+1;Int64.of_int(Char.codech)|CODE_NEG_INT8->Int64.of_int(safe_bin_read_neg_int8buf~pos_ref~pos:(pos+1))|CODE_INT16->Int64.of_int(safe_bin_read_int16buf~pos_ref~pos:(pos+1))|CODE_INT32->safe_bin_read_int32_as_int64buf~pos_ref~pos:(pos+1)|CODE_INT64->safe_bin_read_int64buf~pos_ref~pos:(pos+1)|_->raise_read_errorReadError.Int64_codepos;;letbin_read_nativeintbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\x00'..'\x7f'asch->pos_ref:=pos+1;Nativeint.of_int(Char.codech)|CODE_NEG_INT8->Nativeint.of_int(safe_bin_read_neg_int8buf~pos_ref~pos:(pos+1))|CODE_INT16->Nativeint.of_int(safe_bin_read_int16buf~pos_ref~pos:(pos+1))|CODE_INT32->safe_bin_read_int32_as_nativeintbuf~pos_ref~pos:(pos+1)|CODE_INT64whenarch_sixtyfour->safe_bin_read_int64_as_nativeintbuf~pos_ref~pos:(pos+1)|_->raise_read_errorReadError.Nativeint_codepos;;letbin_read_refbin_read_elbuf~pos_ref=letel=bin_read_elbuf~pos_refinrefelletbin_read_lazybin_read_elbuf~pos_ref=letel=bin_read_elbuf~pos_refinLazy.from_valelletbin_read_optionbin_read_elbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;matchunsafe_getbufposwith|'\000'->pos_ref:=pos+1;None|'\001'->pos_ref:=pos+1;letel=bin_read_elbuf~pos_refinSomeel|_->raise_read_errorReadError.Option_codeposletbin_read_pairbin_read_abin_read_bbuf~pos_ref=leta=bin_read_abuf~pos_refinletb=bin_read_bbuf~pos_refina,bletbin_read_triplebin_read_abin_read_bbin_read_cbuf~pos_ref=leta=bin_read_abuf~pos_refinletb=bin_read_bbuf~pos_refinletc=bin_read_cbuf~pos_refina,b,cletbin_read_n_rev_listbin_read_elbuf~pos_reflen=letrecloopnacc=ifn=0thenaccelseloop(n-1)(bin_read_elbuf~pos_ref::acc)inlooplen[]letbin_read_listbin_read_elbuf~pos_ref=letlen=(bin_read_nat0buf~pos_ref:>int)inletrev_lst=bin_read_n_rev_listbin_read_elbuf~pos_refleninList.revrev_lstletdummy_float_buf=create_buf8let()=ignore(Write.bin_write_floatdummy_float_buf~pos:03.1)letmax_float_array_length=ifarch_sixtyfourthenSys.max_array_lengthelseSys.max_array_length/2;;letbin_read_float_arraybuf~pos_ref=letpos=!pos_refinletlen=(bin_read_nat0buf~pos_ref:>int)iniflen>max_float_array_lengththenraise_read_errorReadError.Array_too_longpos;letsize=len*8inletpos=!pos_refinletnext=pos+sizeincheck_nextbufnext;letarr=Array.create_floatleninunsafe_blit_buf_float_arraybufarr~src_pos:pos~dst_pos:0~len;pos_ref:=next;arr;;letbin_read_array(typea)bin_read_elbuf~pos_ref=if(Obj.magic(bin_read_el:areader):floatreader)==bin_read_floatthen(Obj.magic(bin_read_float_arraybuf~pos_ref:floatarray):aarray)elseletstart_pos=!pos_refinletlen=(bin_read_nat0buf~pos_ref:>int)iniflen=0then[||]elsebeginifarch_sixtyfourthenbeginiflen>Sys.max_array_lengththenraise_read_errorReadError.Array_too_longstart_posendelsebeginiflen>Sys.max_array_length/2thenbeginletmaybe_float=tryletel=bin_read_eldummy_float_buf~pos_ref:(ref0)inSomeelwith_->Noneinmatchmaybe_floatwith|None->iflen>Sys.max_array_lengththenraise_read_errorReadError.Array_too_longstart_pos|Someel->ifObj.tag(Obj.reprel)=Obj.double_tag||len>Sys.max_array_lengththenraise_read_errorReadError.Array_too_longstart_posend;end;letfirst=bin_read_elbuf~pos_refinletres=Array.makelenfirstinfori=1tolen-1doletel=bin_read_elbuf~pos_refinArray.unsafe_setresieldone;resendletbin_read_hashtblbin_read_keybin_read_valbuf~pos_ref=letlen=(bin_read_nat0buf~pos_ref:>int)inlethtbl=Hashtbl.createleninletread_kv_pair=bin_read_pairbin_read_keybin_read_valinletels=bin_read_n_rev_listread_kv_pairbuf~pos_reflenincopy_htbl_listhtblels;;externalbuf_of_vec32:vec32->buf="%identity"externalbuf_of_vec64:vec64->buf="%identity"externalbuf_of_mat32:mat32->buf="%identity"externalbuf_of_mat64:mat64->buf="%identity"letbin_read_float32_vecbuf~pos_ref=letlen=(bin_read_nat0buf~pos_ref:>int)inletsize=len*4inletpos=!pos_refinletnext=pos+sizeincheck_nextbufnext;letvec=Array1.createfloat32fortran_layoutleninunsafe_blit_buf~src:buf~src_pos:pos~dst:(buf_of_vec32vec)~dst_pos:0~len:size;pos_ref:=next;vec;;letbin_read_float64_vecbuf~pos_ref=letlen=(bin_read_nat0buf~pos_ref:>int)inletsize=len*8inletpos=!pos_refinletnext=pos+sizeincheck_nextbufnext;letvec=Array1.createfloat64fortran_layoutleninunsafe_blit_buf~src:buf~src_pos:pos~dst:(buf_of_vec64vec)~dst_pos:0~len:size;pos_ref:=next;vec;;letbin_read_vec=bin_read_float64_vecletbin_read_float32_matbuf~pos_ref=letlen1=(bin_read_nat0buf~pos_ref:>int)inletlen2=(bin_read_nat0buf~pos_ref:>int)inletsize=len1*len2*4inletpos=!pos_refinletnext=pos+sizeincheck_nextbufnext;letmat=Array2.createfloat32fortran_layoutlen1len2inunsafe_blit_buf~src:buf~src_pos:pos~dst:(buf_of_mat32mat)~dst_pos:0~len:size;pos_ref:=next;mat;;letbin_read_float64_matbuf~pos_ref=letlen1=(bin_read_nat0buf~pos_ref:>int)inletlen2=(bin_read_nat0buf~pos_ref:>int)inletsize=len1*len2*8inletpos=!pos_refinletnext=pos+sizeincheck_nextbufnext;letmat=Array2.createfloat64fortran_layoutlen1len2inunsafe_blit_buf~src:buf~src_pos:pos~dst:(buf_of_mat64mat)~dst_pos:0~len:size;pos_ref:=next;mat;;letbin_read_mat=bin_read_float64_matletbin_read_bigstringbuf~pos_ref=letlen=(bin_read_nat0buf~pos_ref:>int)inletpos=!pos_refinletnext=pos+lenincheck_nextbufnext;letstr=create_bufleninunsafe_blit_buf~src:buf~src_pos:pos~dst:str~dst_pos:0~len;pos_ref:=next;str;;letbin_read_variant_intbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+4incheck_nextbufnext;letn=unsafe_get32lebufposin(* [n] must contain an integer already encoded, i.e. [n = 2 * k + 1]. *)ifInt32.logandn1l=0lthenraise(Read_error(ReadError.Variant_tag,pos))elsebegin(* We shift it by one bit to the right se we get back [2 * k + 1] in the end. *)pos_ref:=next;Int32.to_int(Int32.shift_rightn1)end;;letbin_read_int_8bitbuf~pos_ref=letpos=safe_get_posbufpos_refinassert_pospos;pos_ref:=pos+1;unsafe_get8bufpos;;letbin_read_int_16bitbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+2incheck_nextbufnext;pos_ref:=next;unsafe_get16le_unsignedbufposletbin_read_int_32bitbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+4incheck_nextbufnext;pos_ref:=next;letn=unsafe_get32lebufposinsafe_int_of_int32posnletbin_read_int_64bitbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+8incheck_nextbufnext;pos_ref:=next;letn=unsafe_get64lebufposinsafe_int_of_int64posnletbin_read_int64_bitsbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+8incheck_nextbufnext;pos_ref:=next;unsafe_get64lebufposletbin_read_network16_intbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+2incheck_nextbufnext;pos_ref:=next;unsafe_get16be_unsignedbufposletbin_read_network32_intbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+4incheck_nextbufnext;pos_ref:=next;letn=unsafe_get32bebufposinsafe_int_of_int32posnletbin_read_network32_int32buf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+4incheck_nextbufnext;pos_ref:=next;unsafe_get32bebufposletbin_read_network64_intbuf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+8incheck_nextbufnext;pos_ref:=next;letn=unsafe_get64bebufposinsafe_int_of_int64posnletbin_read_network64_int64buf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+8incheck_nextbufnext;pos_ref:=next;unsafe_get64bebufposexternalunsafe_bytes_set32:bytes->int->int32->unit="%caml_string_set32u";;externalunsafe_bytes_set64:bytes->int->int64->unit="%caml_string_set64u";;letbin_read_md5buf~pos_ref=letpos=!pos_refinassert_pospos;letnext=pos+16incheck_nextbufnext;pos_ref:=next;letres=Bytes.create16inifarch_sixtyfourthenbeginleta=unsafe_get64bufposinletb=unsafe_get64buf(pos+8)inunsafe_bytes_set64res0a;unsafe_bytes_set64res8b;endelsebeginleta=unsafe_get32bufposinletb=unsafe_get32buf(pos+4)inletc=unsafe_get32buf(pos+8)inletd=unsafe_get32buf(pos+12)inunsafe_bytes_set32res0a;unsafe_bytes_set32res4b;unsafe_bytes_set32res8c;unsafe_bytes_set32res12d;end;Md5_lib.unsafe_of_binary(Bytes.unsafe_to_stringres)