/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 8 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ċ Ġ* Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ġ*/ Ċ Ċ package Ġkotlin . native . concurrent Ċ Ċ import Ġkotlin . native . internal .* Ċ import Ġkotlinx . c interop .* Ċ Ċ @ Symbol Name (" Kotlin _ Any _ share ") Ċ external Ġprivate Ġfun ĠAny . share () Ċ Ċ @ Symbol Name (" Kotlin _ CP o inter _ Copy Memory ") Ċ external Ġprivate Ġfun ĠCopy Memory ( to : ĠCO pa que Pointer ?, Ġfrom : ĠCO pa que Pointer ?, Ġcount : ĠInt ) Ċ Ċ @ Symbol Name (" Read Heap Ref No Lock ") Ċ internal Ġexternal Ġfun Ġread Heap Ref No Lock ( where : ĠAny , Ġindex : ĠInt ): ĠAny ? Ċ Ċ /** Ċ Ġ* ĠMutable Ġconcurrent ly Ġaccessible Ġdata Ġbuffer . ĠCould Ġbe Ġaccessed Ġfrom Ġseveral Ġworkers Ġsim ult en iously . Ċ Ġ*/ Ċ @ Frozen Ċ @ No Re order Fields Ċ public Ġclass ĠMutable Data Ġconstructor ( capacity : ĠInt Ġ= Ġ 1 6 ) Ġ{ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( capacity Ġ<= Ġ 0 ) Ġthrow ĠIllegalArgumentException () ĊĠĠĠĠĠĠĠ Ġ// ĠInstance Ġof ĠMutable Data Ġis Ġshared . ĊĠĠĠĠĠĠĠ Ġshare () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġbuffer _ Ġ= ĠByteArray ( capacity ). apply Ġ{ Ġshare () Ġ} ĊĠĠĠ Ġprivate Ġvar Ġbuffer : ĠByteArray ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( kotlin . native . Platform . memory Model ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkotlin . native . Memory Model . EXPERIMENT AL Ġ-> Ġbuffer _ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġread Heap Ref No Lock ( this , Ġ 0 ) Ġas ĠByteArray ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ Ġbuffer _ Ġ= Ġvalue } ĊĠĠĠ Ġprivate Ġvar Ġsize _ Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġval Ġlock Ġ= ĠLock () ĊĊĠĠĠ Ġprivate Ġfun Ġresize Data Locked ( new Size : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( new Size Ġ>= Ġsize ) ĊĠĠĠĠĠĠĠ Ġif Ġ( new Size Ġ> Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġactual Size Ġ= Ġmax Of ( buffer . size Ġ* Ġ 3 Ġ/ Ġ 2 Ġ+ Ġ 1 , Ġnew Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Buffer Ġ= ĠByteArray ( actual Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer . copy Into ( new Buffer , ĠstartIndex Ġ= Ġ 0 , Ġend Index Ġ= Ġsize ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Buffer . share () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Ġ= Ġnew Buffer ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġsize ĊĠĠĠĠĠĠĠ Ġsize _ Ġ= Ġnew Size ĊĠĠĠĠĠĠĠ Ġreturn Ġposition ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCurrent Ġdata Ġsize , Ġmay Ġconcurrent ly Ġchange Ġlater Ġon . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġval Ġsize : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġsize _ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReset Ġthe Ġdata Ġbuffer , Ġmak ings Ġits Ġsize Ġ 0 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġreset () Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsize _ Ġ= Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends Ġdata Ġto Ġthe Ġbuffer . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġappend ( data : ĠMutable Data ) Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Copy Ġ= Ġdata . size ĊĠĠĠĠĠĠĠ Ġval Ġwhere Ġ= Ġresize Data Locked ( size Ġ+ Ġto Copy ) ĊĠĠĠĠĠĠĠ Ġdata . copy Into ( buffer , Ġ 0 , Ġto Copy , Ġwhere ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends Ġbyte Ġarray Ġto Ġthe Ġbuffer . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġappend ( data : ĠByteArray , Ġfrom Index : ĠInt Ġ= Ġ 0 , Ġto Index : ĠInt Ġ= Ġdata . size ): ĠUnit Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( from Index Ġ> Ġto Index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIndex OutOfBoundsException ("$ from Index Ġis Ġbigger Ġthan Ġ$ to Index ") ĊĠĠĠĠĠĠĠ Ġif Ġ( from Index Ġ== Ġto Index ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġwhere Ġ= Ġresize Data Locked ( this . size Ġ+ Ġ( to Index Ġ- Ġfrom Index )) ĊĠĠĠĠĠĠĠ Ġdata . copy Into ( buffer , Ġwhere , Ġfrom Index , Ġto Index ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends ĠC Ġdata Ġto Ġthe Ġbuffer , Ġif Ġ` data ` Ġis Ġnull Ġor Ġ` count ` Ġis Ġnon - positive Ġ- Ġreturn . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġappend ( data : ĠCO pa que Pointer ?, Ġcount : ĠInt ): ĠUnit Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( data Ġ== Ġnull Ġ|| Ġcount Ġ<= Ġ 0 ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġwhere Ġ= Ġresize Data Locked ( this . size Ġ+ Ġcount ) ĊĠĠĠĠĠĠĠ Ġbuffer . use Pin ned Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġ-> ĠCopy Memory ( it . address Of ( where ), Ġdata , Ġcount ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCop ies Ġrange Ġof Ġmutable Ġdata Ġto Ġthe Ġbyte Ġarray . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġcopy Into ( output : ĠByteArray , Ġdestination Index : ĠInt , ĠstartIndex : ĠInt , Ġend Index : ĠInt ): ĠUnit Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuffer . copy Into ( output , Ġdestination Index , ĠstartIndex , Ġend Index ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġa Ġbyte Ġfrom Ġthe Ġmutable Ġdata . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ Throws ĠIndex OutOfBoundsException Ġif Ġindex Ġis Ġbeyond Ġrange . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġoperator Ġfun Ġget ( index : ĠInt ): ĠByte Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġindex Ġ< Ġ 0 Ġis Ġchecked Ġbelow Ġby Ġarray Ġaccess . ĊĠĠĠĠĠĠĠ Ġif Ġ( index Ġ>= Ġsize ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIndex OutOfBoundsException ("$ index Ġis Ġnot Ġbelow Ġ$ size ") ĊĠĠĠĠĠĠĠ Ġbuffer [ index ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġprovided Ġblock Ġunder Ġlock Ġwith Ġraw Ġpointer Ġto Ġthe Ġdata Ġstored Ġin Ġthe Ġbuffer . ĊĠĠĠĠ Ġ* ĠBlock Ġis Ġexecuted Ġunder Ġthe Ġspin lock , Ġand Ġmust Ġbe Ġshort . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġ< R > Ġwith Pointer Locked ( block : Ġ( CO pa que Pointer , Ġdata Size : ĠInt ) Ġ-> ĠR ) Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuffer . use Pin ned Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġ-> Ġblock ( it . address Of ( 0 ), Ġsize ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġprovided Ġblock Ġunder Ġlock Ġwith Ġthe Ġraw Ġdata Ġbuffer . ĊĠĠĠĠ Ġ* ĠBlock Ġis Ġexecuted Ġunder Ġthe Ġspin lock , Ġand Ġmust Ġbe Ġshort . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġfun Ġ< R > Ġwith Buffer Locked ( block : Ġ( array : ĠByteArray , Ġdata Size : ĠInt ) Ġ-> ĠR ) Ġ= Ġlocked ( lock ) Ġ{ ĊĠĠĠĠĠĠĠ Ġblock ( buffer , Ġsize ) ĊĠĠĠ Ġ} Ċ } Ċ