module Sound.Sox.Signal.List (
writeFile, put,
withReadFile, getContents,
ReadException, IOReadException,
) where
import qualified Control.Monad.Exception.Synchronous as Sync
import qualified Control.Monad.Exception.Asynchronous as Async
import Control.Monad.Trans.Class (lift, )
import Foreign.Storable (Storable (..), )
import Foreign (Ptr, alloca, )
import System.IO (withBinaryFile, IOMode(WriteMode,ReadMode), Handle, hPutBuf, hGetBuf, )
import Control.Exception.Extensible (SomeException, try, )
import Control.Monad (liftM)
import System.IO.Unsafe (unsafeInterleaveIO, )
import Prelude hiding (writeFile, readFile, getContents, )
writeFile :: Storable a => FilePath -> [a] -> IO ()
writeFile :: forall a. Storable a => FilePath -> [a] -> IO ()
writeFile FilePath
fileName [a]
signal =
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile FilePath
fileName IOMode
WriteMode (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Storable a => Handle -> [a] -> IO ()
put [a]
signal)
put :: Storable a => Handle -> [a] -> IO ()
put :: forall a. Storable a => Handle -> [a] -> IO ()
put Handle
h [a]
signal =
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$
\Ptr a
p -> forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a. Storable a => Handle -> Ptr a -> a -> IO ()
putFrame Handle
h Ptr a
p) [a]
signal
putFrame :: Storable a => Handle -> Ptr a -> a -> IO ()
putFrame :: forall a. Storable a => Handle -> Ptr a -> a -> IO ()
putFrame Handle
h Ptr a
p a
n =
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
p a
n forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Handle -> Ptr a -> Int -> IO ()
hPutBuf Handle
h Ptr a
p (forall a. Storable a => a -> Int
sizeOf a
n)
data ReadException =
BrokenFrame
deriving (Int -> ReadException -> ShowS
[ReadException] -> ShowS
ReadException -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [ReadException] -> ShowS
$cshowList :: [ReadException] -> ShowS
show :: ReadException -> FilePath
$cshow :: ReadException -> FilePath
showsPrec :: Int -> ReadException -> ShowS
$cshowsPrec :: Int -> ReadException -> ShowS
Show, ReadException -> ReadException -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReadException -> ReadException -> Bool
$c/= :: ReadException -> ReadException -> Bool
== :: ReadException -> ReadException -> Bool
$c== :: ReadException -> ReadException -> Bool
Eq, Int -> ReadException
ReadException -> Int
ReadException -> [ReadException]
ReadException -> ReadException
ReadException -> ReadException -> [ReadException]
ReadException -> ReadException -> ReadException -> [ReadException]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ReadException -> ReadException -> ReadException -> [ReadException]
$cenumFromThenTo :: ReadException -> ReadException -> ReadException -> [ReadException]
enumFromTo :: ReadException -> ReadException -> [ReadException]
$cenumFromTo :: ReadException -> ReadException -> [ReadException]
enumFromThen :: ReadException -> ReadException -> [ReadException]
$cenumFromThen :: ReadException -> ReadException -> [ReadException]
enumFrom :: ReadException -> [ReadException]
$cenumFrom :: ReadException -> [ReadException]
fromEnum :: ReadException -> Int
$cfromEnum :: ReadException -> Int
toEnum :: Int -> ReadException
$ctoEnum :: Int -> ReadException
pred :: ReadException -> ReadException
$cpred :: ReadException -> ReadException
succ :: ReadException -> ReadException
$csucc :: ReadException -> ReadException
Enum)
type IOReadException =
Either ReadException SomeException
withReadFile :: Storable a =>
FilePath ->
(Async.Exceptional IOReadException [a] -> IO b) ->
IO b
withReadFile :: forall a b.
Storable a =>
FilePath -> (Exceptional IOReadException [a] -> IO b) -> IO b
withReadFile FilePath
fileName Exceptional IOReadException [a] -> IO b
act =
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile FilePath
fileName IOMode
ReadMode forall a b. (a -> b) -> a -> b
$ \Handle
sig ->
forall a.
Storable a =>
Handle -> IO (Exceptional IOReadException [a])
getContents Handle
sig forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Exceptional IOReadException [a] -> IO b
act
getContents :: Storable a =>
Handle -> IO (Async.Exceptional IOReadException [a])
getContents :: forall a.
Storable a =>
Handle -> IO (Exceptional IOReadException [a])
getContents Handle
h =
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$
\Ptr a
p ->
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\(Async.Exceptional (Just Maybe IOReadException
e) [a]
a) -> forall e a. Maybe e -> a -> Exceptional e a
Async.Exceptional Maybe IOReadException
e [a]
a) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) e b a.
Monad m =>
(m (Exceptional e b) -> m (Exceptional e b))
-> (a -> b -> b) -> b -> ExceptionalT e m a -> m (Exceptional e b)
Async.manySynchronousT
forall a. IO a -> IO a
unsafeInterleaveIO
(:) [] (forall a.
Storable a =>
Handle -> Ptr a -> ExceptionalT (Maybe IOReadException) IO a
getFrame Handle
h Ptr a
p)
getFrame :: Storable a =>
Handle -> Ptr a ->
Sync.ExceptionalT (Maybe IOReadException) IO a
getFrame :: forall a.
Storable a =>
Handle -> Ptr a -> ExceptionalT (Maybe IOReadException) IO a
getFrame Handle
h Ptr a
p =
do let getSize :: Storable a => a -> Ptr a -> Int
getSize :: forall a. Storable a => a -> Ptr a -> Int
getSize a
dummy Ptr a
_ = forall a. Storable a => a -> Int
sizeOf a
dummy
size :: Int
size = forall a. Storable a => a -> Ptr a -> Int
getSize forall a. HasCallStack => a
undefined Ptr a
p
Int
cnt <-
forall (m :: * -> *) e0 e1 a.
Monad m =>
(e0 -> e1) -> ExceptionalT e0 m a -> ExceptionalT e1 m a
Sync.mapExceptionT (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e a.
Monad m =>
m (Either e a) -> ExceptionalT e m a
Sync.fromEitherT forall a b. (a -> b) -> a -> b
$
forall e a. Exception e => IO a -> IO (Either e a)
try forall a b. (a -> b) -> a -> b
$ forall a. Handle -> Ptr a -> Int -> IO Int
hGetBuf Handle
h Ptr a
p Int
size
forall (m :: * -> *) e. Monad m => e -> Bool -> ExceptionalT e m ()
Sync.assertT forall a. Maybe a
Nothing (Int
cnt forall a. Ord a => a -> a -> Bool
> Int
0)
forall (m :: * -> *) e. Monad m => e -> Bool -> ExceptionalT e m ()
Sync.assertT (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left ReadException
BrokenFrame) (Int
cnt forall a. Eq a => a -> a -> Bool
== Int
size)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Ptr a -> IO a
peek Ptr a
p