module Data.Binary.Strict.Util
( hexDumpString
, hexDump
) where
import Data.List (intersperse)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.ByteString.Internal (w2c)
import qualified Data.ByteString.Lazy.Char8 as BLC
import Text.Printf (printf)
hexDumpString :: B.ByteString -> BLC.ByteString
hexDumpString = BLC.fromChunks . dumpLine (0 :: Int) where
dumpLine offset bs
| B.null bs = []
| otherwise = line : (dumpLine (offset + 16) $ B.drop 16 bs) where
line = s $ a ++ b ++ " " ++ c ++ padding ++ right ++ newline
s = BC.pack
a = printf "%08x " offset
b = concat $ intersperse " " $ map (printf "%02x") $ B.unpack $ B.take 8 bs
c = concat $ intersperse " " $ map (printf "%02x") $ B.unpack $ B.take 8 $ B.drop 8 bs
padding = replicate paddingSize ' '
paddingSize = 2 + (16 - (min 16 $ B.length bs)) * 3 - if B.length bs <= 8 then 1 else 0
right = map safeChar $ B.unpack $ B.take 16 bs
newline = "\n"
safeChar c
| c >= 32 && c <= 126 = w2c c
| otherwise = '.'
hexDump :: B.ByteString -> IO ()
hexDump = BLC.putStr . hexDumpString