-- |-- Module : Text.Bytedump-- License : BSD-style-- Maintainer : Vincent Hanquez <vincent@snarc.org>-- Stability : experimental-- Portability : unknown---- A module containing some routines to debug data dump--moduleText.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)whereimportData.ListimportData.WordimportqualifiedData.ByteString.LazyasLimportqualifiedData.ByteStringasB-- | Configuration structure used for formatting functionsdataBytedumpConfig=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::BytedumpConfigdefaultConfig=BytedumpConfig{configRowSize=16,configRowGroupSize=8,configRowGroupSep=" : ",configRowLeft=" | ",configRowRight=" | ",configCellSep=" ",configPrintChar=True}hex::Int->Charhex0='0'hex1='1'hex2='2'hex3='3'hex4='4'hex5='5'hex6='6'hex7='7'hex8='8'hex9='9'hex10='a'hex11='b'hex12='c'hex13='d'hex14='e'hex15='f'hex_=' '{-# INLINE hexBytes #-}hexBytes::Word8->(Char,Char)hexBytesw=(hexh,hexl)where(h,l)=(fromIntegralw)`divMod`16-- | Dump one byte into a 2 hexadecimal characters.hexString::Word8->StringhexStringi=[h,l]where(h,l)=hexBytesi-- | Dump a list of word8 into a raw string of hex valuedumpRaw::[Word8]->StringdumpRaw=concatMaphexString-- | Dump a string into a raw string of hex valuedumpRawS::String->StringdumpRawS=dumpRaw.map(toEnum.fromEnum)-- | Dump a bytestring into a raw string of hex valuedumpRawBS::B.ByteString->StringdumpRawBS=dumpRaw.B.unpack-- | Dump a lazy bytestring into a raw string of hex valuedumpRawLBS::L.ByteString->StringdumpRawLBS=dumpRaw.L.unpackdisptable::BytedumpConfig->[Word8]->[String]disptable_[]=[]disptablecfgx=let(pre,post)=splitAt(configRowSizecfg)xintableRowpre:disptablecfgpostwheretableRowrow=letl=splitMultiple(configRowGroupSizecfg)$maphexStringrowinletlb=intercalate(configRowGroupSepcfg)$map(intercalate(configCellSepcfg))linletrb=mapprintCharrowinletrowLen=2*configRowSizecfg+(configRowSizecfg-1)*length(configCellSepcfg)+((configRowSizecfg`div`configRowGroupSizecfg)-1)*length(configRowGroupSepcfg)inconfigRowLeftcfg++lb++replicate(rowLen-lengthlb)' '++configRowRightcfg++(ifconfigPrintCharcfgthenrbelse"")splitMultiple_[]=[]splitMultiplenl=let(pre,post)=splitAtnlinpre:splitMultiplenpostprintChar::Word8->CharprintCharw|w>=0x20&&w<0x7f=toEnum$fromIntegralw|otherwise='.'dispDiffTable::BytedumpConfig->[Word8]->[Word8]->[String]dispDiffTable_[][]=[]dispDiffTablecfgx1x2=let(pre1,post1)=splitAt(configRowSizecfg)x1inlet(pre2,post2)=splitAt(configRowSizecfg)x2intableRowpre1pre2:dispDiffTablecfgpost1post2wheretableRowrow1row2=letl1=splitMultiple(configRowGroupSizecfg)$maphexStringrow1inletl2=splitMultiple(configRowGroupSizecfg)$maphexStringrow2inletlb1=intercalate(configRowGroupSepcfg)$map(intercalate(configCellSepcfg))l1inletlb2=intercalate(configRowGroupSepcfg)$map(intercalate(configCellSepcfg))l2inletrowLen=2*configRowSizecfg+(configRowSizecfg-1)*length(configCellSepcfg)+((configRowSizecfg`div`configRowGroupSizecfg)-1)*length(configRowGroupSepcfg)inconfigRowLeftcfg++lb1++replicate(rowLen-lengthlb1)' '++configRowRightcfg++lb2++replicate(rowLen-lengthlb2)' '++configRowRightcfgsplitMultiple_[]=[]splitMultiplenl=let(pre,post)=splitAtnlinpre:splitMultiplenpost-- | Dump a list of bytes into formatted strings using a specific configdumpWith::BytedumpConfig->[Word8]->StringdumpWithcfgl=intercalate"\n"rowswhererows=disptablecfgl-- | Dump a string into formatted strings using a specific configdumpWithS::BytedumpConfig->String->StringdumpWithScfg=dumpWithcfg.map(toEnum.fromEnum)-- | Dump a bytestring into formatted strings using a specific configdumpWithBS::BytedumpConfig->B.ByteString->StringdumpWithBScfg=dumpWithcfg.B.unpack-- | Dump a lazy bytestring into formatted strings using a specific configdumpWithLBS::BytedumpConfig->L.ByteString->StringdumpWithLBScfg=dumpWithcfg.L.unpack-- | Dump a list of word8 into a formatted string of hex valuedump::[Word8]->Stringdumpl=intercalate"\n"rowswhererows=disptabledefaultConfigl-- | Dump a string into a formatted string of hex valuedumpS::String->StringdumpS=dump.map(toEnum.fromEnum)-- | Dump a bytestring into a formatted string of hex valuedumpBS::B.ByteString->StringdumpBS=dump.B.unpack-- | Dump a lazy bytestring into a formatted string of hex valuedumpLBS::L.ByteString->StringdumpLBS=dump.L.unpack-- | Dump two list of word8 into a formatted string of hex value side by sidedumpDiff::[Word8]->[Word8]->StringdumpDiffl1l2=intercalate"\n"rowswhererows=dispDiffTabledefaultConfigl1l2-- | Dump a string into a formatted string of hex valuedumpDiffS::String->String->StringdumpDiffSs1s2=dumpDiff(map(toEnum.fromEnum)s1)(map(toEnum.fromEnum)s2)-- | Dump a bytestring into a formatted string of hex valuedumpDiffBS::B.ByteString->B.ByteString->StringdumpDiffBSb1b2=dumpDiff(B.unpackb1)(B.unpackb2)-- | Dump a lazy bytestring into a formatted string of hex valuedumpDiffLBS::L.ByteString->L.ByteString->StringdumpDiffLBSl1l2=dumpDiff(L.unpackl1)(L.unpackl2)