{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module Data.Hash.Internal.Utils
( B16ShortByteString(..)
, b16
) where
import Data.Bits
import Data.Char
import Data.String
import Data.ByteString qualified as B
import qualified Data.ByteString.Short as BS
import Text.Printf
newtype B16ShortByteString = B16ShortByteString
{ B16ShortByteString -> ShortByteString
_unB16ShortByteString :: BS.ShortByteString }
b16 :: B16ShortByteString -> B.ByteString
b16 :: B16ShortByteString -> ByteString
b16 (B16ShortByteString ShortByteString
b) = ShortByteString -> ByteString
BS.fromShort ShortByteString
b
instance Show B16ShortByteString where
show :: B16ShortByteString -> String
show (B16ShortByteString ShortByteString
b) = (Word8 -> String) -> [Word8] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> Word8 -> String
forall r. PrintfType r => String -> r
printf String
"%0.2x") ([Word8] -> String) -> [Word8] -> String
forall a b. (a -> b) -> a -> b
$ ShortByteString -> [Word8]
BS.unpack ShortByteString
b
instance IsString B16ShortByteString where
fromString :: String -> B16ShortByteString
fromString String
l
| Int -> Bool
forall a. Integral a => a -> Bool
odd (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
l) =
String -> B16ShortByteString
forall a. HasCallStack => String -> a
error String
"Data.Hash.Internal.Utils.B16ShortByteString.fromString: odd input length"
| Bool
otherwise = ShortByteString -> B16ShortByteString
B16ShortByteString (ShortByteString -> B16ShortByteString)
-> ShortByteString -> B16ShortByteString
forall a b. (a -> b) -> a -> b
$ [Word8] -> ShortByteString
BS.pack ([Word8] -> ShortByteString) -> [Word8] -> ShortByteString
forall a b. (a -> b) -> a -> b
$ String -> [Word8]
forall {a}. Num a => String -> [a]
go String
l
where
go :: String -> [a]
go [] = [a]
forall a. Monoid a => a
mempty
go [Char
_] = String -> [a]
forall a. HasCallStack => String -> a
error String
"Data.Hash.Internal.Utils.B16ShortByteString.fromString: odd input length"
go (Char
a:Char
b:String
t) = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int -> Int
forall a. Bits a => a -> Int -> a
shiftL (Char -> Int
digitToInt Char
a) Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Char -> Int
digitToInt Char
b) a -> [a] -> [a]
forall a. a -> [a] -> [a]
: String -> [a]
go String
t