package Ġorg . open rs 2 . cache Ċ Ċ import Ġio . netty . buffer . Byte Buf Ċ import Ġio . netty . buffer . Byte Buf InputStream Ċ import Ġio . netty . buffer . Byte Buf OutputStream Ċ import Ġorg . open rs 2 . buffer . use Ċ import Ġorg . open rs 2 . crypto . X tea Key Ċ import Ġorg . open rs 2 . crypto . x tea Decrypt Ċ import Ġorg . open rs 2 . crypto . x tea Encrypt Ċ import Ġjava . io . IOException Ċ Ċ public Ġobject ĠJs 5 Compression Ġ{ ĊĠĠĠ Ġprivate Ġval ĠB ZIP 2 _ MAGIC Ġ= Ġbyte ArrayOf ( 0 x 3 1 , Ġ 0 x 4 1 , Ġ 0 x 5 9 , Ġ 0 x 2 6 , Ġ 0 x 5 3 , Ġ 0 x 5 9 ) ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠG ZIP _ MAGIC Ġ= Ġ 0 x 1 F 8 B ĊĠĠĠ Ġprivate Ġconst Ġval ĠG ZIP _ COMPRESS ION _ METHOD _ DE FL ATE Ġ= Ġ 0 x 0 8 ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠL Z MA _ PB _ MAX Ġ= Ġ 4 ĊĠĠĠ Ġprivate Ġconst Ġval ĠL Z MA _ PRE SET _ DICT _ SIZE _ MAX Ġ= Ġ 1 Ġshl Ġ 2 6 ĊĊĠĠĠ Ġpublic Ġfun Ġcompress ( input : ĠByte Buf , Ġtype : ĠJs 5 Compression Type , Ġkey : ĠX tea Key Ġ= ĠX tea Key . ZERO ): ĠByte Buf Ġ{ ĊĠĠĠĠĠĠĠ Ġinput . alloc (). buffer (). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . write Byte ( type . ordinal ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠJs 5 Compression Type . UN COMPRESSED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġinput . readable Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . writeInt ( len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . write Bytes ( input ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! key . is Zero ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . x tea Encrypt ( 5 , Ġlen , Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput . retain () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlen Index Ġ= Ġoutput . writer Index () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . write Zero ( 4 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun compressed Len Ġ= Ġinput . readable Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . writeInt ( un compressed Len ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= Ġoutput . writer Index () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype . create OutputStream ( Byte Buf OutputStream ( output )). use Ġ{ ĠoutputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . read Bytes ( output Stream , Ġun compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġoutput . writer Index () Ġ- Ġstart ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . setInt ( len Index , Ġlen ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! key . is Zero ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . x tea Encrypt ( 5 , Ġlen Ġ+ Ġ 4 , Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput . retain () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġcompress Best ( ĊĠĠĠĠĠĠĠ Ġinput : ĠByte Buf , ĊĠĠĠĠĠĠĠ Ġenable Lz ma : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġenable Un compressed Encryption : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġkey : ĠX tea Key Ġ= ĠX tea Key . ZERO ĊĠĠĠ Ġ): ĠByte Buf Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtypes Ġ= Ġmutable ListOf ( Js 5 Compression Type . B ZIP 2 , ĠJs 5 Compression Type . GZIP ) ĊĠĠĠĠĠĠĠ Ġif Ġ( enable Lz ma ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtypes Ġ+= ĠJs 5 Compression Type . LZ MA ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( enable Un compressed Encryption Ġ|| Ġkey . is Zero ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġ 5 5 0 Ġclient Ġdoesn 't Ġstrip Ġthe Ġ 2 Ġbyte Ġversion Ġtr ailer Ġbefore ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġpassing Ġa Ġgroup Ġto Ġthe ĠX TE A Ġde cryption Ġfunction . ĠThis Ġcauses Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġlast Ġblock Ġto Ġbe Ġincorrectly Ġdecrypt Ġin Ġmany Ġcases Ġ( depend ing ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġon Ġthe Ġlength Ġof Ġthe Ġgroup Ġmod Ġthe ĠX TE A Ġblock Ġsize ). ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThis Ġdoesn 't Ġcause Ġany Ġproblems Ġwith Ġthe Ġclient 's ĠG ZIP / B ZIP 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġimplementations , Ġas Ġthe Ġlast Ġblock Ġis Ġalways Ġpart Ġof Ġthe Ġtr ailer ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġand Ġthe Ġtr ailer Ġisn 't Ġchecked . ĠHowever , Ġit Ġwould Ġcorrupt Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġlast Ġblock Ġof Ġan Ġun encrypted Ġgroup . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠTODO ( g pe ): Ġare Ġthere Ġany Ġclients Ġwith ĠL Z MA Ġsupport Ġ_ and _ Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġde cryption Ġbug ? ĠCould Ġthe Ġenable Lz ma Ġflag Ġbe Ġre - used Ġfor ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġenable Un compressed Encryption ? ĠOr Ġshould ĠL Z MA Ġalso Ġbe Ġdisabled Ġin ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġclients Ġwith Ġthe Ġde cryption Ġbug ? ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtypes Ġ+= ĠJs 5 Compression Type . UN COMPRESSED ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġbest Ġ= Ġcompress ( input . slice (), Ġtypes . first (), Ġkey ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( type Ġin Ġtypes . drop ( 1 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompress ( input . slice (), Ġtype , Ġkey ). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output . readable Bytes () Ġ< Ġbest . readable Bytes ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbest . release () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbest Ġ= Ġoutput . retain () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġconsume Ġall Ġof Ġinput Ġso Ġthis Ġmethod Ġis Ġa Ġdrop - in Ġreplacement Ġfor Ġcompress () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( input . readable Bytes ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġbest . retain () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbest . release () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġun compress ( input : ĠByte Buf , Ġkey : ĠX tea Key Ġ= ĠX tea Key . ZERO ): ĠByte Buf Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtype Id Ġ= Ġinput . read Unsigned Byte (). toInt () ĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= ĠJs 5 Compression Type . from Ordinal ( type Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIOException (" Invalid Ġcompression Ġtype : Ġ$ type Id ") ĊĊĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġinput . readInt () ĊĠĠĠĠĠĠĠ Ġif Ġ( len Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Length Ġis Ġnegative : Ġ$ len ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠJs 5 Compression Type . UN COMPRESSED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( input . readable Bytes () Ġ< Ġlen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Data Ġtruncated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . read Bytes ( len ). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! key . is Zero ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . x tea Decrypt ( 0 , Ġlen , Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput . retain () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġlen With Un compressed Len Ġ= Ġlen Ġ+ Ġ 4 ĊĠĠĠĠĠĠĠ Ġif Ġ( input . readable Bytes () Ġ< Ġlen With Un compressed Len ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Compressed Ġdata Ġtruncated ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdecrypt ( input , Ġlen With Un compressed Len , Ġkey ). use Ġ{ Ġplaintext Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun compressed Len Ġ= Ġplaintext . readInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( un compressed Len Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Un compressed Ġlength Ġis Ġnegative : Ġ$ un compressed Len ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġplaintext . alloc (). buffer ( un compressed Len , Ġun compressed Len ). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype . create InputStream ( Byte Buf InputStream ( plaintext , Ġlen ), Ġun compressed Len ). use Ġ{ ĠinputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġremaining Ġ= Ġun compressed Len ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( remaining Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġn Ġ= Ġoutput . write Bytes ( inputStream , Ġremaining ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( n Ġ== Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Un compressed Ġdata Ġtruncated ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremaining Ġ-= Ġn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( inputStream . read () Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Un compressed Ġdata Ġoverflow ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput . retain () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġun compress Unless Encrypted ( input : ĠByte Buf ): ĠByte Buf ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġun compress If Key Valid ( input , ĠX tea Key . ZERO ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġun compress If Key Valid ( input : ĠByte Buf , Ġkey : ĠX tea Key ): ĠByte Buf ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtype Id Ġ= Ġinput . read Unsigned Byte (). toInt () ĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= ĠJs 5 Compression Type . from Ordinal ( type Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIOException (" Invalid Ġcompression Ġtype : Ġ$ type Id ") ĊĊĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġinput . readInt () ĊĠĠĠĠĠĠĠ Ġif Ġ( len Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Length Ġis Ġnegative : Ġ$ len ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠJs 5 Compression Type . UN COMPRESSED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( input . readable Bytes () Ġ< Ġlen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Data Ġtruncated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThere Ġis Ġno Ġeasy Ġway Ġfor Ġus Ġto Ġbe Ġsure Ġwhether Ġan Ġun compressed ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġgroup 's Ġkey Ġis Ġvalid Ġor Ġnot , Ġas Ġwe 'd Ġneed Ġspecific Ġvalidation ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġcode Ġfor Ġeach Ġfile Ġformat Ġthe Ġclient Ġuses Ġ( currently Ġonly Ġmaps , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġthough Ġapparently ĠRS 3 Ġis Ġalso Ġcapable Ġof Ġencrypt ing Ġinterfaces ). ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġpractice , Ġencrypted Ġfiles Ġdon 't Ġtend Ġto Ġbe Ġun compressed ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġanyway Ġ- Ġin Ġ 5 5 0 , Ġthis Ġfunctionality Ġis Ġactually Ġbroken Ġdue Ġto Ġa ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġbug Ġ( see Ġthe Ġcomment Ġabout Ġenable Un compressed Encryption Ġin ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġcompress Best Ġabove ). ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠWe Ġtherefore Ġassume Ġall Ġun compressed Ġgroups Ġare Ġun encrypted . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! key . is Zero ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġinput . read Bytes ( len ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġlen With Un compressed Len Ġ= Ġlen Ġ+ Ġ 4 ĊĠĠĠĠĠĠĠ Ġif Ġ( input . readable Bytes () Ġ< Ġlen With Un compressed Len ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Compressed Ġdata Ġtruncated ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠ Ġ* ĠDecrypt Ġtwo ĠX TE A Ġblocks , Ġwhich Ġis Ġsufficient Ġto Ġquickly Ġcheck Ġthe ĊĠĠĠĠĠĠĠĠ Ġ* Ġun compressed Ġlength Ġand Ġthe Ġcompression Ġalgorithm 's Ġheader Ġin Ġeach ĊĠĠĠĠĠĠĠĠ Ġ* Ġcase : ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠB ZIP 2 : Ġ 6 Ġbyte Ġblock Ġmagic ĊĠĠĠĠĠĠĠĠ Ġ* ĠG ZIP : ĠĠ 2 Ġbyte Ġmagic , Ġ 1 Ġbyte Ġcompression Ġmethod ĊĠĠĠĠĠĠĠĠ Ġ* ĠL Z MA : ĠĠ 1 Ġbyte Ġproperties , Ġ 4 Ġbyte Ġdictionary Ġsize ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠWe Ġnever Ġexpect Ġto Ġsee Ġa Ġfile Ġwith Ġfewer Ġthan Ġtwo Ġblocks . ĠThe ĊĠĠĠĠĠĠĠĠ Ġ* Ġcompressed Ġlength Ġof Ġan Ġempty Ġfile Ġis Ġalways Ġtwo ĠX TE A Ġblocks Ġin Ġeach ĊĠĠĠĠĠĠĠĠ Ġ* Ġcase : ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* ĠB ZIP 2 : Ġ 1 0 Ġbytes ĊĠĠĠĠĠĠĠĠ Ġ* ĠG ZIP : ĠĠ 1 8 Ġbytes ĊĠĠĠĠĠĠĠĠ Ġ* ĠL Z MA : ĠĠ 1 0 Ġbytes ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġif Ġ( len With Un compressed Len Ġ< Ġ 1 6 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Compressed Ġdata Ġshorter Ġthan Ġtwo ĠX TE A Ġblocks ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdecrypt ( input . slice (), Ġ 1 6 , Ġkey ). use Ġ{ Ġplaintext Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun compressed Len Ġ= Ġplaintext . readInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( un compressed Len Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . UN COMPRESSED Ġ-> Ġthrow ĠAssertionError () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . B ZIP 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmagic Ġ= ĠByteArray ( B ZIP 2 _ MAGIC . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplaintext . read Bytes ( magic ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! magic . content Equals ( B ZIP 2 _ MAGIC )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . GZIP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmagic Ġ= Ġplaintext . read Unsigned Short () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( magic Ġ!= ĠG ZIP _ MAGIC ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠJ age x 's Ġimplementation Ġonly Ġsupports ĠDE FL ATE . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompression Method Ġ= Ġplaintext . read Unsigned Byte (). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( compression Method Ġ!= ĠG ZIP _ COMPRESS ION _ METHOD _ DE FL ATE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . LZ MA Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproperties Ġ= Ġplaintext . read Unsigned Byte () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġencoding Ġof Ġthe Ġproperties Ġbyte Ġmeans Ġit Ġisn 't ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġpossible Ġfor Ġlc / lp Ġto Ġbe Ġout Ġof Ġrange . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpb Ġ= Ġproperties Ġ/ Ġ 4 5 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pb Ġ> ĠL Z MA _ PB _ MAX ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠJ age x 's Ġimplementation Ġdoesn 't Ġsupport Ġdictionary Ġsizes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġgreater Ġthan Ġ 2 ĠG iB Ġ( which Ġare Ġless Ġthan Ġzero Ġwhen Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġdictionary Ġsize Ġis Ġread Ġas Ġa Ġsigned Ġinteger ). ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠWe Ġalso Ġassume Ġdictionary Ġsizes Ġlarger Ġthan Ġ 6 4 ĠM iB Ġ( the ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġsize Ġof Ġthe Ġdictionary Ġat Ġ- 9 , Ġthe Ġhighest Ġpreset Ġlevel ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġindicate Ġthe Ġkey Ġis Ġincorrect . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIn Ġtheory Ġthese Ġdictionary Ġsizes Ġare Ġactually Ġvalid . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠHowever , Ġin Ġpractice ĠJ age x Ġseems Ġto Ġonly Ġuse Ġlevel Ġ- 3 Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġ- 4 Ġ( as Ġtheir Ġdictionary Ġsize Ġis Ġ 4 ĠM iB ). ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠAt tempting Ġto Ġde compress ĠL Z MA Ġstreams Ġwith Ġlarger ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġdictionaries Ġcan Ġeasily Ġcause ĠO OM Ġexceptions Ġin Ġlow ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġmemory Ġenvironments . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdict Size Ġ= Ġplaintext . readInt LE () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( dict Size Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( dict Size Ġ> ĠL Z MA _ PRE SET _ DICT _ SIZE _ MAX ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . skip Bytes ( len With Un compressed Len ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠRun Ġthe Ġentire Ġde compression Ġalgorithm Ġto Ġconfirm Ġthe Ġkey Ġis Ġvalid . ĊĠĠĠĠĠĠĠ Ġdecrypt ( input , Ġlen With Un compressed Len , Ġkey ). use Ġ{ Ġplaintext Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun compressed Len Ġ= Ġplaintext . readInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( un compressed Len Ġ>= Ġ 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠWe Ġdon 't Ġpass Ġun compressed Len Ġto Ġthe Ġbuffer Ġhere : Ġin Ġsome Ġcases , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġan Ġincorrect Ġkey Ġcan Ġproduce Ġa Ġvalid Ġheader Ġ( part icular ly Ġfor ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠL Z MA , Ġwhich Ġhas Ġno Ġmagic Ġnumber ). ĠIf Ġwe 're Ġun luck y , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġun compressed Len Ġwill Ġbe Ġa Ġhuge Ġnumber Ġ( e . g . Ġ 1 Ġor Ġ 2 Ġg ig aby tes ), ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġwhich Ġmight ĠO OM Ġsome Ġenvironments Ġif Ġallocated Ġup Ġfront . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠHowever , Ġif Ġthe Ġkey Ġis Ġincorrect Ġit 's Ġlikely Ġthat Ġactually ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġattempting Ġto Ġun compress Ġthe Ġdata Ġwill Ġquickly Ġproduce Ġan Ġerror , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġlong Ġbefore Ġwe Ġneed Ġto Ġactually Ġread Ġ 1 Ġor Ġ 2 Ġg ig aby tes Ġof Ġdata . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠWe Ġtherefore Ġallow Ġthe Ġbuffer Ġto Ġgrow Ġdynamically . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplaintext . alloc (). buffer (). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype . create InputStream ( Byte Buf InputStream ( plaintext , Ġlen ), Ġun compressed Len ). use Ġ{ ĠinputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġremaining Ġ= Ġun compressed Len ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( remaining Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġn Ġ= Ġoutput . write Bytes ( inputStream , Ġremaining ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( n Ġ== Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġun compressed Ġdata Ġtruncated ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremaining Ġ-= Ġn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( inputStream . read () Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġun compressed Ġdata Ġoverflow ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput . retain () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdecrypt ( buf : ĠByte Buf , Ġlen : ĠInt , Ġkey : ĠX tea Key ): ĠByte Buf Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( key . is Zero ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġbuf . read Ret ained Slice ( len ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbuf . read Bytes ( len ). use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . x tea Decrypt ( 0 , Ġlen , Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput . retain () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun ĠisEmpty Loc ( buf : ĠByte Buf ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtype Id Ġ= Ġbuf . read Unsigned Byte (). toInt () ĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= ĠJs 5 Compression Type . from Ordinal ( type Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIOException (" Invalid Ġcompression Ġtype : Ġ$ type Id ") ĊĊĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġbuf . readInt () ĊĠĠĠĠĠĠĠ Ġif Ġ( len Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Length Ġis Ġnegative : Ġ$ len ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( type Ġ== ĠJs 5 Compression Type . UN COMPRESSED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( buf . readable Bytes () Ġ< Ġlen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Data Ġtruncated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuf . skip Bytes ( len ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġan Ġempty Ġloc Ġgroup Ġhas Ġa Ġsingle Ġbyte ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlen Ġ== Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġlen With Un compressed Len Ġ= Ġlen Ġ+ Ġ 4 ĊĠĠĠĠĠĠĠ Ġif Ġ( buf . readable Bytes () Ġ< Ġlen With Un compressed Len ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Compressed Ġdata Ġtruncated ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbuf . skip Bytes ( len With Un compressed Len ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . UN COMPRESSED Ġ-> Ġthrow ĠAssertionError () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . B ZIP 2 Ġ-> Ġlen Ġ== Ġ 3 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠA Ġsingle Ġbyte Ġgzip Ġcomp resses Ġto Ġ 2 1 Ġbytes Ġwith Ġlevels Ġ 1 Ġto Ġ 9 , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġand Ġ 2 4 Ġbytes Ġwith Ġlevel Ġ 0 . ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . GZIP Ġ-> Ġlen Ġ== Ġ 2 1 Ġ|| Ġlen Ġ== Ġ 2 4 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJs 5 Compression Type . LZ MA Ġ-> Ġlen Ġ== Ġ 1 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