Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file lz.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577[@@@landmark"auto"]typebigstring=(char,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.tletbigstring_empty=Bigarray.Array1.createBigarray.charBigarray.c_layout0letbigstring_lengthx=Bigarray.Array1.dimx[@@inline]letbigstring_createl=Bigarray.Array1.createBigarray.charBigarray.c_layoutlletinvalid_argfmt=Format.kasprintfinvalid_argfmtletinvalid_boundsofflen=invalid_arg"Out of bounds (off: %d, len: %d)"offlenexternalunsafe_get_uint8:bigstring->int->int="%caml_ba_ref_1"externalunsafe_get_char:bigstring->int->char="%caml_ba_ref_1"externalunsafe_set_uint8:bigstring->int->int->unit="%caml_ba_set_1"externalunsafe_get_uint16:bigstring->int->int="%caml_bigstring_get16"externalunsafe_get_uint32:bigstring->int->int32="%caml_bigstring_get32"externalunsafe_set_uint32:bigstring->int->int32->unit="%caml_bigstring_set32"externalbytes_unsafe_get_uint32:bytes->int->int32="%caml_bytes_get32"letbytes_unsafe_get_uint8:bytes->int->int=funbufoff->Char.code(Bytes.getbufoff)letinput_bigstringicbufofflen=lettmp=Bytes.createleninletres=inputictmp0leninletlen0=resland3inletlen1=resasr2infori=0tolen1-1doleti=i*4inletv=bytes_unsafe_get_uint32tmpiinunsafe_set_uint32buf(off+i)vdone;fori=0tolen0-1doleti=(len1*4)+iinletv=bytes_unsafe_get_uint8tmpiinunsafe_set_uint8buf(off+i)vdone;resexternalstring_unsafe_get_uint32:string->int->int32="%caml_string_get32"letstring_unsafe_get_uint8:string->int->int=funbufoff->Char.codebuf.[off]letbigstring_of_stringv=letlen=String.lengthvinletres=bigstring_createleninletlen0=lenland3inletlen1=lenasr2infori=0tolen1-1doleti=i*4inletv=string_unsafe_get_uint32viinunsafe_set_uint32resivdone;fori=0tolen0-1doleti=(len1*4)+iinletv=string_unsafe_get_uint8viinunsafe_set_uint8resivdone;reslet_length=[|0;1;2;3;4;5;6;7;8;8;9;9;10;10;11;11;12;12;12;12;13;13;13;13;14;14;14;14;15;15;15;15;16;16;16;16;16;16;16;16;17;17;17;17;17;17;17;17;18;18;18;18;18;18;18;18;19;19;19;19;19;19;19;19;20;20;20;20;20;20;20;20;20;20;20;20;20;20;20;20;21;21;21;21;21;21;21;21;21;21;21;21;21;21;21;21;22;22;22;22;22;22;22;22;22;22;22;22;22;22;22;22;23;23;23;23;23;23;23;23;23;23;23;23;23;23;23;23;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;28|]let_distance=[|0;1;2;3;4;4;5;5;6;6;6;6;7;7;7;7;8;8;8;8;8;8;8;8;9;9;9;9;9;9;9;9;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;10;11;11;11;11;11;11;11;11;11;11;11;11;11;11;11;11;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;12;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;13;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;14;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;0;0;16;17;18;18;19;19;20;20;20;20;21;21;21;21;22;22;22;22;22;22;22;22;23;23;23;23;23;23;23;23;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;24;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;25;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;26;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;27;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;28;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29;29|]let_distancecode=ifcode<256then_distance.(code)else_distance.(256+(codelsr7))[@@inline]let_max_match=258let_min_match=3let_min_lookahead=_max_match+_min_match+1let(.!())bufpos=unsafe_get_uint32bufposlet(.![])bufpos=unsafe_get_uint16bufposlet(.!{})bufpos=unsafe_get_uint8bufpostypeconfiguration={max_chain:int;max_lazy:int;good_length:int;nice_length:int}let_4={good_length=4;max_lazy=4;nice_length=16;max_chain=16}let_5={good_length=8;max_lazy=16;nice_length=32;max_chain=32}let_6={good_length=8;max_lazy=16;nice_length=128;max_chain=128}let_7={good_length=8;max_lazy=32;nice_length=128;max_chain=256}let_8={good_length=32;max_lazy=128;nice_length=258;max_chain=1024}let_9={good_length=32;max_lazy=258;nice_length=258;max_chain=4096}let_mem_level=8(* default *)let_hash_bits=_mem_level+7let_hash_size=1lsl_hash_bitslet_hash_mask=_hash_size-1let_hash_shift=(_hash_bits+_min_match-1)/_min_matchlet_too_far=4096letupdate_hashhashchr=(hashlsl_hash_shift)lxorchrland_hash_masktypesrc=[`Channelofin_channel|`Stringofstring|`Manual]typedecode=[`Await|`Flush|`End]typeliterals=De.literalstypedistances=De.distancestypeoptint=Optint.ttypestate={src:src;cfg:configuration;mutablei:bigstring;mutablei_pos:int;mutablei_len:int;l:literals;d:distances;w:bigstring;wbits:int;mutablelookahead:int;mutablestrstart:int;prev:intarray;head:intarray;mutablehash:int;mutablematch_start:int;mutablematch_length:int;mutablematch_available:bool;mutableinsert:int;mutableprev_length:int;mutableprev_match:int;q:De.Queue.t;mutablecrc:optint;mutablek:configuration->state->decode}letmax_dists=(1lsls.wbits)-_min_lookaheadexceptionBreak(* cur is the head of the hash chain for the current string
* and its distance is <= _max_dist
* prev_length >= 1
* len >= _min_lookahead *)letlongest_matchcfgscur_match=letwsize=1lsls.wbitsinletwmask=wsize-1inletstr_end=s.strstart+(_max_match-1)inletlimit=ifs.strstart>max_diststhens.strstart-max_distselse0in(* Stop when !cur becomes <= limit. To somplify the code,
* we prevent matches with the string of window index 0. *)letcur_match=refcur_matchin(* current match *)letchain_length=ref(ifs.prev_length>=cfg.good_lengththencfg.max_chainasr2elsecfg.max_chain)in(* max hash chain length *)letscan=refs.strstartin(* current string *)letscan_start=s.w.![s.strstart]inletscan_end=refs.w.![s.strstart+s.prev_length-1]inletbest_len=refs.prev_lengthin(* best match length so far *)(trywhileletmatch'=ref!cur_matchinifs.w.![!match'+!best_len-1]<>!scan_end||s.w.![!match']<>scan_startthenbegincur_match:=s.prev.(!cur_matchlandwmask);decrchain_length;!cur_match>limit&&!chain_length!=0endelsebeginincrscan;incrmatch';while!scan<str_end&&s.w.!(!scan)=s.w.!(!match')doscan:=!scan+4;match':=!match'+4done;while!scan<str_end&&s.w.![!scan]==s.w.![!match']doscan:=!scan+2;match':=!match'+2done;while!scan<str_end&&s.w.!{!scan}==s.w.!{!match'}doscan:=!scan+1;match':=!match'+1done;ifs.w.!{!scan}==s.w.!{!match'}thenincrscan;letlen=_max_match-1-(str_end-!scan)inscan:=str_end-(_max_match-1);iflen>!best_lenthenbegins.match_start<-!cur_match;best_len:=len;iflen>=cfg.nice_lengththenraiseBreak;scan_end:=s.w.![!scan+!best_len-1]end;cur_match:=s.prev.(!cur_matchlandwmask);decrchain_length;!cur_match>limit&&!chain_length!=0enddo()donewithBreak->());if!best_len<=s.lookaheadthen!best_lenelses.lookaheadleteois=s.i<-bigstring_empty;s.i_pos<-0;s.i_len<-min_intletsrcdsjl=ifj<0||l<0||j+l>bigstring_lengthstheninvalid_boundsjl;ifl==0theneoidelse(d.i<-s;d.i_pos<-j;d.i_len<-j+l-1)leti_rems=s.i_len-s.i_pos+1[@@inline]letsrc_rems=i_remsletio_buffer_size=16384letrefillks=matchs.srcwith|`String_->eois;ks.cfgs|`Channelic->letres=input_bigstringics.i0(bigstring_lengths.i)insrcss.i0res;ks.cfgs|`Manual->s.k<-k;`Awaitletmemcpysrc~src_offdst~dst_off~len=letlen0=lenland3inletlen1=lenasr2infori=0tolen1-1doleti=i*4inletv=unsafe_get_uint32src(src_off+i)inunsafe_set_uint32dst(dst_off+i)vdone;fori=0tolen0-1doleti=(len1*4)+iinletv=unsafe_get_uint8src(src_off+i)inunsafe_set_uint8dst(dst_off+i)vdoneletupdate_crcslen=s.crc<-Checkseum.Adler32.digest_bigstrings.is.i_poslens.crcletinsert_stringsstr=letwsize=1lsls.wbitsinletwmask=wsize-1ins.hash<-update_hashs.hashs.w.!{str+(_min_match-1)};letres=s.head.(s.hash)ins.prev.(strlandwmask)<-res;s.head.(s.hash)<-str;resletsucc_lengthliteralslength=assert(length>=3&&length<=255+3);literals.(256+1+_length.(length-3))<-literals.(256+1+_length.(length-3))+1letsucc_distancedistancesdistance=assert(distance>=1&&distance<=32767+1);distances.(_distance(preddistance))<-distances.(_distance(preddistance))+1letemit_matchs~off~len=De.Queue.push_exns.q(De.Queue.cmd(`Copy(off,len)));succ_length(s.l:>intarray)len;succ_distance(s.d:>intarray)off;ifDe.Queue.availables.q=1then(De.Queue.push_exns.qDe.Queue.eob;true)elsefalseletsucc_literalliteralschr=literals.(Char.codechr)<-literals.(Char.codechr)+1letemit_literalschr=De.Queue.push_exns.q(De.Queue.cmd(`Literalchr));succ_literal(s.l:>intarray)chr;ifDe.Queue.availables.q=1then(De.Queue.push_exns.qDe.Queue.eob;true)elsefalse(* XXX(dinosaure): it's possible that it remains one literal. *)lettrailings=ifs.match_availablethen(let_=emit_literals(unsafe_get_chars.w(s.strstart-1))ins.insert<-(ifs.strstart<_min_match-1thens.strstartelse_min_match-1);`End)else`Endletslide_hashs=letwsize=1lsls.wbitsinletm=ref0inletn=ref_hash_sizeinletp=ref!ninwhiledecrp;m:=s.head.(!p);s.head.(!p)<-(if!m>=wsizethen!m-wsizeelse0);decrn;!n!=0do()done;n:=wsize;p:=!n;whiledecrp;m:=s.prev.(!p);s.prev.(!p)<-(if!m>=wsizethen!m-wsizeelse0);decrn;!n!=0do()doneletrecfill_window(cfg:configuration)s=letwsize=1lsls.wbitsinletwmask=wsize-1inletmore=(wsize*2)-s.lookahead-s.strstartin(* max *)letmore=ifs.strstart>=wsize+max_diststhenbeginmemcpys.w~src_off:wsizes.w~dst_off:0~len:(wsize-more);s.match_start<-s.match_start-wsize;s.strstart<-s.strstart-wsize;slide_hashs;more+wsizeendelsemoreinletrem=i_remsinifrem<=0(* if (s->strm->avail_in == 0) break; *)thenifrem<0thenifs.lookahead>0thendeflate_slowcfgselsetrailingselserefillfill_windowselsetryletlen=minmorereminmemcpys.i~src_off:s.i_poss.w~dst_off:(s.strstart+s.lookahead)~len;(*d*)update_crcslen;s.lookahead<-s.lookahead+len;(*d*)s.i_pos<-s.i_pos+len;ifs.lookahead+s.insert>=_min_matchthenbeginletstr=ref(s.strstart-s.insert)inletinsert=refs.insertins.hash<-s.w.!{!str};s.hash<-update_hashs.hashs.w.!{!str+1};whiles.lookahead+!insert>=_min_match&&!insert!=0dos.hash<-update_hashs.hashs.w.!{!str+_min_match-1};s.prev.(!strlandwmask)<-s.head.(s.hash);s.head.(s.hash)<-!str;incrstr;decrinsert;ifs.lookahead+!insert<_min_matchthen(s.insert<-!insert;raiseBreak)done;s.insert<-!insertend;ifs.lookahead<_min_lookahead&&i_rems>=0thenrefillfill_windowselsedeflate_slowcfgswithBreak->deflate_slowcfgsandenoughcfgs=ifs.lookahead<_min_lookaheadthenfill_windowcfgselsedeflate_slowcfgsanddeflate_slowcfgs=lethash_head=ref0inifs.lookahead>=_min_matchthenhash_head:=insert_stringss.strstart;s.prev_length<-s.match_length;s.prev_match<-s.match_start;s.match_length<-_min_match-1;(if!hash_head!=0&&s.prev_length<cfg.max_lazy&&s.strstart-!hash_head<=max_diststhenletmatch_length=longest_matchcfgs!hash_headinifmatch_length<=5&&match_length==_min_match&&s.strstart-s.match_start>_too_farthens.match_length<-_min_match-1elses.match_length<-match_length);ifs.prev_length>=_min_match&&s.match_length<=s.prev_lengththenbeginletmax_insert=s.strstart+s.lookahead-_min_matchinletflush=emit_matchs~off:(s.strstart-1-s.prev_match)~len:s.prev_lengthins.lookahead<-s.lookahead-(s.prev_length-1);s.prev_length<-s.prev_length-2;whiles.strstart<-s.strstart+1;ifs.strstart<=max_insertthenhash_head:=insert_stringss.strstart;s.prev_length<-s.prev_length-1;s.prev_length<>0do()done;s.match_available<-false;s.match_length<-_min_match-1;s.strstart<-s.strstart+1;ifflushthen(s.k<-enough;`Flush)elseenoughcfgsendelseifs.match_availablethenbeginmatchemit_literals(unsafe_get_chars.w(s.strstart-1))with|true->s.strstart<-s.strstart+1;s.lookahead<-s.lookahead-1;s.k<-enough;`Flush|false->s.strstart<-s.strstart+1;s.lookahead<-s.lookahead-1;enoughcfgsendelsebegins.match_available<-true;s.strstart<-s.strstart+1;s.lookahead<-s.lookahead-1;enoughcfgsendlet_literals=256let_length_codes=29let_l_codes=_literals+1+_length_codeslet_d_codes=30letchecksum{crc;_}=crcletdistances{d;_}=dletliterals{l;_}=lletctzx=letn=ref0andx=refxandy=ref0inifSys.word_size=64then(n:=63;y:=!xlsl32;if!y!=0then(n:=!n-32;x:=!y))elsen:=31;y:=!xlsl16;if!y!=0then(n:=!n-16;x:=!y);y:=!xlsl8;if!y!=0then(n:=!n-8;x:=!y);y:=!xlsl4;if!y!=0then(n:=!n-4;x:=!y);y:=!xlsl2;if!y!=0then(n:=!n-2;x:=!y);y:=!xlsl1;if!y!=0thenn:=!n-1;!nletstate?(level=4)~q~wsrc=letwbits=ctz(bigstring_lengthw/2)-1inletwsize=1lslwbitsinletcfg=matchlevelwith|0|1|2|3|4->_4|5->_5|6->_6|7->_7|8->_8|9->_9|_->invalid_arg"Invalid compression level: %d"levelinleti,i_pos,i_len=matchsrcwith|`Manual->bigstring_empty,1,0|`Stringx->bigstring_of_stringx,0,String.lengthx-1|`Channel_->bigstring_createio_buffer_size,1,0in{src;i;i_pos;i_len;cfg;l=De.make_literals();d=De.make_distances();w;wbits;lookahead=0;strstart=0;prev=Array.makewsize0;head=Array.make_hash_size0;hash=0;match_start=0;match_length=_min_match-1;match_available=false;insert=0;prev_length=_min_match-1;prev_match=0;q;crc=Checkseum.Adler32.default;k=enough}letcompresss=s.ks.cfgstypewindow=bigstringletmake_window~bits=bigstring_create((1lslbits)*2)