{-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} module App.Commands.DumpBitmap ( commandDumpBitmap ) where import App.Commands.Options.Type import App.Dump import Arbor.File.Format.Asif.Data.Ip import Arbor.File.Format.Asif.IO 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.Monoid ((<>)) import Options.Applicative import qualified Arbor.File.Format.Asif.ByteString.Lazy as LBS import qualified Data.Binary.Get as G import qualified Data.ByteString.Lazy as LBS import qualified System.IO as IO {-# ANN module ("HLint: ignore Reduce duplication" :: String) #-} {-# ANN module ("HLint: ignore Redundant do" :: String) #-} parseDumpBitmapOptions :: Parser DumpBitmapOptions parseDumpBitmapOptions = DumpBitmapOptions <$> strOption ( long "source" <> metavar "FILE" <> value "-" <> help "Input file" ) <*> strOption ( long "target" <> metavar "FILE" <> value "-" <> help "Output file" ) commandDumpBitmap :: Parser (IO ()) commandDumpBitmap = runResourceT . runDump <$> parseDumpBitmapOptions runDump :: MonadResource m => DumpBitmapOptions -> m () runDump opt = do (_, hIn) <- openFileOrStd (opt ^. the @"source") IO.ReadMode (_, hOut) <- openFileOrStd (opt ^. the @"target") IO.WriteMode contents <- liftIO $ LBS.hGetContents hIn forM_ (zip [0..] (G.runGet G.getWord64le <$> LBS.chunkBy 8 contents)) $ \(idx, w64) -> forM_ (word64ToList idx w64 []) $ \w32 -> do let ipString = w32 & word32ToIpv4 & ipv4ToString liftIO $ IO.hPutStrLn hOut $ ipString <> replicate (16 - length ipString) ' ' <> "(" <> show w32 <> ")"