{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE InstanceSigs #-}
module Codec.LEB128.List
( fromULEB128
, fromSLEB128
, toULEB128
, toSLEB128
)
where
import Data.Word
import GHC.Magic
import Control.Monad.Trans.State.Strict
import Codec.LEB128.Constraints
import Codec.LEB128.Generic as G
{-# INLINEABLE toULEB128 #-}
toULEB128 :: LEB128 a => a -> [Word8]
toULEB128 = (inline G.encodeLEB128) pure
{-# INLINEABLE toSLEB128 #-}
toSLEB128 :: SLEB128 a => a -> [Word8]
toSLEB128 = (inline G.encodeSLEB128) pure
type ByteProvider a = State [Word8] a
{-# INLINE getByte #-}
getByte :: ByteProvider Word8
getByte = do
wds <- get
case wds of
[] -> error "decode LEB128: Not enough bytes"
(x:xs) -> put xs >> return x
{-# INLINEABLE fromULEB128 #-}
fromULEB128 :: LEB128 a => [Word8] -> (a,[Word8])
fromULEB128 = runState ((inline G.decodeLEB128) getByte)
{-# INLINEABLE fromSLEB128 #-}
fromSLEB128 :: SLEB128 a => [Word8] -> (a,[Word8])
fromSLEB128 = runState ((inline G.decodeSLEB128) getByte)