package Ġcom . air bnb . dee plink dispatch . base Ċ Ċ import Ġcom . air bnb . dee plink dispatch . component Param Prefix Ċ import Ġcom . air bnb . dee plink dispatch . component Param Suffix Ċ import Ġcom . air bnb . dee plink dispatch . configurable Path Segment Prefix Ċ import Ġcom . air bnb . dee plink dispatch . configurable Path Segment Suffix Ċ import Ġjava . io . InputStream Ċ Ċ /** Ċ Ġ* ĠChunk Ġa ĠCharSequence Ġbased Ġon Ġhow Ġlong Ġit 's ĠModified ĠUTF - 8 Ċ Ġ* Ġ( https :// en . wikipedia . org / wiki / UTF - 8 # Modified _ UTF - 8 ) ĠByteArray Ġrepresentation Ġwould Ġbe . Ċ Ġ*/ Ċ fun ĠCharSequence . chunk On Modified Utf 8 Byte Size ( chunk Size : ĠInt ): ĠList < CharSequence > Ġ{ ĊĠĠĠ Ġrequire ( chunk Size Ġ>= Ġ 3 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" UTF - 8 Ġchars Ġcan Ġbe Ġup Ġto Ġ 3 Ġbytes Ġwide . ĠMin um um Ġchunk Ġsize Ġis Ġ 3 Ġbytes ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġresult Ġ= Ġmutable ListOf < CharSequence >() ĊĠĠĠ Ġvar Ġnext Chunk Start Ġ= Ġ 0 ĊĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġthis . length ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġbyte Ġarray Ġfor Ġcurrent Ġchunk Ġand Ġcheck Ġhow Ġmany Ġbytes Ġthis Ġwould Ġtake Ġup . ĊĠĠĠĠĠĠĠ Ġ// ĠU + 0 0 0 0 Ġis Ġencoded Ġas Ġtwo Ġbytes ĠC 0 8 0 Ġin Ġmodified ĠUTF - 8 , Ġwhich Ġis Ġused Ġby ĠJava Ġto ĊĠĠĠĠĠĠĠ Ġ// Ġstore Ġstrings Ġin Ġthe Ġstring Ġtable Ġin Ġclass Ġfiles . ĊĠĠĠĠĠĠĠ Ġval Ġchar Modified Utf 8 ByteArray Size Ġ= Ġthis . substring ( next Chunk Start , Ġi Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. let Ġ{ Ġchunk Ġ-> Ġchunk . toByteArray (). size Ġ+ Ġchunk . count Ġ{ Ġchar Ġ-> Ġchar Ġ== Ġ'\ u 0 0 0 0 ' Ġ} Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠSee Ġif Ġthis Ġchar Ġwould Ġstill Ġfit Ġinto Ġthe Ġchunk . ĠIf Ġnot , Ġcreate Ġchunk Ġand Ġstart Ġnext Ġone . ĊĠĠĠĠĠĠĠ Ġif Ġ( char Modified Utf 8 ByteArray Size Ġ> Ġchunk Size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( this . sub Sequence ( next Chunk Start , Ġi )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Chunk Start Ġ= Ġi ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// ĠIf Ġthere Ġwas Ġa Ġchunk Ġthat Ġwe Ġstarted Ġbut Ġdid Ġnot Ġadd Ġyet , Ġadd Ġthe Ġrest . ĊĠĠĠ Ġif Ġ( next Chunk Start Ġ!= Ġlength ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add ( this . sub Sequence ( next Chunk Start , Ġthis . length )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult Ċ } Ċ Ċ object ĠUtils Ġ{ ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġread Match Index From Strings ( strings : ĠArray < String >): ĠByteArray ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( strings . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġbyte ArrayOf () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( strings . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstrings [ 0 ]. toByteArray ( charset ( Match Index . MATCH _ INDEX _ ENCODING )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfull String Ġ= ĠStringBuilder ( strings . sum Of Ġ{ Ġit . length Ġ}) ĊĠĠĠĠĠĠĠ Ġstrings . forEach Ġ{ Ġfull String . append ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfull String . toString (). toByteArray ( charset ( Match Index . MATCH _ INDEX _ ENCODING )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġto ByteArray Map ( input : ĠMap < String , ĠString >): ĠMap < ByteArray , ĠByteArray > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġinput . entries . associate Ġ{ Ġit . key . toByteArray () Ġto Ġit . value . toByteArray () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġto Byte Arrays List ( input : ĠArray < String >): ĠList < ByteArray > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġinput . map Ġ{ Ġit . toByteArray () Ġ}. toList () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Bytes ( inputStream : ĠInputStream ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠinputStream . read Bytes () ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif ĠComponent ĠParam , Ġfalse Ġif Ġnot . ĠThrows ĠIllegalArgumentException Ġif Ġcontains ĊĠĠĠĠ Ġ* Ġ[ component Param Suffix ] Ġor Ġ[ component Param Prefix ], Ġbut Ġout Ġof Ġorder . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġvalidate If Component Param ( uri Component : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstart Ġ= Ġuri Component . indexOf ( component Param Prefix ) ĊĠĠĠĠĠĠĠ Ġval Ġend Ġ= Ġuri Component . indexOf ( component Param Suffix ) ĊĠĠĠĠĠĠĠ Ġ// Ġ- 1 Ġis Ġthe Ġ" not Ġfound " Ġresult Ġfor ĠString # indexOf () ĊĠĠĠĠĠĠĠ Ġif Ġ( start Ġ!= Ġ- 1 Ġ|| Ġend Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( start Ġ< Ġend ) Ġ{ Ġ" Invalid ĠURI Ġcomponent : Ġ$ uri Component . Ġ$ component Param Prefix Ġmust Ġcome Ġbefore Ġ$ component Param Suffix ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( start Ġ!= Ġ- 1 Ġ&& Ġend Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid ĠURI Ġcomponent : Ġ$ uri Component . ĠIf Ġeither " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ component Param Prefix Ġor Ġ$ component Param Suffix Ġis Ġpresent , Ġthen Ġthey Ġmust Ġboth Ġbe Ġpresent Ġand Ġ$ component Param Prefix Ġmust Ġoccur Ġbefore Ġ$ component Param Suffix ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġa Ġ[ path Segment ] Ġcontains Ġeither Ġ[ configurable Path Segment Prefix ] Ġor Ġ[ configurable Path Segment Suffix ] Ġthen Ġit Ġmust ĊĠĠĠĠ Ġ* Ġstart Ġand Ġend Ġwith Ġthem , Ġrespectively . ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġ[ path Segment ] Ġlooks Ġlike Ġa Ġvalid Ġconfigurable Ġpath Ġsegment , Ġfalse Ġif Ġit Ġis Ġnot Ġa Ġconfigurable Ġpath Ġsegment . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġvalidate If Configurable Path Segment ( path Segment : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( path Segment . contains ( Regex ("$ configurable Path Segment Prefix |$ configurable Path Segment Suffix "))) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( is Configurable Path Segment ( path Segment )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ(" Malformed Ġpath Ġsegment : Ġ$ path Segment ! ĠIf Ġit Ġcontains Ġ$ configurable Path Segment Prefix Ġor Ġ$ configurable Path Segment Suffix , Ġit Ġmust Ġstart Ġwith Ġ$ configurable Path Segment Prefix Ġand Ġend Ġwith Ġ$ configurable Path Segment Suffix .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġis Configurable Path Segment ( path Segment : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ Ġpath Segment . startsWith ( configurable Path Segment Prefix ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpath Segment . endsWith ( configurable Path Segment Suffix ) Ċ } Ċ