summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-11-19 13:19:13 -0500
committerjoe <joe@jerkface.net>2017-11-19 13:30:38 -0500
commitd14b1a34e1c9cee50a7e15eda917e414e62e6ed3 (patch)
tree0b4544d28682a2f002af494325303fb24d16dcc0
parent0f4e8b298014d9db2cb3ebdb167f3a9d9ca1a3f3 (diff)
Updated xxd hex-dump code.
-rw-r--r--src/Text/XXD.hs42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/Text/XXD.hs b/src/Text/XXD.hs
index d835b238..b73a1ea2 100644
--- a/src/Text/XXD.hs
+++ b/src/Text/XXD.hs
@@ -1,26 +1,52 @@
1module Text.XXD where 1{-# LANGUAGE RankNTypes #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3module Text.XXD (xxd, xxd2) where
2 4
3import qualified Data.ByteString.Base16 as Base16 5import qualified Data.ByteString.Base16 as Base16
4import Data.ByteString (ByteString) 6import Data.ByteString (ByteString)
5import qualified Data.ByteString as B 7import qualified Data.ByteString as B
8import Data.ByteArray (ByteArrayAccess,ByteArray)
9import qualified Data.ByteArray as BA
6import Data.Word 10import Data.Word
7import Data.Bits 11import Data.Bits
8import Data.Char 12import Data.Char
13import Data.List
9import Text.Printf 14import Text.Printf
10 15
11nibble :: Word8 -> Char 16nibble :: Word8 -> Char
12nibble b = intToDigit (fromIntegral (b .&. 0x0F)) 17nibble b = intToDigit (fromIntegral (b .&. 0x0F))
13 18
14xxd :: Int -> ByteString -> [String] 19nibbles :: ByteArrayAccess ba => ba -> String
15xxd offset bs | B.null bs = [] 20nibbles xs = unwords $ map (\byte -> [nibble (byte `shiftR` 4), nibble byte])
16xxd offset bs = printf "%03x: %s" offset ds : xxd (offset + B.length xs) bs' 21 $ BA.unpack xs
22
23xxd0 :: (ByteArrayAccess ba) => (forall b. ByteArrayAccess b => b -> String) -> Int -> ba -> [String]
24xxd0 tr offset bs | BA.null bs = []
25xxd0 tr offset bs = printf "%03x: %s%s" offset (nibbles xs) (tr xs)
26 : xxd0 tr (offset + BA.length xs) bs'
17 where 27 where
18 ds = unwords $ map (\byte -> [nibble (byte `shiftR` 4), nibble byte]) 28 (xs,bs') = splitAtView 16 bs
19 $ B.unpack xs 29
20 (xs,bs') = B.splitAt 16 bs 30splitAtView :: (ByteArrayAccess ba) => Int -> ba -> (BA.View ba, BA.View ba)
31splitAtView n bs = (BA.takeView bs n, BA.dropView bs n)
32
33xxd :: ByteArrayAccess a => Int -> a -> [String]
34xxd = xxd0 (const "")
35
36-- | like xxd, but also shows ascii
37xxd2 :: ByteArrayAccess a => Int -> a -> [String]
38xxd2 = xxd0 withAscii
39
40withAscii :: ByteArrayAccess a => a -> [Char]
41withAscii row = replicate (50 - 3 * BA.length row) ' ' ++ myunpack row
42 where
43 myunpack s = map word8tochar (BA.unpack s)
44 where word8tochar w | (w .&. 0x80 /= 0) = '.'
45 word8tochar w = let c = chr (fromIntegral w)
46 in if isPrint c then c else '.'
21 47
22{- 48{-
23main = do 49main = do
24 bs <- B.getContents 50 bs <- B.getContents
25 mapM_ putStrLn $ xxd 0 bs 51 mapM_ putStrLn $ xxd2 0 bs
26 -} 52 -}