{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
module Raaz.Core.Encode.Internal
( Encodable(..), Format(..)
) where
import Data.Maybe
import Data.ByteString (ByteString)
import Data.ByteString.Internal (unsafeCreate)
import Data.String
import Data.Word
import Foreign.Ptr
import Prelude hiding (length)
import System.IO.Unsafe (unsafePerformIO)
import Raaz.Core.Types.Endian
import Raaz.Core.Types.Pointer
import Raaz.Core.Util.ByteString(length, withByteString)
class Encodable a where
toByteString :: a -> ByteString
fromByteString :: ByteString -> Maybe a
unsafeFromByteString :: ByteString -> a
default toByteString :: EndianStore a => a -> ByteString
toByteString a
w = Int -> (Ptr Word8 -> IO ()) -> ByteString
unsafeCreate (BYTES Int -> Int
forall a. Enum a => a -> Int
fromEnum (BYTES Int -> Int) -> BYTES Int -> Int
forall a b. (a -> b) -> a -> b
$ Proxy a -> BYTES Int
forall a. Storable a => Proxy a -> BYTES Int
sizeOf (a -> Proxy a
forall a. a -> Proxy a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
w)) Ptr Word8 -> IO ()
forall {a}. Ptr a -> IO ()
putit
where putit :: Ptr a -> IO ()
putit Ptr a
ptr = Ptr a -> a -> IO ()
forall w. EndianStore w => Ptr w -> w -> IO ()
store (Ptr a -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr) a
w
default fromByteString :: EndianStore a => ByteString -> Maybe a
fromByteString ByteString
bs | Proxy a -> BYTES Int
forall a. Storable a => Proxy a -> BYTES Int
sizeOf Proxy a
proxy BYTES Int -> BYTES Int -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString -> BYTES Int
length ByteString
bs = a -> Maybe a
forall a. a -> Maybe a
Just a
w
| Bool
otherwise = Maybe a
forall a. Maybe a
Nothing
where w :: a
w = IO a -> a
forall a. IO a -> a
unsafePerformIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ ByteString -> (Ptr Any -> IO a) -> IO a
forall something a. ByteString -> (Ptr something -> IO a) -> IO a
withByteString ByteString
bs (Ptr a -> IO a
forall w. EndianStore w => Ptr w -> IO w
load (Ptr a -> IO a) -> (Ptr Any -> Ptr a) -> Ptr Any -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Any -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr)
proxy :: Proxy a
proxy = a -> Proxy a
forall a. a -> Proxy a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
w
unsafeFromByteString = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"fromByteString error") (Maybe a -> a) -> (ByteString -> Maybe a) -> ByteString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Maybe a
forall a. Encodable a => ByteString -> Maybe a
fromByteString
instance Encodable Word8
instance Encodable (LE Word32)
instance Encodable (LE Word64)
instance Encodable (BE Word32)
instance Encodable (BE Word64)
instance Encodable ()
instance Encodable ByteString where
toByteString :: ByteString -> ByteString
toByteString = ByteString -> ByteString
forall a. a -> a
id
{-# INLINE toByteString #-}
fromByteString :: ByteString -> Maybe ByteString
fromByteString = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just
{-# INLINE fromByteString #-}
unsafeFromByteString :: ByteString -> ByteString
unsafeFromByteString = ByteString -> ByteString
forall a. a -> a
id
{-# INLINE unsafeFromByteString #-}
instance Encodable a => Encodable (BYTES a) where
toByteString :: BYTES a -> ByteString
toByteString (BYTES a
a) = a -> ByteString
forall a. Encodable a => a -> ByteString
toByteString a
a
fromByteString :: ByteString -> Maybe (BYTES a)
fromByteString = (a -> BYTES a) -> Maybe a -> Maybe (BYTES a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> BYTES a
forall a. a -> BYTES a
BYTES (Maybe a -> Maybe (BYTES a))
-> (ByteString -> Maybe a) -> ByteString -> Maybe (BYTES a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Maybe a
forall a. Encodable a => ByteString -> Maybe a
fromByteString
unsafeFromByteString :: ByteString -> BYTES a
unsafeFromByteString = a -> BYTES a
forall a. a -> BYTES a
BYTES (a -> BYTES a) -> (ByteString -> a) -> ByteString -> BYTES a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> a
forall a. Encodable a => ByteString -> a
unsafeFromByteString
class (IsString fmt, Show fmt, Encodable fmt) => Format fmt where
encodeByteString :: ByteString -> fmt
decodeFormat :: fmt -> ByteString
instance Format ByteString where
encodeByteString :: ByteString -> ByteString
encodeByteString = ByteString -> ByteString
forall a. a -> a
id
{-# INLINE encodeByteString #-}
decodeFormat :: ByteString -> ByteString
decodeFormat = ByteString -> ByteString
forall a. a -> a
id
{-# INLINE decodeFormat #-}