-- Copyright : (C) 2009 Corey O'Connor -- License : BSD-style (see the file LICENSE) {-# LANGUAGE MagicHash #-} module Bind.Marshal.Verify.Dynamic where import Bind.Marshal.Prelude import Bind.Marshal.Action.Base import Bind.Marshal.Action.Dynamic import Bind.Marshal.Action.Monad import Control.Applicative import Data.IORef import GHC.Exts import GHC.Prim import System.IO import Verify data NopDelegate = NopDelegate instance BufferDelegate NopDelegate where gen_region 0 NopDelegate = returnM $! BDIter 0 0 NopDelegate nullAddr# nullAddr# gen_region _size NopDelegate = fail "NopDelegate can only generate 0 sized buffers" finalize_region bd_iter | bytes_final bd_iter == 0 = returnM (buffer_delegate bd_iter) | otherwise = fail "NopDelegate can only finalize 0 sized buffers" data LoggingDelegate sub_delegate where LoggingDelegate :: BufferDelegate sub_delegate => [ProducerLogEntry] -> sub_delegate -> LoggingDelegate sub_delegate data ProducerLogEntry = GenBuffer Size Size -- Requested miminum size. Max bytes avail of generated buffer. | FinalizeBuffer Size -- Actual finalize size. deriving ( Show, Eq ) logging_buffer_delegate :: BufferDelegate bd => bd -> IO (LoggingDelegate bd) logging_buffer_delegate sub_delegate = returnM $! LoggingDelegate [] sub_delegate dump_request_log :: LoggingDelegate sub_delegate -> IO () dump_request_log (LoggingDelegate log _sub) = do mapM_ (\s -> log_out $ show s) log :: IO () instance BufferDelegate sub_delegate => BufferDelegate (LoggingDelegate sub_delegate) where gen_region size (LoggingDelegate log sub_p) = do bd_iter <- gen_region size sub_p let sub_p' = buffer_delegate bd_iter let log' = log ++ [GenBuffer size (max_bytes_avail bd_iter) ] returnM $! bd_iter { buffer_delegate = LoggingDelegate log' sub_p' } :: IO (BDIter (LoggingDelegate sub_delegate)) finalize_region bd_iter@(BDIter _ _ bd s p) = do let !(LoggingDelegate log sub_p) = bd log' = log ++ [FinalizeBuffer (I# (minusAddr# p s))] sub_p' <- finalize_region (bd_iter {buffer_delegate = sub_p}) returnM $! LoggingDelegate log' sub_p' :: IO (LoggingDelegate sub_delegate) verify_logged_requests :: LoggingDelegate sub_delegate -> [ProducerLogEntry] -> IO () verify_logged_requests p@(LoggingDelegate actual _sub_p) expected = do if actual == expected then returnM () else do fail $ "expected is:\n" ++ show expected :: IO ()