-- |XDR Serialization

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Network.ONCRPC.XDR.Serial
  ( XDR(..)
  , XDREnum(..)
  , xdrToEnum'
  , xdrPutEnum
  , xdrGetEnum
  , XDRUnion(..)
  , xdrDiscriminant
  , xdrPutUnion
  , xdrGetUnion
  
  , xdrSerialize
  , xdrSerializeLazy
  , xdrDeserialize
  , xdrDeserializeLazy
  ) where

import           Control.Monad (guard, unless, replicateM)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import           Data.Functor.Identity (runIdentity)
import           Data.Maybe (fromJust)
import           Data.Proxy (Proxy(..))
import qualified Data.Serialize as S
import qualified Data.Vector as V
import qualified Network.ONCRPC.XDR.Types as XDR
import           GHC.TypeLits (KnownNat, natVal)

import           Network.ONCRPC.XDR.Array

-- |An XDR type that can be (de)serialized.
class XDR a where
  -- |XDR identifier/type descriptor; argument value is ignored.
  xdrType :: a -> String
  xdrPut :: a -> S.Put
  xdrGet :: S.Get a

instance XDR XDR.Int where
  xdrType :: Int -> String
xdrType Int
_ = String
"int"
  xdrPut :: Int -> Put
xdrPut = Int -> Put
S.putInt32be
  xdrGet :: Get Int
xdrGet = Get Int
S.getInt32be
instance XDR XDR.UnsignedInt where
  xdrType :: Length -> String
xdrType Length
_ = String
"unsigned int"
  xdrPut :: Length -> Put
xdrPut = Length -> Put
S.putWord32be
  xdrGet :: Get Length
xdrGet = Get Length
S.getWord32be
instance XDR XDR.Hyper where
  xdrType :: Hyper -> String
xdrType Hyper
_ = String
"hyper"
  xdrPut :: Hyper -> Put
xdrPut = Hyper -> Put
S.putInt64be
  xdrGet :: Get Hyper
xdrGet = Get Hyper
S.getInt64be
instance XDR XDR.UnsignedHyper where
  xdrType :: UnsignedHyper -> String
xdrType UnsignedHyper
_ = String
"unsigned hyper"
  xdrPut :: UnsignedHyper -> Put
xdrPut = UnsignedHyper -> Put
S.putWord64be
  xdrGet :: Get UnsignedHyper
xdrGet = Get UnsignedHyper
S.getWord64be
instance XDR XDR.Float where
  xdrType :: Float -> String
xdrType Float
_ = String
"float"
  xdrPut :: Float -> Put
xdrPut = Float -> Put
S.putFloat32be
  xdrGet :: Get Float
xdrGet = Get Float
S.getFloat32be
instance XDR XDR.Double where
  xdrType :: Double -> String
xdrType Double
_ = String
"double"
  xdrPut :: Double -> Put
xdrPut = Double -> Put
S.putFloat64be
  xdrGet :: Get Double
xdrGet = Get Double
S.getFloat64be
instance XDR XDR.Bool where
  xdrType :: Bool -> String
xdrType Bool
_ = String
"bool"
  xdrPut :: Bool -> Put
xdrPut = forall a. XDREnum a => a -> Put
xdrPutEnum
  xdrGet :: Get Bool
xdrGet = forall a. XDREnum a => Get a
xdrGetEnum

-- |An XDR type defined with \"enum\".
-- Note that the 'XDREnum' 'XDR.Int' value is not (necessarily) the same as the 'Enum' 'Int' value.
-- The 'Enum' instance is derived automatically to allow 'succ', etc. to work usefully in Haskell, whereas the 'XDREnum' reflects the XDR-defined values.
class (XDR a, Enum a) => XDREnum a where
  xdrFromEnum :: a -> XDR.Int
  xdrToEnum :: MonadFail m => XDR.Int -> m a

instance XDREnum XDR.Int where
  xdrFromEnum :: Int -> Int
xdrFromEnum = forall a. a -> a
id
  xdrToEnum :: forall (m :: * -> *). MonadFail m => Int -> m Int
xdrToEnum = forall (m :: * -> *) a. Monad m => a -> m a
return

instance XDREnum XDR.UnsignedInt where
  xdrFromEnum :: Length -> Int
