package Ġj udoku Ċ Ċ import Ġjava . io . IOException Ċ import Ġjava . io . Reader Ċ import Ġjava . lang . reflect . Type Ċ import Ġcom . google . gson .* Ċ Ċ internal Ġobject ĠGrid Serializer Ġ{ Ċ ĉ fun ĠtoString ( g : ĠGrid , Ġhighlight N th Cell : ĠInt ?): ĠString Ġ{ Ċĉ ĉ val Ġresult Ġ= ĠStringBuffer () Ċĉ ĉ var Ġcol Ġ= Ġ 1 Ċĉ ĉ var Ġrow Ġ= Ġ 1 ĊĊĉ ĉ val Ġansi Ġ= ĠUtil . is Ansi Terminal () ĊĊĉ ĉ for Ġ( y Ġin Ġ 0 .. g . num B ands Ġ* Ġ( g . box Height Ġ+ Ġ 1 )) Ġ{ Ċĉĉ ĉ for Ġ( x Ġin Ġ 0 .. g . num Stack s Ġ* Ġ( g . box Width Ġ+ Ġ 1 )) Ġ{ Ċĉĉĉ ĉ var Ġs : ĠString ĊĊĉĉĉ ĉ if Ġ( y Ġ== Ġ 0 ) Ġ{ ĉĉĉĉĉĉĉĉĉ ĉ // Ġfirst Ġhorizontal Ġline Ċĉĉĉĉ ĉ if Ġ( x Ġ== Ġ 0 ) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ Į " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ġif Ġ( x Ġ== Ġg . num Stack s Ġ* Ġ( g . box Width Ġ+ Ġ 1 )) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ Ĳ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ġif Ġ( x Ġ% Ġ( g . box Width Ġ+ Ġ 1 ) Ġ== Ġ 0 ) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ ¬ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶĢâĶĢ âĶĢ " Ġelse Ġ" --- " Ċĉĉĉ ĉ } Ġelse Ġif Ġ( y Ġ== Ġg . num B ands Ġ* Ġ( g . box Height Ġ+ Ġ 1 )) Ġ{ ĉ ĉ // Ġlast Ġhorizontal Ġline Ċĉĉĉĉ ĉ if Ġ( x Ġ== Ġ 0 ) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶĶ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ġif Ġ( x Ġ== Ġg . num Stack s Ġ* Ġ( g . box Width Ġ+ Ġ 1 )) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ ĺ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ġif Ġ( x Ġ% Ġ( g . box Width Ġ+ Ġ 1 ) Ġ== Ġ 0 ) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ ´ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶĢâĶĢ âĶĢ " Ġelse Ġ" --- " Ċĉĉĉ ĉ } Ġelse Ġif Ġ( y Ġ% Ġ( g . box Height Ġ+ Ġ 1 ) Ġ== Ġ 0 ) Ġ{ ĉĉĉ ĉ // Ġmiddle Ġhorizontal Ġline Ċĉĉĉĉ ĉ if Ġ( x Ġ== Ġ 0 ) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ ľ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ġif Ġ( x Ġ== Ġg . num Stack s Ġ* Ġ( g . box Width Ġ+ Ġ 1 )) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ ¤ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ġif Ġ( x Ġ% Ġ( g . box Width Ġ+ Ġ 1 ) Ġ== Ġ 0 ) Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶ¼ " Ġelse Ġ" +" Ċĉĉĉĉ ĉ else Ċĉĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶĢâĶĢ âĶĢ " Ġelse Ġ" --- " Ċĉĉĉ ĉ } Ġelse Ġif Ġ( x Ġ% Ġ( g . box Width Ġ+ Ġ 1 ) Ġ== Ġ 0 ) Ċĉĉĉĉ ĉ s Ġ= Ġif Ġ( ansi ) Ġ" âĶĤ " Ġelse Ġ" |" Ċĉĉĉ ĉ else Ġ{ Ċĉĉĉĉ ĉ check ( row Ġin Ġ 1 .. g . num Rows ) Ċĉĉĉĉ ĉ check ( col Ġin Ġ 1 .. g . num Columns ) ĊĊĉĉĉĉ ĉ val Ġcell Ġ= Ġg . getCell ( col , Ġrow ) Ċĉĉĉĉ ĉ s Ġ= Ġwhen Ġ{ Ċĉĉĉĉĉ ĉ cell Ġ== ĠGrid . EMPTY Ġ-> Ġ" Ġ" Ċĉĉĉĉĉ ĉ g . size Ġ> Ġ 9 Ġ&& Ġg . size Ġ<= Ġ 2 6 Ġ-> Ġ( (' A '. toInt () Ġ- Ġ 1 Ġ+ Ġcell ). to Char ()). toString () Ċĉĉĉĉĉ ĉ else Ġ-> ĠInteger . toString ( cell ) Ċĉĉĉĉ ĉ } ĊĊĉĉĉĉ ĉ var Ġleft Ġ= Ġ" Ġ" Ċĉĉĉĉ ĉ var Ġright Ġ= Ġ" Ġ" Ċĉĉĉĉ ĉ if Ġ( g . to N th ( col , Ġrow ) Ġ== Ġhighlight N th Cell ) Ġ{ Ġleft Ġ= Ġ"[ "; Ġright Ġ= Ġ" ]" Ġ} Ċĉĉĉĉ ĉ if Ġ( s . length Ġ< Ġ 3 ) Ġs Ġ= Ġs Ġ+ Ġright Ċĉĉĉĉ ĉ if Ġ( s . length Ġ< Ġ 3 ) Ġs Ġ= Ġleft Ġ+ Ġs ĊĊĉĉĉĉ ĉ if Ġ(++ col Ġ> Ġg . num Columns ) Ġ{ Ġcol Ġ= Ġ 1 ; Ġ++ row Ġ} Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ result . append ( s ) Ċĉĉ ĉ } ĊĊĉĉ ĉ result . append ('\ n ') Ċĉ ĉ } ĊĊĉ ĉ return Ġresult . toString () Ċ ĉ } ĊĊ ĉ @ Throws ( IOException :: class ) Ċ ĉ fun Ġto Csv ( g : Grid , Ġdest : ĠAppend able ) Ġ{ Ċĉ ĉ for Ġ( row Ġin Ġ 1 .. g . num Rows ) Ġ{ Ċĉĉ ĉ for Ġ( col Ġin Ġ 1 .. g . num Columns ) Ġ{ Ċĉĉĉ ĉ if Ġ( col Ġ> Ġ 1 ) Ġdest . append (',') Ċĉĉĉ ĉ val Ġcell Ġ= Ġg . getCell ( col , Ġrow ) Ċĉĉĉ ĉ dest . append ( when Ġ{ Ċĉĉĉĉ ĉ cell Ġ== ĠGrid . EMPTY Ġ-> Ġ" Ġ" Ċĉĉĉĉ ĉ g . size Ġ> Ġ 9 Ġ&& Ġg . size Ġ<= Ġ 2 6 Ġ-> Ġ(' A '. toInt () Ġ- Ġ 1 Ġ+ Ġcell ). to Char (). toString () Ċĉĉĉĉ ĉ else Ġ-> ĠInteger . toString ( cell ) Ċĉĉĉ ĉ }) Ċĉĉ ĉ } Ċĉĉ ĉ dest . append ('\ n ') Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ fun Ġto Csv ( g : ĠGrid ): ĠString Ġ{ Ċĉ ĉ val Ġbuf Ġ= ĠStringBuffer () Ċĉ ĉ try Ġ{ Ġto Csv ( g , Ġbuf ) Ġ} Ġcatch Ġ( e : ĠException ) Ġ{} Ċĉ ĉ return Ġbuf . toString () Ċ ĉ } ĊĊ ĉ @ Throws ( IOException :: class ) Ċ ĉ fun ĠtoJson ( g : ĠGrid , Ġdest : ĠAppend able ): ĠUnit Ġ= Ġgson Instance . toJson ( g , Ġdest ) Ċ ĉ fun ĠtoJson ( g : ĠGrid ): ĠString Ġ= Ġgson Instance . toJson ( g ) ĊĊ ĉ fun Ġnew FromJson ( from : ĠReader ): ĠGrid Ġ= Ġgson Instance . fromJson ( from , ĠGrid :: class . java ) ĊĊ ĉ private Ġvar Ġ_ gson : ĠGson ? Ġ= Ġnull ĉĉĉĉ ĉ // Ġlazy Ġinit Ċ ĉ private Ġval Ġgson Instance : ĠGson Ċĉ ĉ get () Ġ{ Ċĉĉ ĉ /* ĉ !! Ġis Ġbecause Ġcompiler Ġwar ns Ġthat Ġ_ gson Ġmay Ġhave Ġbeen Ġset Ġto Ġnull Ġby Ċĉĉĉ ĉ another Ġthread Ġin Ġbetween Ġtesting Ġit Ġand Ġreturning Ġit , Ġbut Ġthe Ġvar Ċĉĉĉ ĉ never Ġgoes Ġfrom Ġnon - null Ġto Ġnull Ġ( only Ġthe Ġother Ġway Ġaround ) Ġ*/ Ċĉĉ ĉ if Ġ(_ gson Ġ!= Ġnull ) Ġreturn Ġ_ gson !! ĊĊĉĉ ĉ val Ġserializer Ġ= Ġobject Ġ: ĠJsonSerializer < Grid > Ġ{ Ċĉĉĉ ĉ override Ġfun Ġserialize ( g : ĠGrid , ĠtypeOf T : ĠType , Ċĉĉĉĉĉ ĉ context : ĠJson Serialization Context ): ĠJsonObject Ġ{ Ċĉĉĉĉ ĉ val Ġobj Ġ= ĠJsonObject () Ċĉĉĉĉ ĉ obj . addProperty (" size ", Ġg . size ) Ċĉĉĉĉ ĉ obj . addProperty (" box Width ", Ġg . box Width ) Ċĉĉĉĉ ĉ obj . addProperty (" box Height ", Ġg . box Height ) ĊĊĉĉĉĉ ĉ val Ġcells Ġ= ĠJson Array () Ċĉĉĉĉ ĉ for Ġ( n Ġin Ġ 1 .. g . num Cells ) Ġcells . add ( Json Primitive ( g . cells [ n ])) ĊĉĉĉĠĠĠĠĠĠĠ Ġobj . add (" cells ", Ġcells ) ĊĊĉĉĉĉ ĉ return Ġobj ; Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĉĉ ĉ val Ġde serializer Ġ= Ġobject Ġ: ĠJson Deserializer < Grid > Ġ{ Ċĉĉĉ ĉ @ Throws ( Json ParseException :: class ) Ċĉĉĉ ĉ override Ġfun Ġdeserialize ( json : ĠJson Element , ĠtypeOf T : ĠType , Ċĉĉĉĉĉ ĉ context : ĠJson Deserialization Context ): ĠGrid Ġ{ Ċĉĉĉĉ ĉ val ĠjsonObject Ġ= Ġjson . getAs JsonObject () ĊĊĉĉĉĉ ĉ val Ġsize Ġ= ĠjsonObject . get (" size "). getAs Int () Ċĉĉĉĉ ĉ val Ġbox Width Ġ= ĠjsonObject . get (" box Width "). getAs Int () Ċĉĉĉĉ ĉ val Ġbox Height Ġ= ĠjsonObject . get (" box Height "). getAs Int () Ċĉĉĉĉ ĉ if Ġ( size Ġ!= Ġbox Width Ġ* Ġbox Height ) Ċĉĉĉĉĉ ĉ throw ĠJson ParseException (" Mis matching Ġgrid Ġsize Ġand Ġbox Ġsize ") ĊĊĉĉĉĉ ĉ val Ġarray Ġ= ĠjsonObject . get (" cells "). getAs JsonArray () Ċĉĉĉĉ ĉ if Ġ( array . size () Ġ!= Ġsize Ġ* Ġsize ) Ċĉĉĉĉĉ ĉ throw ĠJson ParseException (" Too Ġfew Ġor Ġtoo Ġmany Ġcell Ġvalues ") ĊĊĉĉĉĉ ĉ val Ġcells Ġ= ĠByteArray ( 1 Ġ+ Ġsize Ġ* Ġsize ) Ġ{ Ċĉĉĉĉĉ ĉ /* ĉ cells [] Ġhas Ġan Ġextra Ġunused Ġelement Ġat Ġthe Ġfront . ĠIndex ing Ġis ĊĉĉĉĉĉĉĠĠ ĉ by Ġa Ġ 1 - based Ġindex . ĠR ather Ġthan Ġdo Ġa Ġsub traction Ġeach Ġtime ĊĉĉĉĉĉĉĠĠ ĉ cell Ġvalues Ġare Ġindexed Ġand Ġread , Ġfor Ġefficiency , Ġthe Ġindex Ġis Ċĉĉĉĉĉĉ ĉ left Ġunchanged . Ġ*/ Ċĉĉĉĉĉ ĉ i Ġ-> Ġ( if Ġ( i Ġ== Ġ 0 ) ĠGrid . EMPTY Ġelse Ġarray . get ( i Ġ- Ġ 1 ). getAs Int ()). to Byte () Ċĉĉĉĉ ĉ } ĊĊĉĉĉĉ ĉ val Ġg Ġ= ĠGrid ( size , Ġbox Width , Ġbox Height , Ġcells , Ċĉĉĉĉĉ ĉ Grid . Deserial ized Type . DE SERIAL IZED ) Ċĉĉĉĉ ĉ if Ġ(! g . is Legal ()) Ġthrow ĠJson ParseException (" Illegal Ġcell Ġvalues ") ĊĊĉĉĉĉ ĉ return Ġg Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĉĉ ĉ _ gson Ġ= ĠGson Builder () Ċĉĉĉ ĉ . register Type Adapter ( Grid :: class . java , Ġserializer ) Ċĉĉĉ ĉ . register Type Adapter ( Grid :: class . java , Ġde serializer ) Ċĉĉĉ ĉ . set Pretty Print ing () Ċĉĉĉ ĉ . create () ĊĊĉĉ ĉ check (_ gson Ġ!= Ġnull ) Ġ{ Ġ" Gson Builder . create () Ġreturned Ġnull " Ġ} Ċĉĉ ĉ return Ġ_ gson !! Ċĉ ĉ } Ċ } Ċ