bind-marshal-0.1: test/FLVHeader/Data.hs
-- Copyright : (C) 2009 Corey O'Connor
-- License : BSD-style (see the file LICENSE)
{-# LANGUAGE ImplicitPrelude #-}
{-# LANGUAGE NoRebindableSyntax #-}
module FLVHeader.Data
where
import Bind.Marshal.Verify
import Control.DeepSeq
import Data.Word
import Foreign.Ptr
import Foreign.Storable
import System.IO
data FLVHeader = FLVHeader
{ version :: !Word8
, has_audio :: !Bool
, has_video :: !Bool
, header_size :: !Word32
}
deriving ( Show, Eq )
instance Arbitrary FLVHeader where
arbitrary = do
let version = 1
has_audio <- arbitrary
has_video <- arbitrary
let has_audio' = if (not has_audio) && (not has_video) then True else has_audio
let header_size = 9
return $! FLVHeader version has_audio' has_video header_size
instance NFData FLVHeader where
rnf (FLVHeader !version !has_audio !has_video !header_size)
= deepseq version
$! deepseq has_audio
$! deepseq has_video
$! rnf header_size
instance Storable FLVHeader where
sizeOf _ = 9
alignment _ = 1
{-# INLINE peek #-}
peek p = do
-- First 3 bytes should be ['F','L','V'] in ASCII
'F' <- peek_char8 (castPtr p)
let p1 = plusPtr p 1
'L' <- peek_char8 p1
let p2 = plusPtr p1 1
'V' <- peek_char8 p2
let p3 = plusPtr p2 1
version :: Word8 <- peek p3
let p4 = plusPtr p3 1
flags :: Word8 <- peek p4
let p5 = plusPtr p4 1
header_size :: Word32 <- peek p5
let ( has_audio, has_video ) = case flags of
1 -> ( True, False )
4 -> ( False, True )
5 -> ( True, True )
return $! FLVHeader version has_audio has_video header_size
{-# INLINE poke #-}
poke p v = do
-- First 3 bytes should be ['F','L','V'] in ASCII
poke_char8 (castPtr p) 'F'
let p1 = plusPtr p 1
poke_char8 p1 'L'
let p2 = plusPtr p1 1
poke_char8 p2 'V'
let p3 = plusPtr p2 1
poke p3 $! version v
let p4 = plusPtr p3 1
case ( has_audio v, has_video v ) of
( True, False ) -> poke p4 ( 1 :: Word8 )
( False, True ) -> poke p4 ( 4 :: Word8 )
( True, True ) -> poke p4 ( 5 :: Word8 )
let p5 = plusPtr p4 1
poke p5 $! header_size v
return ()
peek_char8 :: Ptr Word8 -> IO Char
peek_char8 p = do
v :: Word8 <- peek p
return $! toEnum $! fromEnum v
poke_char8 :: Ptr Word8 -> Char -> IO ()
poke_char8 p c = do
let v :: Word8 = toEnum $! fromEnum c
poke p v