xdrFromEnum = forall a b. (Integral a, Num b) => a -> b
fromIntegral
  xdrToEnum :: forall (m :: * -> *). MonadFail m => Int -> m Length
xdrToEnum = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- |Version of 'xdrToEnum' that fails at runtime for invalid values: @fromJust . 'xdrToEnum'@.
xdrToEnum' :: XDREnum a => XDR.Int -> a
xdrToEnum' :: forall a. XDREnum a => Int -> a
xdrToEnum' = forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (XDREnum a, MonadFail m) => Int -> m a
xdrToEnum

-- |Default implementation of 'xdrPut' for 'XDREnum'.
xdrPutEnum :: XDREnum a => a -> S.Put
xdrPutEnum :: forall a. XDREnum a => a -> Put
xdrPutEnum = forall t. Serialize t => Putter t
S.put forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDREnum a => a -> Int
xdrFromEnum

-- |Default implementation of 'xdrGet' for 'XDREnum'.
xdrGetEnum :: XDREnum a => S.Get a
xdrGetEnum :: forall a. XDREnum a => Get a
xdrGetEnum = forall a (m :: * -> *). (XDREnum a, MonadFail m) => Int -> m a
xdrToEnum forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall t. Serialize t => Get t
S.get

instance XDREnum XDR.Bool where
  xdrFromEnum :: Bool -> Int
xdrFromEnum Bool
False = Int
0
  xdrFromEnum Bool
True = Int
1
  xdrToEnum :: forall (m :: * -> *). MonadFail m => Int -> m Bool
xdrToEnum Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
  xdrToEnum Int
1 = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  xdrToEnum Int
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"invalid bool"

-- |An XDR type defined with \"union\"
class (XDR a, XDREnum (XDRDiscriminant a)) => XDRUnion a where
  type XDRDiscriminant a :: *
  -- |Split a union into its discriminant and body generator.
  xdrSplitUnion :: a -> (XDR.Int, S.Put)
  -- |Get the body of a union based on its discriminant.
  xdrGetUnionArm :: XDR.Int -> S.Get a

xdrDiscriminant :: XDRUnion a => a -> XDRDiscriminant a
xdrDiscriminant :: forall a. XDRUnion a => a -> XDRDiscriminant a
xdrDiscriminant = forall a. XDREnum a => Int -> a
xdrToEnum' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDRUnion a => a -> (Int, Put)
xdrSplitUnion

-- |Default implementation of 'xdrPut' for 'XDRUnion'.
xdrPutUnion :: XDRUnion a => a -> S.Put
xdrPutUnion :: forall a. XDRUnion a => a -> Put
xdrPutUnion = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDR a => a -> Put
xdrPut) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDRUnion a => a -> (Int, Put)
xdrSplitUnion

-- |Default implementation of 'xdrGet' for 'XDRUnion'.
xdrGetUnion :: XDRUnion a => S.Get a
xdrGetUnion :: forall a. XDRUnion a => Get a
xdrGetUnion = forall a. XDR a => Get a
xdrGet forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. XDRUnion a => Int -> Get a
xdrGetUnionArm

instance XDR a => XDR (XDR.Optional a) where
  xdrType :: Optional a -> String
