2 ( writeBinary, readBinary
18import Control.Exception (catch)
19import qualified Data.Binary as Binary
20import qualified Data.ByteString as BS
21import qualified Data.ByteString.Internal as BS
22import qualified Data.ByteString.Builder as B
23import qualified Data.ByteString.Builder.Extra as B (defaultChunkSize)
24import qualified Foreign.ForeignPtr as FPtr
25import GHC.IO.Exception (IOException, IOErrorType(InvalidArgument))
26import qualified System.Directory as Dir
27import System.FilePath ((</>))
28import qualified System.FilePath as FP
29import qualified System.IO as IO
30import System.IO.Error (ioeGetErrorType, annotateIOError, modifyIOError)
37writeBinary :: (Binary.Binary a) => FilePath -> a -> IO ()
38writeBinary path value =
39 do let dir = FP.dropFileName path
40 Dir.createDirectoryIfMissing True dir
41 Binary.encodeFile path value
44readBinary :: (Binary.Binary a) => FilePath -> IO (Maybe a)
46 do exists_ <- Dir.doesFileExist path
50 do result <- Binary.decodeFileOrFail path
52 Left _ -> return Nothing
53 Right a -> return (Just a)
60writeUtf8 :: FilePath -> BS.ByteString -> IO ()
61writeUtf8 filePath content =
62 withUtf8 filePath IO.WriteMode $ \handle ->
63 BS.hPut handle content
66withUtf8 :: FilePath -> IO.IOMode -> (IO.Handle -> IO a) -> IO a
67withUtf8 filePath mode callback =
68 IO.withFile filePath mode $ \handle ->
69 do IO.hSetEncoding handle IO.utf8
77readUtf8 :: FilePath -> IO BS.ByteString
79 withUtf8 filePath IO.ReadMode $ \handle ->
80 modifyIOError (encodingError filePath) $
81 do fileSize <- catch (IO.hFileSize handle) useZeroIfNotRegularFile
82 let readSize = max 0 (fromIntegral fileSize) + 1
83 hGetContentsSizeHint handle readSize (max 255 readSize)
86useZeroIfNotRegularFile :: IOException -> IO Integer
87useZeroIfNotRegularFile _ =
91hGetContentsSizeHint :: IO.Handle -> Int -> Int -> IO BS.ByteString
92hGetContentsSizeHint handle =
95 readChunks chunks readSize incrementSize =
96 do fp <- BS.mallocByteString readSize
97 readCount <- FPtr.withForeignPtr fp $ \buf -> IO.hGetBuf handle buf readSize
98 let chunk = BS.PS fp 0 readCount
99 if readCount < readSize && readSize > 0
100 then return $! BS.concat (reverse (chunk:chunks))
101 else readChunks (chunk:chunks) incrementSize (min 32752 (readSize + incrementSize))
104encodingError :: FilePath -> IOError -> IOError
105encodingError filePath ioErr =
106 case ioeGetErrorType ioErr of
109 (userError "Bad encoding; the file must be valid UTF-8")
122writeBuilder :: FilePath -> B.Builder -> IO ()
123writeBuilder path builder =
124 IO.withBinaryFile path IO.WriteMode $ \handle ->
125 do IO.hSetBuffering handle (IO.BlockBuffering Nothing)
126 B.hPutBuilder handle builder
134 Writer (IO.Handle -> IO ())
137put :: FilePath -> Writer -> IO ()
138put path (Writer callback) =
139 IO.withBinaryFile path IO.WriteMode callback
142putByteString :: BS.ByteString -> Writer
148putBuilder :: B.Builder -> Writer
151 B.hPutBuilder handle builder
154putFile :: FilePath -> Writer
157 IO.withBinaryFile path IO.ReadMode $ \source ->
161putHelp :: IO.Handle -> IO.Handle -> IO ()
163 do chunk <- BS.hGet source B.defaultChunkSize
167 do BS.hPut sink chunk
175exists :: FilePath -> IO Bool
184remove :: FilePath -> IO ()
186 do exists_ <- Dir.doesFileExist filePath
188 then Dir.removeFile filePath
192removeDir :: FilePath -> IO ()
194 do exists_ <- Dir.doesDirectoryExist path
196 then Dir.removeDirectoryRecursive path
204find :: FilePath -> IO (Maybe FilePath)
206 do subDir <- Dir.getCurrentDirectory
207 findHelp name (FP.splitDirectories subDir)
210findHelp :: FilePath -> [String] -> IO (Maybe FilePath)
216 do exists_ <- Dir.doesFileExist (FP.joinPath dirs </> name)
218 then return (Just (FP.joinPath dirs))
219 else findHelp name (init dirs)
226andM :: (Monad m) => [m Bool] -> m Bool
232 check : otherChecks ->
234 if bool then andM otherChecks else return False
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list