{-# LANGUAGE BangPatterns
           , UnboxedTuples #-}

{-# OPTIONS_HADDOCK hide #-}

module Parser.Lathe.Numeric.FixedWidth.Internal
  ( i8HexFixed
  , w8HexFixed

  , i16HexFixed
  , w16HexFixed

  , i32HexFixed
  , w32HexFixed
  , f32HexFixed

  , i64HexFixed
  , w64HexFixed
  , f64HexFixed
  ) where

import           Parser.Lathe.Radix
import           Parser.Lathe.Internal

import           Data.Bits
import qualified Data.ByteString as B (ByteString)
import qualified Data.ByteString.Unsafe as B
import           Data.Int
import           Data.Word
import           GHC.Float (castWord32ToFloat, castWord64ToDouble)



i8HexFixed :: e -> B.ByteString -> (# Res e Int8 #)
i8HexFixed :: forall e. e -> ByteString -> (# Res e Int8 #)
i8HexFixed e
e = (Word8 -> Int8) -> e -> ByteString -> (# Res e Int8 #)
forall a e. (Word8 -> a) -> e -> ByteString -> (# Res e a #)
x8HexFixed Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral e
e

w8HexFixed :: e -> B.ByteString -> (# Res e Word8 #)
w8HexFixed :: forall e. e -> ByteString -> (# Res e Word8 #)
w8HexFixed e
e = (Word8 -> Word8) -> e -> ByteString -> (# Res e Word8 #)
forall a e. (Word8 -> a) -> e -> ByteString -> (# Res e a #)
x8HexFixed Word8 -> Word8
forall a. a -> a
id e
e

{-# INLINE x8HexFixed #-}
x8HexFixed :: (Word8 -> a) -> e -> B.ByteString -> (# Res e a #)
x8HexFixed :: forall a e. (Word8 -> a) -> e -> ByteString -> (# Res e a #)
x8HexFixed Word8 -> a
f e
e = ByteString -> (# Res e a #)
go
  where
    go :: ByteString -> (# Res e a #)
go ByteString
b
      | Just Word8
i0 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0), let !n0 :: Word8
n0 =        Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
unsafeShiftL Word8
i0 Int
0x4
      , Just Word8
i1 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
1), let !n1 :: Word8
n1 = Word8
n0 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.|.              Word8
i1
          = let !r :: a
r = Word8 -> a
f Word8
n1
            in (# a -> Res e a
forall a e. a -> Res e a
Yes a
r #)

      | Bool
otherwise = (# e -> Res e a
forall e a. e -> Res e a
No e
e #)



i16HexFixed :: e -> B.ByteString -> (# Res e Int16 #)
i16HexFixed :: forall e. e -> ByteString -> (# Res e Int16 #)
i16HexFixed e
e = (Word16 -> Int16) -> e -> ByteString -> (# Res e Int16 #)
forall a e. (Word16 -> a) -> e -> ByteString -> (# Res e a #)
x16HexFixed Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral e
e

w16HexFixed :: e -> B.ByteString -> (# Res e Word16 #)
w16HexFixed :: forall e. e -> ByteString -> (# Res e Word16 #)
w16HexFixed e
e = (Word16 -> Word16) -> e -> ByteString -> (# Res e Word16 #)
forall a e. (Word16 -> a) -> e -> ByteString -> (# Res e a #)
x16HexFixed Word16 -> Word16
forall a. a -> a
id e
e

{-# INLINE x16HexFixed #-}
x16HexFixed :: (Word16 -> a) -> e -> B.ByteString -> (# Res e a #)
x16HexFixed :: forall a e. (Word16 -> a) -> e -> ByteString -> (# Res e a #)
x16HexFixed Word16 -> a
f e
e = ByteString -> (# Res e a #)
go
  where
    go :: ByteString -> (# Res e a #)
go ByteString
b
      | Just Word8
i0 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0), let !n0 :: Word16
n0 =        Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i0) Int
0xC
      , Just Word8
i1 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
1), let !n1 :: Word16
n1 = Word16
n0 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i1) Int
0x8
      , Just Word8
i2 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
2), let !n2 :: Word16
n2 = Word16
n1 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|. Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i2) Int
0x4
      , Just Word8
i3 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
3), let !n3 :: Word16
n3 = Word16
n2 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.|.               Word8 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i3
          = let !r :: a
r = Word16 -> a
f Word16
n3
            in (# a -> Res e a
forall a e. a -> Res e a
Yes a
r #)

      | Bool
otherwise = (# e -> Res e a
forall e a. e -> Res e a
No e
e #)



i32HexFixed :: e -> B.ByteString -> (# Res e Int32 #)
i32HexFixed :: forall e. e -> ByteString -> (# Res e Int32 #)
i32HexFixed e
e = (Word32 -> Int32) -> e -> ByteString -> (# Res e Int32 #)
forall a e. (Word32 -> a) -> e -> ByteString -> (# Res e a #)
x32HexFixed Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral e
e

w32HexFixed :: e -> B.ByteString -> (# Res e Word32 #)
w32HexFixed :: forall e. e -> ByteString -> (# Res e Word32 #)
w32HexFixed e
e = (Word32 -> Word32) -> e -> ByteString -> (# Res e Word32 #)
forall a e. (Word32 -> a) -> e -> ByteString -> (# Res e a #)
x32HexFixed Word32 -> Word32
forall a. a -> a
id e
e

f32HexFixed :: e -> B.ByteString -> (# Res e Float #)
f32HexFixed :: forall e. e -> ByteString -> (# Res e Float #)
f32HexFixed e
e = (Word32 -> Float) -> e -> ByteString -> (# Res e Float #)
forall a e. (Word32 -> a) -> e -> ByteString -> (# Res e a #)
x32HexFixed Word32 -> Float
castWord32ToFloat e
e

{-# INLINE x32HexFixed #-}
x32HexFixed :: (Word32 -> a) -> e -> B.ByteString -> (# Res e a #)
x32HexFixed :: forall a e. (Word32 -> a) -> e -> ByteString -> (# Res e a #)
x32HexFixed Word32 -> a
f e
e = ByteString -> (# Res e a #)
go
  where
    go :: ByteString -> (# Res e a #)
go ByteString
b
      | Just Word8
i0 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0), let !n0 :: Word32
n0 =        Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i0) Int
0x1C
      , Just Word8
i1 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
1), let !n1 :: Word32
n1 = Word32
n0 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i1) Int
0x18
      , Just Word8
i2 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
2), let !n2 :: Word32
n2 = Word32
n1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i2) Int
0x14
      , Just Word8
i3 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
3), let !n3 :: Word32
n3 = Word32
n2 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i3) Int
0x10
      , Just Word8
i4 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
4), let !n4 :: Word32
n4 = Word32
n3 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i4) Int
0x0C
      , Just Word8
i5 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
5), let !n5 :: Word32
n5 = Word32
n4 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i5) Int
0x08
      , Just Word8
i6 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
6), let !n6 :: Word32
n6 = Word32
n5 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i6) Int
0x04
      , Just Word8
i7 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
7), let !n7 :: Word32
n7 = Word32
n6 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|.               Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i7
          = let !r :: a
r = Word32 -> a
f Word32
n7
            in (# a -> Res e a
forall a e. a -> Res e a
Yes a
r #)

      | Bool
otherwise = (# e -> Res e a
forall e a. e -> Res e a
No e
e #)



i64HexFixed :: e -> B.ByteString -> (# Res e Int64 #)
i64HexFixed :: forall e. e -> ByteString -> (# Res e Int64 #)
i64HexFixed e
e = (Word64 -> Int64) -> e -> ByteString -> (# Res e Int64 #)
forall a e. (Word64 -> a) -> e -> ByteString -> (# Res e a #)
x64HexFixed Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral e
e

w64HexFixed :: e -> B.ByteString -> (# Res e Word64 #)
w64HexFixed :: forall e. e -> ByteString -> (# Res e Word64 #)
w64HexFixed e
e = (Word64 -> Word64) -> e -> ByteString -> (# Res e Word64 #)
forall a e. (Word64 -> a) -> e -> ByteString -> (# Res e a #)
x64HexFixed Word64 -> Word64
forall a. a -> a
id e
e

f64HexFixed :: e -> B.ByteString -> (# Res e Double #)
f64HexFixed :: forall e. e -> ByteString -> (# Res e Double #)
f64HexFixed e
e = (Word64 -> Double) -> e -> ByteString -> (# Res e Double #)
forall a e. (Word64 -> a) -> e -> ByteString -> (# Res e a #)
x64HexFixed Word64 -> Double
castWord64ToDouble e
e

{-# INLINE x64HexFixed #-}
x64HexFixed :: (Word64 -> a) -> e -> B.ByteString -> (# Res e a #)
x64HexFixed :: forall a e. (Word64 -> a) -> e -> ByteString -> (# Res e a #)
x64HexFixed Word64 -> a
f e
e = ByteString -> (# Res e a #)
go
  where
    go :: ByteString -> (# Res e a #)
go ByteString
b
      | Just Word8
i0 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x0), let !n0 :: Word64
n0 =        Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i0) Int
0x3C
      , Just Word8
i1 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x1), let !n1 :: Word64
n1 = Word64
n0 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i1) Int
0x38
      , Just Word8
i2 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x2), let !n2 :: Word64
n2 = Word64
n1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i2) Int
0x34
      , Just Word8
i3 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x3), let !n3 :: Word64
n3 = Word64
n2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i3) Int
0x30
      , Just Word8
i4 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x4), let !n4 :: Word64
n4 = Word64
n3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i4) Int
0x2C
      , Just Word8
i5 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x5), let !n5 :: Word64
n5 = Word64
n4 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i5) Int
0x28
      , Just Word8
i6 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x6), let !n6 :: Word64
n6 = Word64
n5 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i6) Int
0x24
      , Just Word8
i7 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x7), let !n7 :: Word64
n7 = Word64
n6 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i7) Int
0x20
      , Just Word8
i8 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x8), let !n8 :: Word64
n8 = Word64
n7 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i8) Int
0x1C
      , Just Word8
i9 <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0x9), let !n9 :: Word64
n9 = Word64
n8 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i9) Int
0x18
      , Just Word8
iA <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0xA), let !nA :: Word64
nA = Word64
n9 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
iA) Int
0x14
      , Just Word8
iB <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0xB), let !nB :: Word64
nB = Word64
nA Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
iB) Int
0x10
      , Just Word8
iC <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0xC), let !nC :: Word64
nC = Word64
nB Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
iC) Int
0x0C
      , Just Word8
iD <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0xD), let !nD :: Word64
nD = Word64
nC Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
iD) Int
0x08
      , Just Word8
iE <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0xE), let !nE :: Word64
nE = Word64
nD Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
unsafeShiftL (Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
iE) Int
0x04
      , Just Word8
iF <- Word8 -> Maybe Word8
hex (ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0xF), let !nF :: Word64
nF = Word64
nE Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.               Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
iF
          = let !r :: a
r = Word64 -> a
f Word64
nF
            in (# a -> Res e a
forall a e. a -> Res e a
Yes a
r #)

      | Bool
otherwise = (# e -> Res e a
forall e a. e -> Res e a
No e
e #)