bytedump-1.0/0000755000000000000000000000000012022044045011362 5ustar0000000000000000bytedump-1.0/README.md0000644000000000000000000000331212022044045012640 0ustar0000000000000000Haskell Bytedump library ======================== This is a set of helper to dump bytes (list of word8, string, bytestring, lazy bytestring) into nice to read tables like the unix utility hexdump. Example ------- this is an example using the default configuration. ``` | 7f 45 4c 46 02 01 01 00 : 00 00 00 00 00 00 00 00 | .ELF............ | 02 00 3e 00 01 00 00 00 : 68 5e 40 00 00 00 00 00 | ..>.....h^@..... | 40 00 00 00 00 00 00 00 : 00 99 0a 00 00 00 00 00 | @............... | 00 00 00 00 40 00 38 00 : 08 00 40 00 20 00 1d 00 | ....@.8...@. ... | 06 00 00 00 05 00 00 00 : 40 00 00 00 00 00 00 00 | ........@....... | 40 00 40 00 00 00 00 00 : 40 00 40 00 00 00 00 00 | @.@.....@.@..... | c0 01 00 00 00 00 00 00 : c0 01 00 00 00 00 00 00 | ................ | 08 00 00 00 00 00 00 00 : 03 00 00 00 04 00 00 00 | ................ | 00 02 00 00 00 00 00 00 : 00 02 40 00 00 00 00 00 | ..........@..... | 00 02 40 00 00 00 00 00 : 1c 00 00 00 00 00 00 00 | ..@............. | 1c 00 00 00 00 00 00 00 : 01 00 00 00 00 00 00 00 | ................ | 01 00 00 00 05 00 00 00 : 00 00 00 00 00 00 00 00 | ................ | 00 00 40 00 00 00 00 00 : 00 00 40 00 00 00 00 00 | ..@.......@..... | a4 e7 09 00 00 00 00 00 : a4 e7 09 00 00 00 00 00 | ................ | 00 00 20 00 00 00 00 00 : 01 00 00 00 06 00 00 00 | .. ............. | 00 f0 09 00 00 00 00 00 : 00 f0 69 00 00 00 00 00 | ..........i..... | 00 f0 69 00 00 00 00 00 : 98 a7 00 00 00 00 00 00 | ..i............. | 18 5f 01 00 00 00 00 00 : 00 00 20 00 00 00 00 00 | ._........ ..... | 02 00 00 00 06 00 00 00 : 30 f0 09 00 00 00 00 00 | ........0....... | 30 f0 69 00 00 00 00 00 : 30 f0 69 00 00 00 00 00 | 0.i.....0.i..... ``` bytedump-1.0/LICENSE0000644000000000000000000000273112022044045012372 0ustar0000000000000000Copyright (c) 2010-2011 Vincent Hanquez All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bytedump-1.0/bytedump.cabal0000644000000000000000000000226712022044045014206 0ustar0000000000000000Name: bytedump Version: 1.0 Description: A set of helpers to dump bytes with lots of different output formats easy to read for humans eyes. License: BSD3 License-file: LICENSE Author: Vincent Hanquez Copyright: Vincent Hanquez Author: Vincent Hanquez Maintainer: Vincent Hanquez Synopsis: Flexible byte dump helpers for human readers. Build-Type: Simple Category: Debug Homepage: http://github.com/vincenthz/hs-bytedump Cabal-Version: >=1.6 Data-Files: README.md Flag executable Description: Build the executable Default: False Library Build-Depends: base >= 3 && < 5 , bytestring Exposed-modules: Text.Bytedump ghc-options: -Wall Executable Hexdump Main-is: Hexdump.hs if flag(executable) Buildable: True Build-Depends: base >= 3 && < 5 , bytestring else Buildable: False source-repository head type: git location: git://github.com/vincenthz/hs-bytedump bytedump-1.0/Setup.hs0000644000000000000000000000005612022044045013017 0ustar0000000000000000import Distribution.Simple main = defaultMain bytedump-1.0/Hexdump.hs0000644000000000000000000000031712022044045013331 0ustar0000000000000000import Text.Bytedump import System.Environment (getArgs) import qualified Data.ByteString.Lazy as L main = do args <- getArgs fileData <- L.readFile $ args !! 0 putStrLn $ dumpLBS fileData bytedump-1.0/Text/0000755000000000000000000000000012022044045012306 5ustar0000000000000000bytedump-1.0/Text/Bytedump.hs0000644000000000000000000001632412022044045014441 0ustar0000000000000000 -- | -- Module : Text.Bytedump -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing some routines to debug data dump -- module Text.Bytedump ( hexString -- * Formatted string configuration , BytedumpConfig(..) , defaultConfig -- * Dump bytes into not formatted strings , dumpRaw , dumpRawS , dumpRawBS , dumpRawLBS -- * Dump bytes into formatted strings using a specific config , dumpWith , dumpWithS , dumpWithBS , dumpWithLBS -- * Dump bytes into formatted strings using default config , dump , dumpS , dumpBS , dumpLBS -- * Dump 2 set of bytes into formatted side-by-side strings using default config , dumpDiff , dumpDiffS , dumpDiffBS , dumpDiffLBS ) where import Data.List import Data.Word import qualified Data.ByteString.Lazy as L import qualified Data.ByteString as B -- | Configuration structure used for formatting functions data BytedumpConfig = BytedumpConfig { configRowSize :: Int -- ^ number of bytes per row. , configRowGroupSize :: Int -- ^ number of bytes per group per row. , configRowGroupSep :: String -- ^ string separating groups. , configRowLeft :: String -- ^ string on the left of the row. , configRowRight :: String -- ^ string on the right of the row. , configCellSep :: String -- ^ string separating cells in row. , configPrintChar :: Bool -- ^ if the printable ascii table is displayed. } deriving (Show,Eq) -- | Default Config using 16 bytes by row with a separation at the 8th byte, and -- dumping printable ascii character on the right. defaultConfig :: BytedumpConfig defaultConfig = BytedumpConfig { configRowSize = 16 , configRowGroupSize = 8 , configRowGroupSep = " : " , configRowLeft = " | " , configRowRight = " | " , configCellSep = " " , configPrintChar = True } hex :: Int -> Char hex 0 = '0' hex 1 = '1' hex 2 = '2' hex 3 = '3' hex 4 = '4' hex 5 = '5' hex 6 = '6' hex 7 = '7' hex 8 = '8' hex 9 = '9' hex 10 = 'a' hex 11 = 'b' hex 12 = 'c' hex 13 = 'd' hex 14 = 'e' hex 15 = 'f' hex _ = ' ' {-# INLINE hexBytes #-} hexBytes :: Word8 -> (Char, Char) hexBytes w = (hex h, hex l) where (h,l) = (fromIntegral w) `divMod` 16 -- | Dump one byte into a 2 hexadecimal characters. hexString :: Word8 -> String hexString i = [h,l] where (h,l) = hexBytes i -- | Dump a list of word8 into a raw string of hex value dumpRaw :: [Word8] -> String dumpRaw = concatMap hexString -- | Dump a string into a raw string of hex value dumpRawS :: String -> String dumpRawS = dumpRaw . map (toEnum.fromEnum) -- | Dump a bytestring into a raw string of hex value dumpRawBS :: B.ByteString -> String dumpRawBS = dumpRaw . B.unpack -- | Dump a lazy bytestring into a raw string of hex value dumpRawLBS :: L.ByteString -> String dumpRawLBS = dumpRaw . L.unpack disptable :: BytedumpConfig -> [Word8] -> [String] disptable _ [] = [] disptable cfg x = let (pre, post) = splitAt (configRowSize cfg) x in tableRow pre : disptable cfg post where tableRow row = let l = splitMultiple (configRowGroupSize cfg) $ map hexString row in let lb = intercalate (configRowGroupSep cfg) $ map (intercalate (configCellSep cfg)) l in let rb = map printChar row in let rowLen = 2 * configRowSize cfg + (configRowSize cfg - 1) * length (configCellSep cfg) + ((configRowSize cfg `div` configRowGroupSize cfg) - 1) * length (configRowGroupSep cfg) in configRowLeft cfg ++ lb ++ replicate (rowLen - length lb) ' ' ++ configRowRight cfg ++ (if configPrintChar cfg then rb else "") splitMultiple _ [] = [] splitMultiple n l = let (pre, post) = splitAt n l in pre : splitMultiple n post printChar :: Word8 -> Char printChar w | w >= 0x20 && w < 0x7f = toEnum $ fromIntegral w | otherwise = '.' dispDiffTable :: BytedumpConfig -> [Word8] -> [Word8] -> [String] dispDiffTable _ [] [] = [] dispDiffTable cfg x1 x2 = let (pre1, post1) = splitAt (configRowSize cfg) x1 in let (pre2, post2) = splitAt (configRowSize cfg) x2 in tableRow pre1 pre2 : dispDiffTable cfg post1 post2 where tableRow row1 row2 = let l1 = splitMultiple (configRowGroupSize cfg) $ map hexString row1 in let l2 = splitMultiple (configRowGroupSize cfg) $ map hexString row2 in let lb1 = intercalate (configRowGroupSep cfg) $ map (intercalate (configCellSep cfg)) l1 in let lb2 = intercalate (configRowGroupSep cfg) $ map (intercalate (configCellSep cfg)) l2 in let rowLen = 2 * configRowSize cfg + (configRowSize cfg - 1) * length (configCellSep cfg) + ((configRowSize cfg `div` configRowGroupSize cfg) - 1) * length (configRowGroupSep cfg) in configRowLeft cfg ++ lb1 ++ replicate (rowLen - length lb1) ' ' ++ configRowRight cfg ++ lb2 ++ replicate (rowLen - length lb2) ' ' ++ configRowRight cfg splitMultiple _ [] = [] splitMultiple n l = let (pre, post) = splitAt n l in pre : splitMultiple n post -- | Dump a list of bytes into formatted strings using a specific config dumpWith :: BytedumpConfig -> [Word8] -> String dumpWith cfg l = intercalate "\n" rows where rows = disptable cfg l -- | Dump a string into formatted strings using a specific config dumpWithS :: BytedumpConfig -> String -> String dumpWithS cfg = dumpWith cfg . map (toEnum.fromEnum) -- | Dump a bytestring into formatted strings using a specific config dumpWithBS :: BytedumpConfig -> B.ByteString -> String dumpWithBS cfg = dumpWith cfg . B.unpack -- | Dump a lazy bytestring into formatted strings using a specific config dumpWithLBS :: BytedumpConfig -> L.ByteString -> String dumpWithLBS cfg = dumpWith cfg . L.unpack -- | Dump a list of word8 into a formatted string of hex value dump :: [Word8] -> String dump l = intercalate "\n" rows where rows = disptable defaultConfig l -- | Dump a string into a formatted string of hex value dumpS :: String -> String dumpS = dump . map (toEnum.fromEnum) -- | Dump a bytestring into a formatted string of hex value dumpBS :: B.ByteString -> String dumpBS = dump . B.unpack -- | Dump a lazy bytestring into a formatted string of hex value dumpLBS :: L.ByteString -> String dumpLBS = dump . L.unpack -- | Dump two list of word8 into a formatted string of hex value side by side dumpDiff :: [Word8] -> [Word8] -> String dumpDiff l1 l2 = intercalate "\n" rows where rows = dispDiffTable defaultConfig l1 l2 -- | Dump a string into a formatted string of hex value dumpDiffS :: String -> String -> String dumpDiffS s1 s2 = dumpDiff (map (toEnum.fromEnum) s1) (map (toEnum.fromEnum) s2) -- | Dump a bytestring into a formatted string of hex value dumpDiffBS :: B.ByteString -> B.ByteString -> String dumpDiffBS b1 b2 = dumpDiff (B.unpack b1) (B.unpack b2) -- | Dump a lazy bytestring into a formatted string of hex value dumpDiffLBS :: L.ByteString -> L.ByteString -> String dumpDiffLBS l1 l2 = dumpDiff (L.unpack l1) (L.unpack l2)