ByteString.hs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. {-# LANGUAGE OverloadedStrings #-}
  2. -- | UniformIO on memory
  3. module System.IO.Uniform.ByteString (
  4. ByteStringIO,
  5. withByteStringIO, withByteStringIO'
  6. ) where
  7. import System.IO.Uniform
  8. import Data.ByteString (ByteString)
  9. import qualified Data.ByteString as BS
  10. import qualified Data.ByteString.Lazy as LBS
  11. import qualified Data.ByteString.Builder as BSBuild
  12. import Control.Concurrent.MVar
  13. --import Data.Default.Class
  14. --import System.Posix.Types (Fd(..))
  15. {- |
  16. Wrapper that does UniformIO that reads and writes on the memory.
  17. Input and output may be queried and replaced during the execution of
  18. the target, with obviously undefined results in case of concurrent
  19. execution.
  20. -}
  21. data ByteStringIO = ByteStringIO {bsioinput :: MVar ByteString, bsiooutput :: MVar BSBuild.Builder}
  22. instance UniformIO ByteStringIO where
  23. uRead s n = do
  24. i <- takeMVar . bsioinput $ s
  25. let (r, i') = BS.splitAt n i
  26. putMVar (bsioinput s) i'
  27. return r
  28. uPut s t = do
  29. o <- takeMVar . bsiooutput $ s
  30. let o' = mappend o $ BSBuild.byteString t
  31. putMVar (bsiooutput s) o'
  32. uClose _ = return ()
  33. startTls _ = return
  34. isSecure _ = True
  35. isEOF t = withMVar (bsioinput t) $ return . BS.null
  36. -- | withByteStringIO' input f
  37. -- Runs f with a ByteStringIO that has the given input, returns f's output and
  38. -- the ByteStringIO output.
  39. withByteStringIO' :: ByteString -> (ByteStringIO -> IO a) -> IO (a, LBS.ByteString)
  40. withByteStringIO' input f = do
  41. ivar <- newMVar input
  42. ovar <- newMVar . BSBuild.byteString $ BS.empty
  43. let bsio = ByteStringIO ivar ovar
  44. a <- f bsio
  45. out <- takeMVar . bsiooutput $ bsio
  46. return (a, BSBuild.toLazyByteString out)
  47. -- | The same as withByteStringIO', but returns an strict ByteString
  48. withByteStringIO :: ByteString -> (ByteStringIO -> IO a) -> IO (a, ByteString)
  49. withByteStringIO input f = do
  50. (a, t) <- withByteStringIO' input f
  51. return (a, LBS.toStrict t)