ちょっと前に作った16進ダンププログラムをリファクタリングしてみました
id:ha-tan:20060802:1154448075で作った16進ダンププログラムをリファクタリングしてみました。リファクタリングのポイントはこんな感じ。
ファイル: hd.hs
module Main (main) where import System (getArgs) import System.IO (hSetBinaryMode, hGetContents, openBinaryFile, IOMode (ReadMode), stdin) import Data.Char (ord, isAscii, isPrint) import Text.Printf (printf) readBinaryFiles :: [FilePath] -> IO String readBinaryFiles [] = do hSetBinaryMode stdin True getContents readBinaryFiles files = return . concat =<< mapM f files where f file = hGetContents =<< openBinaryFile file ReadMode groupn :: Int -> [a] -> [[a]] groupn _ [] = [] groupn n xs = let (xs1, xs2) = splitAt n xs in xs1 : groupn n xs2 hexdump :: String -> [String] hexdump = zipWith (\ o l -> off o ++ hex l ++ asc l) [0, 16 ..] . groupn 16 where off :: Int -> String off = printf "%08x " hex :: String -> String hex = pad 36 . concatMap f . groupn 4 where f xs = (concatMap (printf "%02x") $ map ord xs) ++ " " pad n s = s ++ replicate (n - length s) ' ' asc :: String -> String asc = (++) " " . map (\ c -> if isAscii c && isPrint c then c else '.') main :: IO () main = mapM_ putStrLn . hexdump =<< readBinaryFiles =<< getArgs
実行例:
$ echo hoge | ./hd.exe 00000000 686f6765 0a hoge.