asif-3.2.0: app/App/Commands/Dump.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module App.Commands.Dump where
import App.Commands.Options.Type (DumpOptions (DumpOptions))
import App.Dump
import Arbor.File.Format.Asif.IO
import Arbor.File.Format.Asif.Segment
import Control.Lens
import Control.Monad
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource (MonadResource, runResourceT)
import Data.Generics.Product.Any
import Data.Maybe
import Data.Monoid ((<>))
import Data.Text (Text)
import Options.Applicative
import qualified Data.Attoparsec.ByteString as AP
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Set as S
import qualified Data.Text as T
import qualified System.IO as IO
{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
{-# ANN module ("HLint: ignore Redundant do" :: String) #-}
parseDumpOptions :: Parser DumpOptions
parseDumpOptions = DumpOptions
<$> strOption
( long "source"
<> metavar "FILE"
<> value "-"
<> help "Input file"
)
<*> strOption
( long "target"
<> metavar "FILE"
<> value "-"
<> help "Output file"
)
<*> many
( option auto
( long "without-segment"
<> metavar "SEGMENT_ID"
<> help "Output file"
)
)
<*> many
( strOption
( long "without-filename"
<> metavar "FILE"
<> help "Output file"
)
)
commandDump :: Parser (IO ())
commandDump = runResourceT . runDump <$> parseDumpOptions
runDump :: MonadResource m => DumpOptions -> m ()
runDump opt = do
(_, hIn) <- openFileOrStd (opt ^. the @"source") IO.ReadMode
(_, hOut) <- openFileOrStd (opt ^. the @"target") IO.WriteMode
let dumpWithoutSegments = opt ^. the @"withoutSegments" & S.fromList :: S.Set Int
let dumpWithoutFilenames = opt ^. the @"withoutFilenames" <&> T.pack & S.fromList :: S.Set Text
contents <- liftIO $ LBS.hGetContents hIn
case extractSegments magic contents of
Left errorMessage -> do
liftIO $ IO.hPutStrLn IO.stderr $ "Error occured: " <> errorMessage
return ()
Right segments -> do
let filenames = fromMaybe "" . (^. the @"meta" . the @"filename") <$> segments
let namedSegments = zip filenames segments
forM_ (zip [0..] namedSegments) $ \(i :: Int, (filename, segment)) -> do
unless (S.member filename dumpWithoutFilenames || S.member i dumpWithoutSegments) $ do
dumpSegment hOut i filename segment
where magic = AP.string "seg:" *> (BS.pack <$> many AP.anyWord8) AP.<?> "\"seg:????\""