{-# LANGUAGE CPP #-} {-# LANGUAGE TypeFamilies #-} module Data.IOData where import Control.Monad (liftM) import Control.Monad.IO.Class import qualified Data.ByteString as ByteString import qualified Data.ByteString.Char8 as ByteString8 import qualified Data.ByteString.Lazy as LByteString import Data.ByteString.Lazy.Internal (defaultChunkSize) import Data.Sequences (IsSequence) import Data.Sequences.Lazy (fromStrict) import qualified Data.Text as Text import qualified Data.Text.IO as Text import qualified Data.Text.Lazy as LText import qualified Data.Text.Lazy.IO as LText import Prelude (Char, flip, ($), (.), FilePath) import qualified Prelude import System.IO (Handle) import qualified System.IO #if !MIN_VERSION_text(0, 11, 3) import Control.Exception (handle, throwIO) import System.IO.Error (isEOFError) #endif -- | Data which can be read to and from files and handles. -- -- Note that, for lazy sequences, these operations may perform -- lazy I\/O. class IsSequence a => IOData a where readFile :: MonadIO m => FilePath -> m a writeFile :: MonadIO m => FilePath -> a -> m () getLine :: MonadIO m => m a hGetContents :: MonadIO m => Handle -> m a hGetLine :: MonadIO m => Handle -> m a hPut :: MonadIO m => Handle -> a -> m () hPutStrLn :: MonadIO m => Handle -> a -> m () hGetChunk :: MonadIO m => Handle -> m a instance IOData ByteString.ByteString where readFile = liftIO . ByteString.readFile writeFile fp = liftIO . ByteString.writeFile fp getLine = liftIO ByteString.getLine hGetContents = liftIO . ByteString.hGetContents hGetLine = liftIO . ByteString.hGetLine hPut h = liftIO . ByteString.hPut h hPutStrLn h = liftIO . ByteString8.hPutStrLn h hGetChunk = liftIO . flip ByteString.hGetSome defaultChunkSize instance IOData LByteString.ByteString where readFile = liftIO . LByteString.readFile writeFile fp = liftIO . LByteString.writeFile fp getLine = liftM fromStrict (liftIO ByteString.getLine) hGetContents = liftIO . LByteString.hGetContents hGetLine = liftM fromStrict . liftIO . ByteString.hGetLine hPut h = liftIO . LByteString.hPut h hPutStrLn h lbs = liftIO $ do LByteString.hPutStr h lbs ByteString8.hPutStrLn h ByteString.empty hGetChunk = liftM fromStrict . hGetChunk instance IOData Text.Text where readFile = liftIO . Text.readFile writeFile fp = liftIO . Text.writeFile fp getLine = liftIO Text.getLine hGetContents = liftIO . Text.hGetContents hGetLine = liftIO . Text.hGetLine hPut h = liftIO . Text.hPutStr h hPutStrLn h = liftIO . Text.hPutStrLn h #if MIN_VERSION_text(0, 11, 3) hGetChunk = liftIO . Text.hGetChunk #else -- Dangerously inefficient! hGetChunk = liftIO . handleEOF . liftM Text.singleton . System.IO.hGetChar where handleEOF = handle $ \e -> if isEOFError e then Prelude.return Text.empty else throwIO e #endif instance IOData LText.Text where readFile = liftIO . LText.readFile writeFile fp = liftIO . LText.writeFile fp getLine = liftIO LText.getLine hGetContents = liftIO . LText.hGetContents hGetLine = liftIO . LText.hGetLine hPut h = liftIO . LText.hPutStr h hPutStrLn h = liftIO . LText.hPutStrLn h hGetChunk = liftM fromStrict . hGetChunk instance (Char ~ c) => IOData [c] where readFile = liftIO . Prelude.readFile writeFile fp = liftIO . Prelude.writeFile fp getLine = liftIO Prelude.getLine hGetContents = liftIO . System.IO.hGetContents hGetLine = liftIO . System.IO.hGetLine hPut h = liftIO . System.IO.hPutStr h hPutStrLn h = liftIO . System.IO.hPutStrLn h hGetChunk = liftM Text.unpack . hGetChunk