xdrType = (Char
'*'forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDR a => a -> String
xdrType forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasCallStack => Maybe a -> a
fromJust
  xdrPut :: Optional a -> Put
xdrPut = forall a. XDRUnion a => a -> Put
xdrPutUnion
  xdrGet :: Get (Optional a)
xdrGet = forall a. XDRUnion a => Get a
xdrGetUnion

instance XDR a => XDRUnion (XDR.Optional a) where
  type XDRDiscriminant (XDR.Optional a) = XDR.Bool
  xdrSplitUnion :: Optional a -> (Int, Put)
xdrSplitUnion Optional a
Nothing = (Int
0, forall (m :: * -> *) a. Monad m => a -> m a
return ())
  xdrSplitUnion (Just a
a) = (Int
1, forall a. XDR a => a -> Put
xdrPut a
a)
  xdrGetUnionArm :: Int -> Get (Optional a)
xdrGetUnionArm Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  xdrGetUnionArm Int
1 = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. XDR a => Get a
xdrGet
  xdrGetUnionArm Int
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"xdrGetUnion: invalid discriminant for " forall a. [a] -> [a] -> [a]
++ forall a. XDR a => a -> String
xdrType (forall a. HasCallStack => a
undefined :: XDR.Optional a)

xdrPutPad :: XDR.Length -> S.Put
xdrPutPad :: Length -> Put
xdrPutPad Length
n = case Length
n forall a. Integral a => a -> a -> a
`mod` Length
4 of
  Length
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Length
1 -> Putter Word16
S.putWord16host Word16
0 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Putter Word8
S.putWord8 Word8
0
  Length
2 -> Putter Word16
S.putWord16host Word16
0
  ~Length
3 -> Putter Word8
S.putWord8 Word8
0

xdrGetPad :: XDR.Length -> S.Get ()
xdrGetPad :: Length -> Get ()
xdrGetPad Length
n = case Length
n forall a. Integral a => a -> a -> a
`mod` Length
4 of
  Length
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Length
1 -> do
    Word16
0 <- Get Word16
S.getWord16host
    Word8
0 <- Get Word8
S.getWord8
    forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Length
2 -> do
    Word16
0 <- Get Word16
S.getWord16host
    forall (m :: * -> *) a. Monad m => a -> m a
return ()
  ~Length
3 -> do
    Word8
0 <- Get Word8
S.getWord8
    forall (m :: * -> *) a. Monad m => a -> m a
return ()

bsLength :: BS.ByteString -> XDR.Length
bsLength :: ByteString -> Length
bsLength = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Int
BS.length

xdrPutByteString :: XDR.Length -> BS.ByteString -> S.Put
xdrPutByteString :: Length -> ByteString -> Put
xdrPutByteString Length
l ByteString
b
  | ByteString -> Length
bsLength ByteString
b forall a. Eq a => a -> a -> Bool
/= Length
l = forall a. HasCallStack => String -> a
error String
"xdrPutByteString: incorrect length"
  | Bool
otherwise = do
  ByteString -> Put
S.putByteString ByteString
b
  Length -> Put
xdrPutPad Length
l

xdrGetByteString :: XDR.Length -> S.Get BS.ByteString
xdrGetByteString :: Length -> Get ByteString
xdrGetByteString Length
l = do
  ByteString
b <- Int -> Get ByteString
S.getByteString forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Length
l
  Length -> Get ()
xdrGetPad Length
l
  forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
b

fixedLength :: forall n a . KnownNat n => LengthArray 'EQ n a -> String -> String
fixedLength :: forall (n :: Nat) a.
KnownNat n =>
LengthArray 'EQ n a -> String -> String
fixedLength LengthArray 'EQ n a
a = (forall a. [a] -> [a] -> [a]
++ (Char
'[' forall a. a -> [a] -> [a]
: forall a. Show a => a -> String
show (forall (n :: Nat) a. KnownNat n => LengthArray 'EQ n a -> Int
fixedLengthArrayLength LengthArray 'EQ n a
a) forall a. [a] -> [a] -> [a]
++ String
"]"))

variableLength :: forall n a . KnownNat n => LengthArray 'LT n a -> String -> String
variableLength :: forall (n :: Nat) a.
KnownNat n =>
LengthArray 'LT n a -> String -> String
variableLength LengthArray 'LT n a
a
  | Length
n forall a. Eq a => a -> a -> Bool
== Length
XDR.maxLength = (forall a. [a] -> [a] -> [a]
++ String
"<>")
  | Bool
otherwise = (forall a. [a] -> [a] -> [a]
++ (Char
'<' forall a. a -> [a] -> [a]
: forall a. Show a => a -> String
show Length
n forall a. [a] -> [a] -> [a]
++ String
">"))
  where n :: Length
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) a. KnownNat n => LengthArray 'LT n a -> Int
boundedLengthArrayBound LengthArray 'LT n a
a

