{- |
Reading records from streams

This is still only for demonstration and might be of not much use
and you should not rely on the interface.
-}
module Data.Accessor.BinaryRead (
   Stream,
   C(any),
   ByteSource(readWord8),
   ByteStream(getWord8),
   ByteCompatible(toByte),
   Parser(Parser, runParser),
   field,
   record,
   ) where

import qualified Data.Accessor.Basic as Accessor
import Data.Accessor.ByteSource
         (ByteSource(..), ByteStream(..), ByteCompatible(..))

import qualified Control.Monad.Trans.State as State
import Control.Monad (liftM, )
import Data.Word (Word8, )
import Data.Char (chr, )

import Prelude hiding (any)


type Stream = [Word8]

class C a where
   any :: ByteSource source => source a

instance C Word8 where
   any :: forall (source :: * -> *). ByteSource source => source Word8
any = forall (source :: * -> *). ByteSource source => source Word8
readWord8

instance C Char where
   any :: forall (source :: * -> *). ByteSource source => source Char
any =
      forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall (source :: * -> *). ByteSource source => source Word8
readWord8

instance C Int where
   any :: forall (source :: * -> *). ByteSource source => source Int
any =
      do Word8
c0 <- forall (source :: * -> *). ByteSource source => source Word8
readWord8
         Word8
c1 <- forall (source :: * -> *). ByteSource source => source Word8
readWord8
         Word8
c2 <- forall (source :: * -> *). ByteSource source => source Word8
readWord8
         Word8
c3 <- forall (source :: * -> *). ByteSource source => source Word8
readWord8
         forall (m :: * -> *) a. Monad m => a -> m a
return
            (forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 (\Int
acc Int
d -> Int
accforall a. Num a => a -> a -> a
*Int
256forall a. Num a => a -> a -> a
+Int
d)
               (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (Integral a, Num b) => a -> b
fromIntegral [Word8
c0,Word8
c1,Word8
c2,Word8
c3]))


newtype Parser s r = Parser {forall s r. Parser s r -> (r, s) -> Maybe (r, s)
runParser :: (r, s) -> Maybe (r, s)}


field :: (ByteStream s, C a) =>
   Accessor.T r a -> Parser s r
field :: forall s a r. (ByteStream s, C a) => T r a -> Parser s r
field T r a
f =
   forall s r. ((r, s) -> Maybe (r, s)) -> Parser s r
Parser forall a b. (a -> b) -> a -> b
$
      forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (\r
r -> forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
State.runStateT forall a b. (a -> b) -> a -> b
$
         forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a
x -> forall r a. T r a -> a -> r -> r
Accessor.set T r a
f a
x r
r) forall a (source :: * -> *). (C a, ByteSource source) => source a
any)

record :: [Parser s r] -> Parser s r
record :: forall s r. [Parser s r] -> Parser s r
record [Parser s r]
ps =
   forall s r. ((r, s) -> Maybe (r, s)) -> Parser s r
Parser forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip (forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(>>=)) (forall a b. (a -> b) -> [a] -> [b]
map forall s r. Parser s r -> (r, s) -> Maybe (r, s)
runParser [Parser s r]
ps) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just

-- TODO: writer