module System.IO.Streams.Binary
(
binaryFromStream
, binaryInputStream
, binaryToStream
, binaryOutputStream
, DecodeException(..)
) where
import Control.Exception (throw,Exception)
import Data.Binary (Binary,get,put)
import Data.Binary.Builder (Builder,toLazyByteString)
import Data.Binary.Get (runGetIncremental,
Decoder(..),
pushEndOfInput,
pushChunk,
ByteOffset)
import Data.Binary.Put (execPut)
import Data.ByteString (ByteString)
import qualified Data.ByteString as S
import Data.Typeable (Typeable)
import System.IO.Streams (makeInputStream,
makeOutputStream,
InputStream,
OutputStream,
write,
unRead)
import qualified System.IO.Streams as Stream
import System.IO.Streams.ByteString (writeLazyByteString)
data DecodeException = DecodeException ByteOffset String
deriving (Typeable)
instance Show DecodeException where
show (DecodeException offset message) =
"Decode exception, offset " ++ show offset ++ ":" ++ show message
instance Exception DecodeException
decodeFromStream :: Decoder a
-> InputStream ByteString
-> IO (Maybe a)
decodeFromStream decoder is =
Stream.read is >>=
maybe (return Nothing)
(\s -> if S.null s then go decoder else go $ pushChunk decoder s)
where go (Fail _ offset message) = throw $ DecodeException offset message
go (Done s _ x) =
do
if S.null s then return () else unRead s is
return $ Just x
go decoder' = Stream.read is >>=
maybe (go $ pushEndOfInput decoder')
(\s -> if S.null s then go decoder' else go $ pushChunk decoder' s)
binaryFromStream :: Binary a
=> InputStream ByteString
-> IO (Maybe a)
binaryFromStream = decodeFromStream (runGetIncremental get)
binaryInputStream :: Binary a
=> InputStream ByteString
-> IO (InputStream a)
binaryInputStream = makeInputStream . binaryFromStream
binaryToStream :: Binary a
=> OutputStream ByteString
-> Maybe a
-> IO ()
binaryToStream os Nothing = write Nothing os
binaryToStream os (Just x) = writeLazyByteString (toLazyByteString $ execPut $ put x) os
binaryOutputStream :: Binary a
=> OutputStream ByteString
-> IO (OutputStream a)
binaryOutputStream = makeOutputStream . binaryToStream