/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 ĠGoogle ĠInc . Ċ Ġ* Ċ Ġ* ĠThis Ġprogram Ġis Ġfree Ġsoftware : Ġyou Ġcan Ġredistribute Ġit Ġand / or Ġmodify Ċ Ġ* Ġit Ġunder Ġthe Ġterms Ġof Ġthe ĠGNU ĠGeneral ĠPublic ĠLicense Ġas Ġpublished Ġby Ċ Ġ* Ġthe ĠFree ĠSoftware ĠFoundation , Ġeither Ġversion Ġ 3 Ġof Ġthe ĠLicense , Ġor Ċ Ġ* Ġ( at Ġyour Ġoption ) Ġany Ġlater Ġversion . Ċ Ġ* Ċ Ġ* ĠThis Ġprogram Ġis Ġdistributed Ġin Ġthe Ġhope Ġthat Ġit Ġwill Ġbe Ġuseful , Ċ Ġ* Ġbut ĠWITHOUT ĠANY ĠWARRANTY ; Ġwithout Ġeven Ġthe Ġimplied Ġwarranty Ġof Ċ Ġ* ĠMERCHANTABILITY Ġor ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE . Ġ ĠSee Ġthe Ċ Ġ* ĠGNU ĠGeneral ĠPublic ĠLicense Ġfor Ġmore Ġdetails . Ċ Ġ* Ċ Ġ* ĠYou Ġshould Ġhave Ġreceived Ġa Ġcopy Ġof Ġthe ĠGNU ĠGeneral ĠPublic ĠLicense Ċ Ġ* Ġalong Ġwith Ġthis Ġprogram . Ġ ĠIf Ġnot , Ġsee Ġ< http :// www . gnu . org / licenses />. Ċ Ġ*/ Ċ package Ġcom . wa 2 c . android . cif sd ocument spro vider . data . io Ċ Ċ import Ġandroid . os . Proxy FileDescriptor Callback Ċ import Ġandroid . system . Errno Exception Ċ import Ġandroid . system . Os Constants Ċ import Ġcom . wa 2 c . android . cif sd ocument spro vider . common . utils . log D Ċ import Ġcom . wa 2 c . android . cif sd ocument spro vider . common . utils . log E Ċ import Ġcom . wa 2 c . android . cif sd ocument spro vider . common . values . Access Mode Ċ import Ġjc ifs . smb . S mb Exception Ċ import Ġjc ifs . smb . S mb File Ċ import Ġjc ifs . smb . S mb Random Access File Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġjava . io . IOException Ċ Ċ /** Ċ Ġ* ĠC IF S ĠProxy ĠFile ĠCallback Ċ Ġ*/ Ċ class ĠC ifs Proxy File Callback ( ĊĠĠĠ Ġprivate Ġval Ġs mb File : ĠS mb File , ĊĠĠĠ Ġprivate Ġval Ġmode : ĠAccess Mode Ċ ) Ġ: ĠProxy FileDescriptor Callback () Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠFile Ġsize ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġfile Se ize : ĠLong Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ Ġs mb File . length () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Errno Exception ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġvar Ġreader : ĠBackground Buffer Reader ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġwriter : ĠBackground Buffer Writer ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġoutput Access : ĠS mb Random Access File ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġfun Ġget Reader (): ĠBackground Buffer Reader Ġ{ ĊĠĠĠĠĠĠĠ Ġwriter ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Access ?. close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Access Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . release () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (" Writer Ġreleased ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġreader ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠBackground Buffer Reader ( file Se ize ) Ġ{ Ġstart , Ġarray , Ġoff , Ġlen Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs mb File . open Random Access ( mode . smb Mode , ĠS mb File . FILE _ SHARE _ READ ). use Ġ{ Ġaccess Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccess . seek ( start ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccess . read ( array , Ġoff , Ġlen ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreader Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (" Reader Ġcreated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Writer (): ĠBackground Buffer Writer Ġ{ ĊĠĠĠĠĠĠĠ Ġreader ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . release () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreader Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (" Reader Ġreleased ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwriter ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠBackground Buffer Writer Ġ{ Ġstart , Ġarray , Ġoff , Ġlen Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( output Access Ġ?: Ġs mb File . open Random Access ( mode . smb Mode , ĠS mb File . FILE _ SHARE _ WRITE ). also Ġ{ Ġoutput Access Ġ= Ġit Ġ}). let Ġ{ Ġaccess Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccess . seek ( start ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccess . write ( array , Ġoff , Ġlen ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwriter Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog D (" Writer Ġcreated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Errno Exception :: class ) ĊĠĠĠ Ġoverride Ġfun Ġon GetSize (): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfile Se ize ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Errno Exception :: class ) ĊĠĠĠ Ġoverride Ġfun Ġon Read ( offset : ĠLong , Ġsize : ĠInt , Ġdata : ĠByteArray ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġget Reader (). read Buffer ( offset , Ġsize , Ġdata ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Errno Exception ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ@ Throws ( Errno Exception :: class ) ĊĠĠĠ Ġoverride Ġfun Ġon Write ( offset : ĠLong , Ġsize : ĠInt , Ġdata : ĠByteArray ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mode Ġ!= ĠAccess Mode . W ) Ġ{ Ġthrow ĠS mb Exception (" Writing Ġis Ġnot Ġpermitted ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġget Writer (). write Buffer ( offset , Ġsize , Ġdata ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Errno Exception ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Errno Exception :: class ) ĊĠĠĠ Ġoverride Ġfun Ġon F sync () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠNothing Ġto Ġdo ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Release () Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreader ?. release () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter ?. release () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Access ?. close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs mb File . close () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Errno Exception ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġ@ Throws ( Errno Exception :: class ) ĊĠĠĠ Ġprivate Ġfun Ġthrow Errno Exception ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog E ( e ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠHack Ġaround Ġthat ĠSam ba Proxy File Callback Ġthrows ĠErr no Exception Ġrather Ġthan ĠIOException ĊĠĠĠĠĠĠĠ Ġ// Ġassuming Ġthe Ġunderlying Ġcause Ġis Ġan ĠErr no Exception . ĊĠĠĠĠĠĠĠ Ġif Ġ( e . cause Ġis ĠErr no Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġ( e . cause Ġas ĠErr no Exception ?) !! ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠErr no Exception (" I / O ", ĠOs Constants . E IO , Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