{-# LANGUAGE FlexibleInstances, MagicHash #-}

{- |
    Module      :  SDP.Binary
    Copyright   :  (c) Andrey Mulik 2020
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  portable
    
    @SDP.Binary@ provides @sdp@ instances for binary.
-}
module SDP.Binary
(
  -- * Export
  module Data.Binary
)
where

import Prelude ()
import SDP.SafePrelude
import SDP.Unboxed
import SDP.Linear

import SDP.Templates.AnyBorder
import SDP.Templates.AnyChunks

import SDP.Prim.SArray
import SDP.Prim.SBytes

import Data.Binary

default ()

--------------------------------------------------------------------------------

instance (Binary e) => Binary (SArray# e)
  where
    get :: Get (SArray# e)
get = do Int
n <- Get Int
forall t. Binary t => Get t
get; Int -> [e] -> SArray# e
forall l e. Linear l e => Int -> [e] -> l
fromListN Int
n ([e] -> SArray# e) -> Get [e] -> Get (SArray# e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get e -> Get [e]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n Get e
forall t. Binary t => Get t
get
    put :: SArray# e -> Put
put = [e] -> Put
forall t. Binary t => [t] -> Put
putList ([e] -> Put) -> (SArray# e -> [e]) -> SArray# e -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SArray# e -> [e]
forall l e. Linear l e => l -> [e]
listL

instance (Binary e, Unboxed e) => Binary (SBytes# e)
  where
    get :: Get (SBytes# e)
get = do Int
n <- Get Int
forall t. Binary t => Get t
get; Int -> [e] -> SBytes# e
forall l e. Linear l e => Int -> [e] -> l
fromListN Int
n ([e] -> SBytes# e) -> Get [e] -> Get (SBytes# e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get e -> Get [e]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n Get e
forall t. Binary t => Get t
get
    put :: SBytes# e -> Put
put = [e] -> Put
forall t. Binary t => [t] -> Put
putList ([e] -> Put) -> (SBytes# e -> [e]) -> SBytes# e -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SBytes# e -> [e]
forall l e. Linear l e => l -> [e]
listL

instance (Nullable (rep e), Binary (rep e)) => Binary (AnyChunks rep e)
  where
    put :: AnyChunks rep e -> Put
put = \ AnyChunks rep e
es -> let cs :: [rep e]
cs = AnyChunks rep e -> [rep e]
forall (rep :: * -> *) e. AnyChunks rep e -> [rep e]
toChunks AnyChunks rep e
es in do Int -> Put
forall t. Binary t => t -> Put
put ([rep e] -> Int
forall b i. Bordered b i => b -> Int
sizeOf [rep e]
cs); [rep e] -> Put
forall t. Binary t => [t] -> Put
putList [rep e]
cs
    get :: Get (AnyChunks rep e)
get = do Int
n <- Get Int
forall t. Binary t => Get t
get; [rep e] -> AnyChunks rep e
forall (rep :: * -> *) e.
Nullable (rep e) =>
[rep e] -> AnyChunks rep e
fromChunks ([rep e] -> AnyChunks rep e)
-> Get [rep e] -> Get (AnyChunks rep e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get (rep e) -> Get [rep e]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n Get (rep e)
forall t. Binary t => Get t
get

instance (Binary i, Index i, Binary (rep e)) => Binary (AnyBorder rep i e)
  where
    put :: AnyBorder rep i e -> Put
put = \ (AnyBorder i
l i
u rep e
es) -> do i -> Put
forall t. Binary t => t -> Put
put i
l; i -> Put
forall t. Binary t => t -> Put
put i
u; rep e -> Put
forall t. Binary t => t -> Put
put rep e
es
    get :: Get (AnyBorder rep i e)
get = (i -> i -> rep e -> AnyBorder rep i e)
-> Get i -> Get i -> Get (rep e) -> Get (AnyBorder rep i e)
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 i -> i -> rep e -> AnyBorder rep i e
forall (rep :: * -> *) i e. i -> i -> rep e -> AnyBorder rep i e
AnyBorder Get i
forall t. Binary t => Get t
get Get i
forall t. Binary t => Get t
get Get (rep e)
forall t. Binary t => Get t
get