module Data.Avro.Internal.DecodeRaw
  ( DecodeRaw(..)
  ) where

import Data.Avro.Internal.Zag
import Data.Binary.Get
import Data.Bits
import Data.Int
import Data.List
import Data.Word

getNonNegative :: (Bits i, Integral i) => Get i
getNonNegative :: forall i. (Bits i, Integral i) => Get i
getNonNegative = do
  [Word8]
orig <- Get [Word8]
getWord8s
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\i
a Word8
x -> (i
a forall a. Bits a => a -> Int -> a
`shiftL` Int
7) forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x) i
0 (forall a. [a] -> [a]
reverse [Word8]
orig)

getWord8s :: Get [Word8]
getWord8s :: Get [Word8]
getWord8s = do
  Word8
w <- Get Word8
getWord8
  let msb :: Bool
msb = Word8
w forall a. Bits a => a -> Int -> Bool
`testBit` Int
7 in (Word8
w forall a. Bits a => a -> a -> a
.&. Word8
0x7F forall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> if Bool
msb
    then Get [Word8]
getWord8s
    else forall (m :: * -> *) a. Monad m => a -> m a
return []

class DecodeRaw a where
  decodeRaw :: Get a

instance DecodeRaw Word where
  decodeRaw :: Get Word
decodeRaw = forall i. (Bits i, Integral i) => Get i
getNonNegative
  {-# INLINE decodeRaw #-}

instance DecodeRaw Word8 where
  decodeRaw :: Get Word8
decodeRaw = forall i. (Bits i, Integral i) => Get i
getNonNegative
  {-# INLINE decodeRaw #-}

instance DecodeRaw Word16 where
  decodeRaw :: Get Word16
decodeRaw = forall i. (Bits i, Integral i) => Get i
getNonNegative
  {-# INLINE decodeRaw #-}

instance DecodeRaw Word32 where
  decodeRaw :: Get Word32
decodeRaw = forall i. (Bits i, Integral i) => Get i
getNonNegative
  {-# INLINE decodeRaw #-}

instance DecodeRaw Word64 where
  decodeRaw :: Get Word64
decodeRaw = forall i. (Bits i, Integral i) => Get i
getNonNegative
  {-# INLINE decodeRaw #-}

instance DecodeRaw Int where
  decodeRaw :: Get Int
decodeRaw = forall a. Zag a => a -> Zagged a
zag forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. DecodeRaw a => Get a
decodeRaw :: Get Word)
  {-# INLINE decodeRaw #-}

instance DecodeRaw Int8 where
  decodeRaw :: Get Int8
decodeRaw = forall a. Zag a => a -> Zagged a
zag forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. DecodeRaw a => Get a
decodeRaw :: Get Word8)
  {-# INLINE decodeRaw #-}

instance DecodeRaw Int16 where
  decodeRaw :: Get Int16
decodeRaw = forall a. Zag a => a -> Zagged a
zag forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. DecodeRaw a => Get a
decodeRaw :: Get Word16)
  {-# INLINE decodeRaw #-}

instance DecodeRaw Int32 where
  decodeRaw :: Get Int32
decodeRaw = forall a. Zag a => a -> Zagged a
zag forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. DecodeRaw a => Get a
decodeRaw :: Get Word32)
  {-# INLINE decodeRaw #-}

instance DecodeRaw Int64 where
  decodeRaw :: Get Int64
decodeRaw = forall a. Zag a => a -> Zagged a
zag forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. DecodeRaw a => Get a
decodeRaw :: Get Word64)
  {-# INLINE decodeRaw #-}