asif-3.2.0: app/App/Commands/DumpOnly.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module App.Commands.DumpOnly
( commandDumpOnly
) where
import App.Commands.Options.Type (DumpOnlyOptions (DumpOnlyOptions))
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) #-}
parseDumpOnlyOptions :: Parser DumpOnlyOptions
parseDumpOnlyOptions = DumpOnlyOptions
<$> strOption
( long "source"
<> metavar "FILE"
<> value "-"
<> help "Input file"
)
<*> strOption
( long "target"
<> metavar "FILE"
<> value "-"
<> help "Output file"
)
<*> many
( option auto
( long "segment"
<> metavar "SEGMENT_ID"
<> help "Output file"
)
)
<*> many
( strOption
( long "filename"
<> metavar "FILE"
<> help "Output file"
)
)
commandDumpOnly :: Parser (IO ())
commandDumpOnly = runResourceT . runDump <$> parseDumpOnlyOptions
runDump :: MonadResource m => DumpOnlyOptions -> m ()
runDump opt = do
(_, hIn) <- openFileOrStd (opt ^. the @"source") IO.ReadMode
(_, hOut) <- openFileOrStd (opt ^. the @"target") IO.WriteMode
let dumpSegments = opt ^. the @"segments" & S.fromList :: S.Set Int
let dumpFilenames = opt ^. the @"filenames" <&> 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
when (S.member filename dumpFilenames || S.member i dumpSegments) $ do
dumpSegment hOut i filename segment
where magic = AP.string "seg:" *> (BS.pack <$> many AP.anyWord8) AP.<?> "\"seg:????\""