Initial commit
This commit is contained in:
commit
cbdb8902b0
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Revision history for streamly-files
|
||||||
|
|
||||||
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
|
* First version. Released on an unsuspecting world.
|
30
LICENSE
Normal file
30
LICENSE
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Copyright (c) 2020, Julian Ospald
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of Julian Ospald nor the names of other
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
6
cabal.project
Normal file
6
cabal.project
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
packages: ./streamly-filesystem.cabal
|
||||||
|
|
||||||
|
source-repository-package
|
||||||
|
type: git
|
||||||
|
location: https://github.com/composewell/streamly.git
|
||||||
|
tag: 753d091b75bd0d493b130a7eb66b283a949994e3
|
116
src/Streamly/External/FileSystem/Handle/Posix.hs
vendored
Normal file
116
src/Streamly/External/FileSystem/Handle/Posix.hs
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE MultiWayIf #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- Module : Streamly.External.FileSystem.Handle.Posix
|
||||||
|
-- Copyright : © 2020 Julian Ospald
|
||||||
|
-- License : BSD3
|
||||||
|
--
|
||||||
|
-- Maintainer : Julian Ospald <hasufell@posteo.de>
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : portable
|
||||||
|
--
|
||||||
|
-- This module provides high-level file streaming API.
|
||||||
|
module Streamly.External.FileSystem.Handle.Posix where
|
||||||
|
|
||||||
|
import Streamly
|
||||||
|
import Streamly.Memory.Array
|
||||||
|
import qualified Streamly.Memory.Array as A
|
||||||
|
import qualified Streamly.FileSystem.Handle as FH
|
||||||
|
import qualified Streamly.Internal.FileSystem.Handle
|
||||||
|
as IFH
|
||||||
|
import qualified Streamly.Prelude as S
|
||||||
|
import qualified Streamly.Internal.Prelude as S
|
||||||
|
import System.IO ( Handle
|
||||||
|
, hClose
|
||||||
|
)
|
||||||
|
import Control.Monad.IO.Class ( liftIO
|
||||||
|
, MonadIO
|
||||||
|
)
|
||||||
|
import Data.Word ( Word8 )
|
||||||
|
import Data.Word8
|
||||||
|
import Control.Exception.Safe
|
||||||
|
import qualified Data.ByteString.Lazy as L
|
||||||
|
import qualified Data.ByteString as BS
|
||||||
|
import qualified Streamly.External.ByteString as Strict
|
||||||
|
import qualified Data.ByteString.Lazy.Internal as BSLI
|
||||||
|
import System.IO.Unsafe
|
||||||
|
import qualified Streamly.Internal.Data.Unfold as SIU
|
||||||
|
import Streamly.Internal.Data.Unfold.Types
|
||||||
|
import System.Posix.RawFilePath.Directory.Traversals
|
||||||
|
import qualified Streamly.Internal.Data.Stream.StreamD.Type
|
||||||
|
as D
|
||||||
|
import System.Posix.ByteString
|
||||||
|
import System.Posix.Foreign ( DirType )
|
||||||
|
import System.Posix.Directory.ByteString
|
||||||
|
as PosixBS
|
||||||
|
|
||||||
|
|
||||||
|
-- |Read the given file lazily as a lazy ByteString.
|
||||||
|
--
|
||||||
|
-- The handle is closed automatically, when the stream exits normally,
|
||||||
|
-- aborts or gets garbage collected.
|
||||||
|
--
|
||||||
|
-- This uses `unsafeInterleaveIO` under the hood.
|
||||||
|
readFile :: Handle -> IO L.ByteString
|
||||||
|
readFile handle' = fromChunks (readFileStream handle')
|
||||||
|
where
|
||||||
|
-- https://github.com/psibi/streamly-bytestring/issues/7
|
||||||
|
fromChunks =
|
||||||
|
S.foldrM (\x b -> unsafeInterleaveIO b >>= pure . BSLI.chunk x)
|
||||||
|
(pure BSLI.Empty)
|
||||||
|
. S.map Strict.fromArray
|
||||||
|
|
||||||
|
|
||||||
|
-- | Read from the given handle as a streamly filestream.
|
||||||
|
--
|
||||||
|
-- The handle is closed automatically, when the stream exits normally,
|
||||||
|
-- aborts or gets garbage collected.
|
||||||
|
readFileStream :: (MonadCatch m, MonadAsync m)
|
||||||
|
=> Handle
|
||||||
|
-> SerialT m (Array Word8)
|
||||||
|
readFileStream = S.unfold
|
||||||
|
(SIU.finallyIO (liftIO . hClose)
|
||||||
|
FH.readChunks
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-- | Like 'copyFileStream', except for two file handles.
|
||||||
|
copyFile :: (MonadCatch m, MonadAsync m, MonadMask m)
|
||||||
|
=> Handle
|
||||||
|
-> Handle
|
||||||
|
-> m ()
|
||||||
|
copyFile fromHandle toHandle =
|
||||||
|
copyFileStream (readFileStream fromHandle) toHandle
|
||||||
|
|
||||||
|
|
||||||
|
-- | Copy a stream to a file handle.
|
||||||
|
--
|
||||||
|
-- The handle is closed automatically after the stream is copied.
|
||||||
|
copyFileStream :: (MonadCatch m, MonadAsync m, MonadMask m)
|
||||||
|
=> SerialT m (Array Word8) -- ^ stream to copy
|
||||||
|
-> Handle -- ^ file handle to copy to
|
||||||
|
-> m ()
|
||||||
|
copyFileStream stream handle' =
|
||||||
|
finally (liftIO $ hClose handle') $ S.fold (FH.writeChunks handle') stream
|
||||||
|
|
||||||
|
|
||||||
|
unfoldDirectoryContents :: MonadIO m
|
||||||
|
=> Unfold m DirStream (DirType, RawFilePath)
|
||||||
|
unfoldDirectoryContents = Unfold step return
|
||||||
|
where
|
||||||
|
{-# INLINE [0] step #-}
|
||||||
|
step dirstream = do
|
||||||
|
(typ, e) <- liftIO $ readDirEnt dirstream
|
||||||
|
return if
|
||||||
|
| BS.null e -> D.Stop
|
||||||
|
| BS.pack [_period] == e -> D.Skip dirstream
|
||||||
|
| BS.pack [_period, _period] == e -> D.Skip dirstream
|
||||||
|
| otherwise -> D.Yield (typ, e) dirstream
|
||||||
|
|
||||||
|
|
||||||
|
getDirectoryContents :: (MonadCatch m, MonadAsync m, MonadMask m)
|
||||||
|
=> DirStream
|
||||||
|
-> SerialT m (DirType, RawFilePath)
|
||||||
|
getDirectoryContents = S.unfold
|
||||||
|
(SIU.finallyIO (liftIO . PosixBS.closeDirStream) unfoldDirectoryContents)
|
38
streamly-filesystem.cabal
Normal file
38
streamly-filesystem.cabal
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
cabal-version: >=1.10
|
||||||
|
|
||||||
|
name: streamly-filesytem
|
||||||
|
version: 0.1.0.0
|
||||||
|
synopsis: Beautiful file streaming
|
||||||
|
-- description:
|
||||||
|
bug-reports: https://github.com/hasufell/streamly-filesystem/issues
|
||||||
|
license: BSD3
|
||||||
|
license-file: LICENSE
|
||||||
|
author: Julian Ospald <hasufell@posteo.de>
|
||||||
|
maintainer: Julian Ospald <hasufell@posteo.de>
|
||||||
|
copyright: Julian Ospald <hasufell@posteo.de> 2020
|
||||||
|
category: Streaming
|
||||||
|
build-type: Simple
|
||||||
|
extra-source-files: CHANGELOG.md
|
||||||
|
|
||||||
|
library
|
||||||
|
if os(windows) -- not supported yet
|
||||||
|
build-depends: unbuildable<0
|
||||||
|
buildable: False
|
||||||
|
exposed-modules: Streamly.External.FileSystem.Handle.Posix
|
||||||
|
-- other-modules:
|
||||||
|
-- other-extensions:
|
||||||
|
build-depends: base >= 4.12 && < 5
|
||||||
|
, bytestring >= 0.10
|
||||||
|
, hpath-directory >= 0.13
|
||||||
|
, safe-exceptions >= 0.1
|
||||||
|
, streamly >= 0.7
|
||||||
|
, streamly-bytestring >= 0.1.0.1
|
||||||
|
, unix >= 2.7
|
||||||
|
, word8 >= 0.1.3
|
||||||
|
hs-source-dirs: src
|
||||||
|
default-language: Haskell2010
|
||||||
|
GHC-Options: -Wall -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
||||||
|
|
||||||
|
source-repository head
|
||||||
|
type: git
|
||||||
|
location: https://github.com/hasufell/streamly-filesystem
|
Loading…
Reference in New Issue
Block a user