xdrGetBoundedArray :: forall n a . KnownNat n => (XDR.Length -> S.Get a) -> S.Get (LengthArray 'LT n a)
xdrGetBoundedArray :: forall (n :: Nat) a.
KnownNat n =>
(Length -> Get a) -> Get (LengthArray 'LT n a)
xdrGetBoundedArray Length -> Get a
g = do
  Length
l <- forall a. XDR a => Get a
xdrGet
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Length
l forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Nat) a. KnownNat n => LengthArray 'LT n a -> Int
boundedLengthArrayBound (forall a. HasCallStack => a
undefined :: LengthArray 'LT n a))
  forall a (o :: Ordering) (n :: Nat). a -> LengthArray o n a
unsafeLengthArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Length -> Get a
g Length
l

instance (KnownNat n, XDR a) => XDR (LengthArray 'EQ n [a]) where
  xdrType :: LengthArray 'EQ n [a] -> String
xdrType LengthArray 'EQ n [a]
la = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'EQ n a -> String -> String
fixedLength LengthArray 'EQ n [a]
la forall a b. (a -> b) -> a -> b
$ forall a. XDR a => a -> String
xdrType forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'EQ n [a]
la
  xdrPut :: LengthArray 'EQ n [a] -> Put
xdrPut LengthArray 'EQ n [a]
la = do
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. XDR a => a -> Put
xdrPut [a]
a
    where
    a :: [a]
a = forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'EQ n [a]
la
  xdrGet :: Get (LengthArray 'EQ n [a])
xdrGet = forall a (o :: Ordering) (n :: Nat). a -> LengthArray o n a
unsafeLengthArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall a. Num a => Integer -> a
fromInteger (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n))) forall a. XDR a => Get a
xdrGet

instance (KnownNat n, XDR a) => XDR (LengthArray 'LT n [a]) where
  xdrType :: LengthArray 'LT n [a] -> String
xdrType LengthArray 'LT n [a]
la = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'LT n a -> String -> String
variableLength LengthArray 'LT n [a]
la forall a b. (a -> b) -> a -> b
$ forall a. XDR a => a -> String
xdrType forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'LT n [a]
la
  xdrPut :: LengthArray 'LT n [a] -> Put
xdrPut LengthArray 'LT n [a]
la = do
    forall a. XDR a => a -> Put
xdrPut (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
a) :: XDR.Length)
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. XDR a => a -> Put
xdrPut [a]
a
    where
    a :: [a]
a = forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'LT n [a]
la
  xdrGet :: Get (LengthArray 'LT n [a])
xdrGet = forall (n :: Nat) a.
KnownNat n =>
(Length -> Get a) -> Get (LengthArray 'LT n a)
xdrGetBoundedArray forall a b. (a -> b) -> a -> b
$ \Length
l -> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall a b. (Integral a, Num b) => a -> b
fromIntegral Length
l) forall a. XDR a => Get a
xdrGet

instance (KnownNat n, XDR a) => XDR (LengthArray 'EQ n (V.Vector a)) where
  xdrType :: LengthArray 'EQ n (Vector a) -> String
xdrType LengthArray 'EQ n (Vector a)
la = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'EQ n a -> String -> String
fixedLength LengthArray 'EQ n (Vector a)
la forall a b. (a -> b) -> a -> b
$ forall a. XDR a => a -> String
xdrType forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> a
V.head forall a b. (a -> b) -> a -> b
$ forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'EQ n (Vector a)
la
  xdrPut :: LengthArray 'EQ n (Vector a) -> Put
xdrPut LengthArray 'EQ n (Vector a)
la = do
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. XDR a => a -> Put
xdrPut Vector a
a
    where
    a :: Vector a
a = forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'EQ n (Vector a)
la
  xdrGet :: Get (LengthArray 'EQ n (Vector a))
xdrGet = forall a (o :: Ordering) (n :: Nat). a -> LengthArray o n a
unsafeLengthArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM (forall a. Num a => Integer -> a
fromInteger (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n))) forall a. XDR a => Get a
xdrGet

instance (KnownNat n, XDR a) => XDR (LengthArray 'LT n (V.Vector a)) where
  xdrType :: LengthArray 'LT n (Vector a) -> String
xdrType LengthArray 'LT n (Vector a)
la = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'LT n a -> String -> String
variableLength LengthArray 'LT n (Vector a)
la forall a b. (a -> b) -> a -> b
$ forall a. XDR a => a -> String
xdrType forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> a
V.head forall a b. (a -> b) -> a -> b
$ forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'LT n (Vector a)
la
  xdrPut :: LengthArray 'LT n (Vector a) -> Put
xdrPut LengthArray 'LT n (Vector a)
la = do
    forall a. XDR a => a -> Put
xdrPut (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Vector a -> Int
V.length Vector a
a) :: XDR.Length)
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. XDR a => a -> Put
xdrPut Vector a
a
    where
    a :: Vector a
a = forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'LT n (Vector a)
la
  xdrGet :: Get (LengthArray 'LT n (Vector a))
xdrGet = forall (n :: Nat) a.
KnownNat n =>
(Length -> Get a) -> Get (LengthArray 'LT n a)
xdrGetBoundedArray forall a b. (a -> b) -> a -> b
$ \Length
l -> forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM (forall a b. (Integral a, Num b) => a -> b
fromIntegral Length
l) forall a. XDR a => Get a
xdrGet

instance KnownNat n => XDR (LengthArray 'EQ n BS.ByteString) where
  xdrType :: LengthArray 'EQ n ByteString -> String
xdrType LengthArray 'EQ n ByteString
o = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'EQ n a -> String -> String
fixedLength LengthArray 'EQ n ByteString
o String
"string"
  xdrPut :: LengthArray 'EQ n ByteString -> Put
xdrPut LengthArray 'EQ n ByteString
o =
    Length -> ByteString -> Put
xdrPutByteString (forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n)) forall a b. (a -> b) -> a -> b
$ forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'EQ n ByteString
o
  xdrGet :: Get (LengthArray 'EQ n ByteString)
xdrGet = forall a (o :: Ordering) (n :: Nat). a -> LengthArray o n a
unsafeLengthArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    Length -> Get ByteString
xdrGetByteString (forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n))

instance KnownNat n => XDR (LengthArray 'LT n BS.ByteString) where
  xdrType :: LengthArray 'LT n ByteString -> String
xdrType LengthArray 'LT n ByteString
o = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'LT n a -> String -> String
variableLength LengthArray 'LT n ByteString
o String
"string"
  xdrPut :: LengthArray 'LT n ByteString -> Put
xdrPut LengthArray 'LT n ByteString
o = do
    forall a. XDR a => a -> Put
xdrPut Length
l
    Length -> ByteString -> Put
xdrPutByteString Length
l ByteString
b
    where 
    l :: Length
l = ByteString -> Length
bsLength ByteString
b
    b :: ByteString
b = forall (o :: Ordering) (n :: Nat) a. LengthArray o n a -> a
unLengthArray LengthArray 'LT n ByteString
o
  xdrGet :: Get (LengthArray 'LT n ByteString)
xdrGet = forall (n :: Nat) a.
KnownNat n =>
(Length -> Get a) -> Get (LengthArray 'LT n a)
xdrGetBoundedArray Length -> Get ByteString
xdrGetByteString

instance KnownNat n => XDR (LengthArray 'EQ n OpaqueString) where
  xdrType :: LengthArray 'EQ n OpaqueString -> String
xdrType LengthArray 'EQ n OpaqueString
o = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'EQ n a -> String -> String
fixedLength LengthArray 'EQ n OpaqueString
o String
"opaque"
  xdrPut :: LengthArray 'EQ n OpaqueString -> Put
xdrPut = forall a. XDR a => a -> Put
xdrPut forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (o :: Ordering) (n :: Nat).
LengthArray o n OpaqueString -> LengthArray o n ByteString
unOpaqueLengthArray
  xdrGet :: Get (LengthArray 'EQ n OpaqueString)
xdrGet = forall (o :: Ordering) (n :: Nat).
LengthArray o n ByteString -> LengthArray o n OpaqueString
opaqueLengthArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. XDR a => Get a
xdrGet

instance KnownNat n => XDR (LengthArray 'LT n OpaqueString) where
  xdrType :: LengthArray 'LT n OpaqueString -> String
xdrType LengthArray 'LT n OpaqueString
o = forall (n :: Nat) a.
KnownNat n =>
LengthArray 'LT n a -> String -> String
variableLength LengthArray 'LT n OpaqueString
o String
"opaque"
  xdrPut :: LengthArray 'LT n OpaqueString -> Put
xdrPut = forall a. XDR a => a -> Put
xdrPut forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (o :: Ordering) (n :: Nat).
LengthArray o n OpaqueString -> LengthArray o n ByteString
unOpaqueLengthArray
  xdrGet :: Get (LengthArray 'LT n OpaqueString)
xdrGet = forall (o :: Ordering) (n :: Nat).
LengthArray o n ByteString -> LengthArray o n OpaqueString
opaqueLengthArray forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. XDR a => Get a
xdrGet

instance XDR () where
  xdrType :: () -> String
xdrType () = String
"void"
  xdrPut :: () -> Put
xdrPut () = forall (m :: * -> *) a. Monad m => a -> m a
return ()
  xdrGet :: Get ()
xdrGet = forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance (XDR a, XDR b) => XDR (a, b) where
  xdrType :: (a, b) -> String
xdrType (a
a, b
b) = forall a. XDR a => a -> String
xdrType a
a forall a. [a] -> [a] -> [a]
++ Char
'+' forall a. a -> [a] -> [a]
: forall a. XDR a => a -> String
xdrType b
b
  xdrPut :: (a, b) -> Put
xdrPut (a
a, b
b) = forall a. XDR a => a -> Put
xdrPut a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. XDR a => a -> Put
xdrPut b
b
  xdrGet :: Get (a, b)
xdrGet = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. XDR a => Get a
xdrGet forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. XDR a => Get a
xdrGet

instance (XDR a, XDR b, XDR c) => XDR (a, b, c) where
  xdrType :: (a, b, c) -> String
xdrType (a
a, b
b, c
c) = forall a. XDR a => a -> String
xdrType a
a forall a. [a] -> [a] -> [a]
++ Char
'+' forall a. a -> [a] -> [a]
: forall a. XDR a => a -> String
xdrType b
b forall a. [a] -> [a] -> [a]
++ Char
'+' forall a. a -> [a] -> [a]
: forall a. XDR a => a -> String
xdrType c
c
  xdrPut :: (a, b, c) -> Put
xdrPut (a
a, b
b, c
c) = forall a. XDR a => a -> Put
xdrPut a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. XDR a => a -> Put
xdrPut b
b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. XDR a => a -> Put
xdrPut c
c
  xdrGet :: Get (a, b, c)
xdrGet = (,,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. XDR a => Get a
xdrGet forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. XDR a => Get a
xdrGet forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. XDR a => Get a
xdrGet

instance (XDR a, XDR b, XDR c, XDR d) => XDR (a, b, c, d) where
  xdrType :: (a, b, c, d) -> String
xdrType (a
a, b
b, c
c, d
d) = forall a. XDR a => a -> String
xdrType a
a forall a. [a] -> [a] -> [a]
++ Char
'+' forall a. a -> [a] -> [a]
: forall a. XDR a => a -> String
xdrType b
b forall a. [a] -> [a] -> [a]
++ Char
'+' forall a. a -> [a] -> [a]
: forall a. XDR a => a -> String
xdrType c
c forall a. [a] -> [a] -> [a]
++ Char
'+' forall a. a -> [a] -> [a]
: forall a. XDR a => a -> String
xdrType d
d
  xdrPut :: (a, b, c, d) -> Put
xdrPut (a
a, b
b, c
c, d
d) = forall a. XDR a => a -> Put
xdrPut a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. XDR a => a -> Put
xdrPut b
b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. XDR a => a -> Put
xdrPut c
c forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. XDR a => a -> Put
xdrPut d
d
  xdrGet :: Get (a, b, c, d)
xdrGet = (,,,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. XDR a => Get a
xdrGet forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. XDR a => Get a
xdrGet forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. XDR a => Get a
xdrGet forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. XDR a => Get a
xdrGet

xdrSerialize :: XDR a => a -> BS.ByteString
xdrSerialize :: forall a. XDR a => a -> ByteString
xdrSerialize = Put -> ByteString
S.runPut forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDR a => a -> Put
xdrPut

xdrSerializeLazy :: XDR a => a -> BSL.ByteString
xdrSerializeLazy :: forall a. XDR a => a -> ByteString
xdrSerializeLazy = Put -> ByteString
S.runPutLazy forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. XDR a => a -> Put
xdrPut

-- |@"S.runGet' 'xdrGet'@
xdrDeserialize :: XDR a => BS.ByteString -> Either String a
xdrDeserialize :: forall a. XDR a => ByteString -> Either String a
xdrDeserialize = forall a. Get a -> ByteString -> Either String a
S.runGet forall a. XDR a => Get a
xdrGet

-- |@"S.runGetLazy' 'xdrGet'@
xdrDeserializeLazy :: XDR a => BSL.ByteString -> Either String a
xdrDeserializeLazy :: forall a. XDR a => ByteString -> Either String a
xdrDeserializeLazy = forall a. Get a -> ByteString -> Either String a
S.runGetLazy forall a. XDR a => Get a
xdrGet