{-# LANGUAGE MultiParamTypeClasses
           , TypeSynonymInstances
           , FlexibleInstances
  #-}


module Data.ByteString.Nums.Careless.Hex where


import Prelude hiding (head, tail, drop)
import Data.Word
import Data.Int
import Data.ByteString hiding (head, pack)
import Data.ByteString.Internal
import qualified Data.ByteString.Lazy.Char8 as Lazy
import qualified Data.ByteString.Lazy.Internal as Lazy




{-| Types that can be read from hexadecimal strings. Characters that are not
    hexadecimal digits are skipped over. One pleasant consequence of this is
    that a leading @0x@ is simply ignored.
 -}
class (Num n) => Hexable b n where
  hex                       ::  b -> n

instance Hexable ByteString Word8 where
  hex :: ByteString -> Word8
hex                        =  ByteString -> Word8
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Word16 where
  hex :: ByteString -> Word16
hex                        =  ByteString -> Word16
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Word32 where
  hex :: ByteString -> Word32
hex                        =  ByteString -> Word32
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Word64 where
  hex :: ByteString -> Word64
hex                        =  ByteString -> Word64
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Word where
  hex :: ByteString -> Word
hex                        =  ByteString -> Word
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Int8 where
  hex :: ByteString -> Int8
hex                        =  ByteString -> Int8
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Int16 where
  hex :: ByteString -> Int16
hex                        =  ByteString -> Int16
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Int32 where
  hex :: ByteString -> Int32
hex                        =  ByteString -> Int32
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Int64 where
  hex :: ByteString -> Int64
hex                        =  ByteString -> Int64
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Int where
  hex :: ByteString -> Int
hex                        =  ByteString -> Int
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Float where
  hex :: ByteString -> Float
hex                        =  ByteString -> Float
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Double where
  hex :: ByteString -> Double
hex                        =  ByteString -> Double
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Rational where
  hex :: ByteString -> Rational
hex                        =  ByteString -> Rational
forall n. Num n => ByteString -> n
strict_hex
instance Hexable ByteString Integer where
  hex :: ByteString -> Integer
hex                        =  ByteString -> Integer
forall n. Num n => ByteString -> n
strict_hex

instance Hexable Lazy.ByteString Word8 where
  hex :: ByteString -> Word8
hex                        =  ByteString -> Word8
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Word16 where
  hex :: ByteString -> Word16
hex                        =  ByteString -> Word16
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Word32 where
  hex :: ByteString -> Word32
hex                        =  ByteString -> Word32
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Word64 where
  hex :: ByteString -> Word64
hex                        =  ByteString -> Word64
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Word where
  hex :: ByteString -> Word
hex                        =  ByteString -> Word
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Int8 where
  hex :: ByteString -> Int8
hex                        =  ByteString -> Int8
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Int16 where
  hex :: ByteString -> Int16
hex                        =  ByteString -> Int16
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Int32 where
  hex :: ByteString -> Int32
hex                        =  ByteString -> Int32
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Int64 where
  hex :: ByteString -> Int64
hex                        =  ByteString -> Int64
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Int where
  hex :: ByteString -> Int
hex                        =  ByteString -> Int
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Float where
  hex :: ByteString -> Float
hex                        =  ByteString -> Float
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Double where
  hex :: ByteString -> Double
hex                        =  ByteString -> Double
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Rational where
  hex :: ByteString -> Rational
hex                        =  ByteString -> Rational
forall n. Num n => ByteString -> n
lazy_hex
instance Hexable Lazy.ByteString Integer where
  hex :: ByteString -> Integer
hex                        =  ByteString -> Integer
forall n. Num n => ByteString -> n
lazy_hex




hexalize                    ::  (Num n) => n -> Word8 -> n
hexalize :: forall n. Num n => n -> Word8 -> n
hexalize n
acc Word8
byte
  | Char -> Char -> Bool
between Char
'a' Char
'f'          =  Word8 -> n
forall {a}. Integral a => a -> n
place_up (Word8
byte Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
0x0a Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Char -> Word8
c2w Char
'a')
  | Char -> Char -> Bool
between Char
'A' Char
'F'          =  Word8 -> n
forall {a}. Integral a => a -> n
place_up (Word8
byte Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
0x0a Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Char -> Word8
c2w Char
'A')
  | Char -> Char -> Bool
between Char
'0' Char
'9'          =  Word8 -> n
forall {a}. Integral a => a -> n
place_up (Word8
byte Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Char -> Word8
c2w Char
'0')
  | Bool
otherwise                =  n
acc
 where
  between :: Char -> Char -> Bool
between Char
a Char
z                =  Word8
byte Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Char -> Word8
c2w Char
a Bool -> Bool -> Bool
&& Word8
byte Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Char -> Word8
c2w Char
z
  place_up :: a -> n
place_up a
b                 =  (n
0x10 n -> n -> n
forall a. Num a => a -> a -> a
* n
acc) n -> n -> n
forall a. Num a => a -> a -> a
+ a -> n
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b

strict_hex                  ::  (Num n) => ByteString -> n
strict_hex :: forall n. Num n => ByteString -> n
strict_hex ByteString
bytes             =  (n -> Word8 -> n) -> n -> ByteString -> n
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' n -> Word8 -> n
forall n. Num n => n -> Word8 -> n
hexalize n
0 ByteString
bytes

lazy_hex                    ::  (Num n) => Lazy.ByteString -> n
lazy_hex :: forall n. Num n => ByteString -> n
lazy_hex ByteString
bytes               =  (n -> ByteString -> n) -> n -> ByteString -> n
forall a. (a -> ByteString -> a) -> a -> ByteString -> a
Lazy.foldlChunks ((n -> Word8 -> n) -> n -> ByteString -> n
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
foldl' n -> Word8 -> n
forall n. Num n => n -> Word8 -> n
hexalize) n
0 ByteString
bytes