packages feed

knob 0.2.1 → 0.2.2

raw patch · 2 files changed

+49/−38 lines, 2 filesdep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: bytestring

API changes (from Hackage documentation)

+ Data.Knob: data Device
+ Data.Knob: newDevice :: MonadIO m => Knob -> IOMode -> m Device

Files

knob.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: knob-version: 0.2.1+version: 0.2.2 license: MIT license-file: license.txt author: John Millikin <jmillikin@gmail.com>
lib/Data/Knob.hs view
@@ -31,6 +31,9 @@    , newFileHandle   , withFileHandle++  , Device+  , newDevice   ) where  import qualified Control.Concurrent.MVar as MVar@@ -48,6 +51,7 @@ import qualified GHC.IO.Exception as IO import qualified GHC.IO.Handle as IO import qualified System.IO as IO+import Data.Maybe (fromMaybe)  -- | A knob is a basic virtual file, which contains a byte buffer. A knob can -- have multiple 'IO.Handle's open to it, each of which behaves like a standard@@ -57,9 +61,51 @@ -- byte buffer. newtype Knob = Knob (MVar.MVar ByteString) +checkOffset :: Integer -> IO ()+checkOffset off = when (toInteger (maxBound :: Int) < off) (throwIO err) where+  err = IO.IOError Nothing IO.InvalidArgument "" "offset > (maxBound :: Int)" Nothing Nothing++newKnob :: MonadIO m => ByteString -> m Knob+newKnob bytes = do+  var <- liftIO (MVar.newMVar bytes)+  return (Knob var)++getContents :: MonadIO m => Knob -> m ByteString+getContents (Knob var) = liftIO (MVar.readMVar var)++setContents :: MonadIO m => Knob -> ByteString -> m ()+setContents (Knob var) bytes = liftIO (MVar.modifyMVar_ var (\_ -> return bytes))++-- | Create a new 'IO.Handle' pointing to a 'Knob'. This handle behaves like+-- a file-backed handle for most purposes.+newFileHandle :: MonadIO m+              => Knob+              -> String -- ^ Filename shown in error messages+              -> IO.IOMode -> m IO.Handle+newFileHandle knob name mode = liftIO $ do+  device <- newDevice knob mode+  IO.mkFileHandle device name mode Nothing IO.noNewlineTranslation++-- | See 'newFileHandle'.+withFileHandle :: MonadIO m+               => Knob+               -> String -- ^ Filename shown in error messages.+               -> IO.IOMode -> (IO.Handle -> IO a) -> m a+withFileHandle knob name mode io = liftIO (bracket (newFileHandle knob name mode) IO.hClose io)++-- | An IO device backed by a 'Knob'. You shouldn't usually use this type directly;+-- use 'newFileHandle' or 'withFileHandle' instead. data Device = Device IO.IOMode (MVar.MVar ByteString) (MVar.MVar Int)   deriving (Typeable) +newDevice :: MonadIO m => Knob -> IO.IOMode -> m Device+newDevice (Knob var) mode = liftIO $ do+  startPosition <- MVar.withMVar var $ \bytes -> return $ case mode of+    IO.AppendMode -> Data.ByteString.length bytes+    _ -> 0+  posVar <- MVar.newMVar startPosition+  pure $ Device mode var posVar+ instance IO.IODevice Device where   ready _ _ _ = return True   close _ = return ()@@ -87,13 +133,9 @@   getSize (Device _ var _) = do     bytes <- MVar.readMVar var     return (toInteger (Data.ByteString.length bytes))-  setSize dev size = setDeviceSize dev size+  setSize = setDeviceSize   devType _ = return IO.RegularFile -checkOffset :: Integer -> IO ()-checkOffset off = when (toInteger (maxBound :: Int) < off) (throwIO err) where-  err = IO.IOError Nothing IO.InvalidArgument "" "offset > (maxBound :: Int)" Nothing Nothing- setDeviceSize :: Device -> Integer -> IO () setDeviceSize (Device mode bytes_var _) size = checkSize >> setBytes where   intSize :: Int@@ -146,7 +188,7 @@    fillReadBuffer dev buf = do     (numRead, newBuf) <- IO.fillReadBuffer0 dev buf-    return (maybe 0 id numRead, newBuf)+    return (fromMaybe 0 numRead, newBuf)    fillReadBuffer0 (Device _ bytes_var pos_var) buf = do     MVar.withMVar bytes_var $ \bytes -> do@@ -177,34 +219,3 @@   flushWriteBuffer0 dev buf = do     newBuf <- IO.flushWriteBuffer dev buf     return (IO.bufR buf - IO.bufL buf, newBuf)--newKnob :: MonadIO m => ByteString -> m Knob-newKnob bytes = do-  var <- liftIO (MVar.newMVar bytes)-  return (Knob var)--getContents :: MonadIO m => Knob -> m ByteString-getContents (Knob var) = liftIO (MVar.readMVar var)--setContents :: MonadIO m => Knob -> ByteString -> m ()-setContents (Knob var) bytes = liftIO (MVar.modifyMVar_ var (\_ -> return bytes))---- | Create a new 'IO.Handle' pointing to a 'Knob'. This handle behaves like--- a file-backed handle for most purposes.-newFileHandle :: MonadIO m-              => Knob-              -> String -- ^ Filename shown in error messages-              -> IO.IOMode -> m IO.Handle-newFileHandle (Knob var) name mode = liftIO $ do-  startPosition <- MVar.withMVar var $ \bytes -> return $ case mode of-    IO.AppendMode -> Data.ByteString.length bytes-    _ -> 0-  posVar <- MVar.newMVar startPosition-  IO.mkFileHandle (Device mode var posVar) name mode Nothing IO.noNewlineTranslation---- | See 'newFileHandle'.-withFileHandle :: MonadIO m-               => Knob-               -> String -- ^ Filename shown in error messages.-               -> IO.IOMode -> (IO.Handle -> IO a) -> m a-withFileHandle knob name mode io = liftIO (bracket (newFileHandle knob name mode) IO.hClose io)