/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠRealm ĠInc . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġio . realm . jvm Ċ Ċ import Ġjava . io . File Ċ import Ġjava . nio . file . Files Ċ import Ġjava . security . Message Digest Ċ import Ġjava . util . Collections Ċ import Ġjava . util . Enumeration Ċ import Ġjava . util . LinkedList Ċ import Ġjava . util . Locale Ċ import Ġjava . util . Properties Ċ Ċ /** Ċ Ġ* ĠLoad Ġthe ĠC ++ Ġdynamic Ġlibraries Ġfrom Ġthe Ġfat ĠJar . Ċ Ġ* ĠThe Ġfat ĠJar Ġcontains Ġthree Ġplatforms Ġ( Win , ĠLinux Ġand ĠMac ) Ġthe Ġloader Ġdetect s Ġthe Ġhost Ġplatform Ċ Ġ* Ġthen Ġextract Ġand Ġinstall Ġthe Ġlibraries Ġin Ġthe Ġsame Ġorder Ġspecified Ġin Ġthe Ġ' dynamic _ libraries . properties ' Ġfile . Ċ Ġ* Ċ Ġ* ĠNote : Ġthis Ġclass Ġshould Ġbe Ġinvoke Ġdynamically Ġusing Ġreflection Ġso Ġthe Ġclass loader Ġcan Ġhave Ġaccesses Ċ Ġ* Ġto Ġthe Ġdynamic Ġlibraries Ġfiles Ġlocated Ġinside Ġthe Ġfat ĠJar . Ċ Ġ*/ Ċ class ĠSo Loader Ġ{ ĊĠĠĠ Ġprivate Ġval Ġplatform : ĠPlatform Ġ= ĠPlatform . current OS () ĊĠĠĠ Ġprivate Ġval Ġlibs : ĠMutable List < Pair < String , ĠString >> Ġ= Ġmutable ListOf () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġread Libraries Hashes () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġload () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġload Ġthe Ġlibraries Ġin Ġthe Ġorder Ġof Ġdependency Ġspecified Ġin Ġ' dynamic _ libraries . properties ' ĊĠĠĠĠĠĠĠ Ġfor Ġ( lib Ġin Ġlibs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload ( library Name Ġ= Ġlib . first , Ġexpected Hash Ġ= Ġlib . second ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload ( library Name : ĠString , Ġexpected Hash : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġload Ġthe Ġembedded Ġ. so Ġfile Ġlocated Ġinside Ġthe ĠJar Ġfile . ĊĠĠĠĠĠĠĠ Ġ// Ġunpack ing Ġthe Ġfile Ġis Ġskipped Ġif Ġthe Ġhash Ġof Ġthe Ġfile Ġis Ġalready Ġinstalled . ĊĠĠĠĠĠĠĠ Ġ// Ġinstead , Ġthe Ġon - disk Ġfile Ġwill Ġbe Ġloaded . ĊĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġeach ĠSO Ġfile : ĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġif Ġthe Ġlibrary Ġis Ġalready Ġinstalled Ġin Ġthe Ġdefault Ġplatform Ġlocation ĊĠĠĠĠĠĠĠ Ġ// Ġpath Ġshould Ġbe Ġ< default Ġuser Ġlib Ġdir >/ io . realm . kotlin / hash / lib realm ffi . so ĊĠĠĠĠĠĠĠ Ġ// Ġif Ġthe Ġfull Ġpath Ġexists Ġ( and Ġthe Ġon - disk Ġhash Ġmatches ) Ġthen Ġload Ġit Ġotherwise Ġunpack Ġand Ġload Ġit . ĊĠĠĠĠĠĠĠ Ġval Ġlibrary Installation Location : ĠFile Ġ= Ġdefault AbsolutePath ( library Name , Ġexpected Hash ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! library Installation Location . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġunpack And Install ( library Name , Ġlibrary Installation Location , Ġexpected Hash ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġonly Ġdouble Ġcheck Ġthe Ġinstalled Ġlib Ġhash Ġ( in Ġcase Ġit Ġwas Ġt amper ed Ġwith Ġlocally ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Hash OrThrow ( library Installation Location , Ġexpected Hash ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" Unsafe Dynamic ally Loaded Code ") ĊĠĠĠĠĠĠĠ Ġ// ĠSystem . load Library Ġdoes Ġnot Ġaccept Ġa Ġfull Ġpath Ġto Ġthe Ġlib Ġ( needs Ġto Ġbe Ġin Ġthe Ġcurrent ĠJava Ġpaths ) ĊĠĠĠĠĠĠĠ ĠSystem . load ( library Installation Location . absolute Path ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġread Libraries Hashes () Ġ{ ĊĠĠĠĠĠĠĠ Ġjava Class . getResource AsStream ("${ platform . short Name }/ dynamic _ libraries . properties "). use Ġ{ Ġprops Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOrdered Properties (). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload ( props ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( lib Name Ġin Ġkeys ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlibs . add ( Pair ( lib Name Ġas ĠString , Ġget ( lib Name ) Ġas ĠString )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdefault AbsolutePath ( library Name : ĠString , Ġlibrary Hash : ĠString ): ĠFile Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠFile ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplatform . default System Location Ġ+ ĠFile . separator Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlibrary Hash Ġ+ ĠFile . separator Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( platform . prefix Ġ+ Ġlibrary Name Ġ+ Ġ"." Ġ+ Ġplatform . suffix ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlib Path Inside Jar ( library Name : ĠString ) Ġ= ĊĠĠĠĠĠĠĠ Ġ"${ platform . short Name }/${ platform . prefix }$ library Name .${ platform . suffix }" ĊĊĠĠĠ Ġprivate Ġfun Ġunpack And Install ( library Name : ĠString , Ġabsolute Path : ĠFile , Ġexpected Hash : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġabsolute Path . parent File . mkdir s () ĊĠĠĠĠĠĠĠ Ġjava Class . getResource AsStream ( lib Path Inside Jar ( library Name )). use Ġ{ Ġlib Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFiles . new OutputStream ( absolute Path . to Path ()). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlib . copy To ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġafter Ġunpack ing Ġmake Ġsure Ġthe Ġhash Ġis Ġvalid ĊĠĠĠĠĠĠĠ Ġvalid Hash OrThrow ( absolute Path , Ġexpected Hash ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalid Hash OrThrow ( file : ĠFile , Ġexpected Hash : ĠString , Ġcleanup : ĠBoolean Ġ= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! isValid Hash ( file , Ġexpected Hash )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cleanup ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . delete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġerror (" Cor rupt Ġor Ġinvalid Ġhash Ġfor Ġ${ file . absolute Path } Ġexpected Ġhash Ġis Ġ$ expected Hash ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠisValid Hash ( file : ĠFile , Ġexpected : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdigest Ġ= ĠMessage Digest . getInstance (" SHA - 1 ") ĊĠĠĠĠĠĠĠ ĠFiles . new InputStream ( file . to Path ()). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuf Ġ= ĠByteArray ( BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= Ġit . read ( buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bytes Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdigest . update ( buf , Ġ 0 , Ġbytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhash Ġ= Ġdigest . digest (). to HexString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġhash Ġ== Ġexpected ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠByteArray . to HexString (): ĠString Ġ= ĊĠĠĠĠĠĠĠ Ġjoin ToString ("", Ġtransform Ġ= Ġ{ Ġ"% 0 2 x ". format ( it ) Ġ}) Ċ } Ċ Ċ private Ġenum Ġclass ĠPlatform ( ĊĠĠĠ Ġval Ġshort Name : ĠString , ĊĠĠĠ Ġval Ġprefix : ĠString , ĊĠĠĠ Ġval Ġsuffix : ĠString , ĊĠĠĠ Ġval Ġdefault System Location : ĠString Ċ ) Ġ{ ĊĠĠĠ ĠMAC OS ( ĊĠĠĠĠĠĠĠ Ġshort Name Ġ= Ġ"/ jni / macos ", ĊĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ" lib ", ĊĠĠĠĠĠĠĠ Ġsuffix Ġ= Ġ" dylib ", ĊĠĠĠĠĠĠĠ Ġdefault System Location Ġ= Ġ"${ System . getProperty (" user . home ") }/ Library / Caches / io . realm . kotlin /" ĊĠĠĠ Ġ), ĊĠĠĠ ĠLIN UX ( ĊĠĠĠĠĠĠĠ Ġshort Name Ġ= Ġ"/ jni / linux ", ĊĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ" lib ", ĊĠĠĠĠĠĠĠ Ġsuffix Ġ= Ġ" so ", ĊĠĠĠĠĠĠĠ Ġdefault System Location Ġ= Ġ"${ System . getProperty (" user . home ") }/. cache / io . realm . kotlin /" ĊĠĠĠ Ġ), ĊĠĠĠ ĠWINDO WS ( ĊĠĠĠĠĠĠĠ Ġshort Name Ġ= Ġ"/ jni / windows ", ĊĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ"", ĊĠĠĠĠĠĠĠ Ġsuffix Ġ= Ġ" dll ", ĊĠĠĠĠĠĠĠ Ġdefault System Location Ġ= Ġ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . getenv (" LOCAL APP DATA ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġ"${ System . getProperty (" user . home ") }/ AppData / Local " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ+ Ġ"/ io - realm - kotlin /" ĊĠĠĠ Ġ); ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġcurrent OS (): ĠPlatform Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġos Ġ= ĠSystem . getProperty (" os . name "). lowercase ( Locale . getDefault ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġos . contains (" win ") Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWINDO WS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġos . contains (" nix ") Ġ|| Ġos . contains (" nux ") Ġ|| Ġos . contains (" a ix ") Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLIN UX ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġos . contains (" mac ") Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMAC OS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unsupported ĠOS : Ġ$ os ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġconst Ġval ĠBUFFER _ SIZE Ġ= Ġ 1 6 3 8 4 Ġ// Ġ 1 6 k Ċ Ċ // ĠPre serve Ġthe Ġinsertion Ġorders Ġfor Ġthe Ġkeys Ġin Ġorder Ġto Ġload Ċ // Ġthe Ġdynamic Ġlibraries Ġin Ġthe Ġsame Ġorder Ġspecified Ġin Ġthe Ġproperty Ġfile . Ċ private Ġclass ĠOrdered Properties Ġ: ĠProperties () Ġ{ ĊĠĠĠ Ġprivate Ġval Ġordered Keys Ġ= ĠLinkedList < Any >() ĊĊĠĠĠ Ġoverride Ġfun Ġput ( key : ĠAny ?, Ġvalue : ĠAny ?): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġordered Keys . add ( key !! ) ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . put ( key , Ġvalue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġkeys (): ĠEnumeration < Any > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠCollections . enumeration ( ordered Keys ) ĊĠĠĠ Ġ} Ċ } Ċ