-- | Byte functions. module Music.Theory.Byte where import qualified Data.ByteString as B {- bytestring -} import Data.Char {- base -} import Data.List.Split {- split -} import Data.Maybe {- base -} import Numeric {- base -} import qualified Music.Theory.Read as T {- hmt -} -- | Given /n/ in (0,255) make two character hex string. -- -- > mapMaybe byte_hex_pp [0x0F,0xF0,0xF0F] == ["0F","F0"] byte_hex_pp :: (Integral i, Show i) => i -> Maybe String byte_hex_pp n = case showHex n "" of [c] -> Just ['0',toUpper c] [c,d] -> Just (map toUpper [c,d]) _ -> Nothing -- | Erroring variant. byte_hex_pp_err :: (Integral i, Show i) => i -> String byte_hex_pp_err = fromMaybe (error "byte_hex_pp") . byte_hex_pp -- | 'unwords' of 'map' of 'byte_hex_pp_err'. -- -- > byte_seq_hex_pp [0x0F,0xF0] == "0F F0" byte_seq_hex_pp :: (Integral i, Show i) => [i] -> String byte_seq_hex_pp = unwords . map byte_hex_pp_err -- | Read two character hexadecimal string. read_hex_byte :: (Eq t,Num t) => String -> t read_hex_byte s = case s of [_,_] -> T.reads_to_read_precise_err "readHex" readHex s _ -> error "read_hex_byte" read_hex_byte_seq :: (Eq t,Num t) => String -> [t] read_hex_byte_seq = map read_hex_byte . words -- | Load binary 'U8' sequence from file. load_byte_seq :: Integral i => FilePath -> IO [i] load_byte_seq = fmap (map fromIntegral . B.unpack) . B.readFile store_byte_seq :: Integral i => FilePath -> [i] -> IO () store_byte_seq fn = B.writeFile fn . B.pack . map fromIntegral -- | Load hexadecimal text 'U8' sequence from file. load_hex_byte_seq :: Integral i => FilePath -> IO [i] load_hex_byte_seq = fmap (map read_hex_byte . words) . readFile -- | Store 'U8' sequence as hexadecimal text, 16 words per line. store_hex_byte_seq :: (Integral i,Show i) => FilePath -> [i] -> IO () store_hex_byte_seq fn = writeFile fn . unlines . map unwords . chunksOf 16 . map byte_hex_pp_err