file-io (empty) → 0.1.0.0
raw patch · 7 files changed
+331/−0 lines, 7 filesdep +Win32dep +basedep +bytestring
Dependencies added: Win32, base, bytestring, filepath, unix
Files
- CHANGELOG.md +5/−0
- System/File/Common.hs +82/−0
- System/File/OsPath.hs +30/−0
- System/File/PlatformPath.hs +28/−0
- System/File/Posix.hs +32/−0
- System/File/Windows.hs +111/−0
- file-io.cabal +43/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for file-io++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ System/File/Common.hs view
@@ -0,0 +1,82 @@++-- | Like 'openFile', but open the file in binary mode.+-- On Windows, reading a file in text mode (which is the default)+-- will translate CRLF to LF, and writing will translate LF to CRLF.+-- This is usually what you want with text files. With binary files+-- this is undesirable; also, as usual under Microsoft operating systems,+-- text mode treats control-Z as EOF. Binary mode turns off all special+-- treatment of end-of-line and end-of-file characters.+-- (See also 'System.IO.hSetBinaryMode'.)++-- On POSIX systems, 'openBinaryFile' is an /interruptible operation/ as+-- described in "Control.Exception".+openBinaryFile :: FILE_PATH -> IOMode -> IO Handle+openBinaryFile fp iomode = do+ h <- openFile fp iomode+ hSetBinaryMode h True+ pure h++-- | Run an action on a file.+--+-- The 'Handle' is automatically closed afther the action.+withFile :: FILE_PATH -> IOMode -> (Handle -> IO r) -> IO r+withFile fp iomode action = bracket+ (openFile fp iomode)+ hClose+ action++withBinaryFile :: FILE_PATH -> IOMode -> (Handle -> IO r) -> IO r+withBinaryFile fp iomode action = bracket+ (openBinaryFile fp iomode)+ hClose+ action++-- | Run an action on a file.+--+-- The 'Handle' is not automatically closed to allow lazy IO. Use this+-- with caution.+withFile'+ :: FILE_PATH -> IOMode -> (Handle -> IO r) -> IO r+withFile' fp iomode action = do+ h <- openFile fp iomode+ action h++withBinaryFile'+ :: FILE_PATH -> IOMode -> (Handle -> IO r) -> IO r+withBinaryFile' fp iomode action = do+ h <- openBinaryFile fp iomode+ action h++-- | The 'readFile' function reads a file and returns the contents of the file+-- as a 'ByteString'. The file is read lazily, on demand.+readFile :: FILE_PATH -> IO BSL.ByteString+readFile fp = withFile' fp ReadMode BSL.hGetContents++-- | The 'readFile'' function reads a file and returns the contents of the file+-- as a 'ByteString'. The file is fully read before being returned.+readFile'+ :: FILE_PATH -> IO BS.ByteString+readFile' fp = withFile fp ReadMode BS.hGetContents++-- | The computation 'writeFile' @file str@ function writes the lazy 'ByteString' @str@,+-- to the file @file@.+writeFile :: FILE_PATH -> BSL.ByteString -> IO ()+writeFile fp contents = withFile fp WriteMode (`BSL.hPut` contents)++-- | The computation 'writeFile' @file str@ function writes the strict 'ByteString' @str@,+-- to the file @file@.+writeFile'+ :: FILE_PATH -> BS.ByteString -> IO ()+writeFile' fp contents = withFile fp WriteMode (`BS.hPut` contents)++-- | The computation 'appendFile' @file str@ function appends the lazy 'ByteString' @str@,+-- to the file @file@.+appendFile :: FILE_PATH -> BSL.ByteString -> IO ()+appendFile fp contents = withFile fp AppendMode (`BSL.hPut` contents)++-- | The computation 'appendFile' @file str@ function appends the strict 'ByteString' @str@,+-- to the file @file@.+appendFile'+ :: FILE_PATH -> BS.ByteString -> IO ()+appendFile' fp contents = withFile fp AppendMode (`BS.hPut` contents)+
+ System/File/OsPath.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE CPP #-}++module System.File.OsPath where++#if defined(mingw32_HOST_OS) || defined(__MINGW32__)+#define CTOR WS+import qualified System.File.Windows as P+#else+#define CTOR PS+import qualified System.File.Posix as P+#endif++import Control.Exception (bracket)+import System.IO (IOMode(..), Handle, hSetBinaryMode, hClose)+import System.OsPath+import System.OsString.Internal.Types++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL++#define FILE_PATH OsPath+#include "Common.hs"++-- | Open a file and return the 'Handle'.+openFile :: OsPath -> IOMode -> IO Handle+openFile (OsString fp) = P.openFile fp++-- | Open an existing file and return the 'Handle'.+openExistingFile :: OsPath -> IOMode -> IO Handle+openExistingFile (OsString fp) = P.openExistingFile fp
+ System/File/PlatformPath.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE CPP #-}++module System.File.PlatformPath where++#if defined(mingw32_HOST_OS) || defined(__MINGW32__)+import qualified System.File.Windows as P+#else+import qualified System.File.Posix as P+#endif++import Control.Exception (bracket)+import System.IO (IOMode(..), Handle, hSetBinaryMode, hClose)+import System.OsPath.Types++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL++#define FILE_PATH PlatformPath+#include "Common.hs"++-- | Open a file and return the 'Handle'.+openFile :: PlatformPath -> IOMode -> IO Handle+openFile fp = P.openFile fp++-- | Open an existing file and return the 'Handle'.+openExistingFile :: PlatformPath -> IOMode -> IO Handle+openExistingFile fp = P.openExistingFile fp+
+ System/File/Posix.hs view
@@ -0,0 +1,32 @@+module System.File.Posix where++import System.IO (IOMode(..), Handle)+import System.Posix.IO.PosixString+ ( defaultFileFlags,+ fdToHandle,+ openFd,+ OpenFileFlags(noctty, nonBlock, creat, append, trunc),+ OpenMode(ReadWrite, ReadOnly, WriteOnly) )+import System.OsPath.Posix ( PosixPath )++-- | Open a file and return the 'Handle'.+openFile :: PosixPath -> IOMode -> IO Handle+openFile fp iomode = fdToHandle =<< case iomode of+ ReadMode -> open ReadOnly df+ WriteMode -> open WriteOnly df { trunc = True }+ AppendMode -> open WriteOnly df { append = True }+ ReadWriteMode -> open ReadWrite df+ where+ open = openFd fp+ df = defaultFileFlags { noctty = True, nonBlock = True, creat = Just 0o666 }++-- | Open an existing file and return the 'Handle'.+openExistingFile :: PosixPath -> IOMode -> IO Handle+openExistingFile fp iomode = fdToHandle =<< case iomode of+ ReadMode -> open ReadOnly df+ WriteMode -> open WriteOnly df { trunc = True }+ AppendMode -> open WriteOnly df { append = True }+ ReadWriteMode -> open ReadWrite df+ where+ open = openFd fp+ df = defaultFileFlags { noctty = True, nonBlock = True, creat = Nothing }
+ System/File/Windows.hs view
@@ -0,0 +1,111 @@+{-# LANGUAGE CPP #-}++module System.File.Windows where++import Control.Exception (bracketOnError)+import Data.Bits+import System.IO (IOMode(..), Handle)+import System.OsPath.Windows ( WindowsPath )++import qualified System.Win32 as Win32+import qualified System.Win32.WindowsString.File as WS+import Control.Monad (when, void)+#if defined(__IO_MANAGER_WINIO__)+import GHC.IO.SubSystem+#endif++-- | Open a file and return the 'Handle'.+openFile :: WindowsPath -> IOMode -> IO Handle+openFile fp iomode = bracketOnError+ (WS.createFile+ fp+ accessMode+ shareMode+ Nothing+ createMode+#if defined(__IO_MANAGER_WINIO__)+ (case ioSubSystem of+ IoPOSIX -> Win32.fILE_ATTRIBUTE_NORMAL+ IoNative -> Win32.fILE_ATTRIBUTE_NORMAL .|. Win32.fILE_FLAG_OVERLAPPED+ )+#else+ Win32.fILE_ATTRIBUTE_NORMAL+#endif+ Nothing)+ Win32.closeHandle+ toHandle+ where+ toHandle h = do+ when (iomode == AppendMode ) $ void $ Win32.setFilePointerEx h 0 Win32.fILE_END+ Win32.hANDLEToHandle h+ accessMode = case iomode of+ ReadMode -> Win32.gENERIC_READ+ WriteMode -> Win32.gENERIC_WRITE+ AppendMode -> Win32.gENERIC_WRITE .|. Win32.fILE_APPEND_DATA+ ReadWriteMode -> Win32.gENERIC_READ .|. Win32.gENERIC_WRITE++ createMode = case iomode of+ ReadMode -> Win32.oPEN_ALWAYS+ WriteMode -> Win32.cREATE_ALWAYS+ AppendMode -> Win32.oPEN_ALWAYS+ ReadWriteMode -> Win32.oPEN_ALWAYS++ shareMode = case iomode of+ ReadMode -> maxShareMode+ WriteMode -> writeShareMode+ AppendMode -> writeShareMode+ ReadWriteMode -> maxShareMode++maxShareMode :: Win32.ShareMode+maxShareMode =+ Win32.fILE_SHARE_DELETE .|.+ Win32.fILE_SHARE_READ .|.+ Win32.fILE_SHARE_WRITE++writeShareMode :: Win32.ShareMode+writeShareMode =+ Win32.fILE_SHARE_DELETE .|.+ Win32.fILE_SHARE_READ++ -- | Open an existing file and return the 'Handle'.+openExistingFile :: WindowsPath -> IOMode -> IO Handle+openExistingFile fp iomode = bracketOnError+ (WS.createFile+ fp+ accessMode+ shareMode+ Nothing+ createMode+#if defined(__IO_MANAGER_WINIO__)+ (case ioSubSystem of+ IoPOSIX -> Win32.fILE_ATTRIBUTE_NORMAL+ IoNative -> Win32.fILE_ATTRIBUTE_NORMAL .|. Win32.fILE_FLAG_OVERLAPPED+ )+#else+ Win32.fILE_ATTRIBUTE_NORMAL+#endif+ Nothing)+ Win32.closeHandle+ toHandle+ where+ toHandle h = do+ when (iomode == AppendMode ) $ void $ Win32.setFilePointerEx h 0 Win32.fILE_END+ Win32.hANDLEToHandle h+ accessMode = case iomode of+ ReadMode -> Win32.gENERIC_READ+ WriteMode -> Win32.gENERIC_WRITE+ AppendMode -> Win32.gENERIC_WRITE .|. Win32.fILE_APPEND_DATA+ ReadWriteMode -> Win32.gENERIC_READ .|. Win32.gENERIC_WRITE++ createMode = case iomode of+ ReadMode -> Win32.oPEN_EXISTING+ WriteMode -> Win32.tRUNCATE_EXISTING+ AppendMode -> Win32.oPEN_EXISTING+ ReadWriteMode -> Win32.oPEN_EXISTING++ shareMode = case iomode of+ ReadMode -> maxShareMode+ WriteMode -> writeShareMode+ AppendMode -> writeShareMode+ ReadWriteMode -> maxShareMode+
+ file-io.cabal view
@@ -0,0 +1,43 @@+cabal-version: 2.4+name: file-io+version: 0.1.0.0++synopsis: Basic file IO operations via 'OsPath'++description: Basic file IO operations like Prelude, but for 'OsPath'.++-- A URL where users can report bugs.+-- bug-reports:++-- The license under which the package is released.+license: BSD-3-Clause+author: Julian Ospald+maintainer: hasufell@posteo.de++copyright: Julian Ospald 2022+category: System+extra-source-files: CHANGELOG.md+ System/File/Common.hs++library+ default-language: Haskell2010++ if os(windows)+ other-modules:+ System.File.Windows+ build-depends: Win32 >= 2.13.3.0+ else+ other-modules:+ System.File.Posix+ build-depends: unix >= 2.8.0.0++ build-depends:+ base >= 4.10 && < 4.17,+ bytestring >=0.11.3.0,+ filepath >= 1.4.100.0++ exposed-modules:+ System.File.OsPath+ System.File.PlatformPath++ ghc-options: -Wall