{-# LANGUAGE Trustworthy #-}

-- Copyright (C) 2019  Herbert Valerio Riedel
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

-- | @lzlib@ operations in the 'ST' monad
--
-- See respective functions in "Codec.Compression.Lzlib" for documentation where missing.
module Codec.Compression.Lzlib.ST
    ( -- * Compression functions
      LzEncoder
    , IO.CompressParams(..)
    , IO.compressParamPreset

    , lzCompressOpen
    , lzCompressClose
    , lzCompressRead
    , lzCompressWrite
    , lzCompressSyncFlush
    , lzCompressFinish
    , lzCompressFinished
    , lzCompressMemberFinished
    , lzCompressRestartMember

      -- * Decompression functions
    , LzDecoder

    , lzDecompressOpen
    , lzDecompressClose
    , lzDecompressRead
    , lzDecompressWrite
    , lzDecompressSyncToMember
    , lzDecompressFinish
    , lzDecompressFinished
    , lzDecompressMemberFinished
    , lzDecompressReset

      -- * Error codes
    , LzErrno(..)
    ) where

import           Codec.Compression.Lzlib (LzErrno (..))
import qualified Codec.Compression.Lzlib as IO
import           Internal                hiding (LzDecoder, LzEncoder)

----------------------------------------------------------------------------

newtype LzEncoder s = LzEncoder IO.LzEncoder

lzCompressOpen :: IO.CompressParams -> ST s (Either LzErrno (LzEncoder s))
lzCompressOpen :: CompressParams -> ST s (Either LzErrno (LzEncoder s))
lzCompressOpen p :: CompressParams
p = IO (Either LzErrno (LzEncoder s))
-> ST s (Either LzErrno (LzEncoder s))
forall a s. IO a -> ST s a
unsafeIOToST ((LzEncoder -> LzEncoder s)
-> Either LzErrno LzEncoder -> Either LzErrno (LzEncoder s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LzEncoder -> LzEncoder s
forall s. LzEncoder -> LzEncoder s
LzEncoder (Either LzErrno LzEncoder -> Either LzErrno (LzEncoder s))
-> IO (Either LzErrno LzEncoder)
-> IO (Either LzErrno (LzEncoder s))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CompressParams -> IO (Either LzErrno LzEncoder)
IO.lzCompressOpen CompressParams
p)

lzCompressClose :: LzEncoder s -> ST s ()
lzCompressClose :: LzEncoder s -> ST s ()
lzCompressClose (LzEncoder lze :: LzEncoder
lze) = IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> IO ()
IO.lzCompressClose LzEncoder
lze)

lzCompressWrite :: LzEncoder s -> ByteString -> ST s Int
lzCompressWrite :: LzEncoder s -> ByteString -> ST s Int
lzCompressWrite (LzEncoder lze :: LzEncoder
lze) ibs :: ByteString
ibs = IO Int -> ST s Int
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> ByteString -> IO Int
IO.lzCompressWrite LzEncoder
lze ByteString
ibs)

lzCompressRead :: LzEncoder s -> Int -> ST s ByteString
lzCompressRead :: LzEncoder s -> Int -> ST s ByteString
lzCompressRead (LzEncoder lze :: LzEncoder
lze) bufsize :: Int
bufsize = IO ByteString -> ST s ByteString
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> Int -> IO ByteString
IO.lzCompressRead LzEncoder
lze Int
bufsize)

lzCompressFinish :: LzEncoder s -> ST s LzErrno
lzCompressFinish :: LzEncoder s -> ST s LzErrno
lzCompressFinish (LzEncoder lze :: LzEncoder
lze) = IO LzErrno -> ST s LzErrno
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> IO LzErrno
IO.lzCompressFinish LzEncoder
lze)

lzCompressRestartMember :: LzEncoder s -> Word64 -> ST s LzErrno
lzCompressRestartMember :: LzEncoder s -> Word64 -> ST s LzErrno
lzCompressRestartMember (LzEncoder lze :: LzEncoder
lze) msize :: Word64
msize = IO LzErrno -> ST s LzErrno
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> Word64 -> IO LzErrno
IO.lzCompressRestartMember LzEncoder
lze Word64
msize)

lzCompressSyncFlush :: LzEncoder s -> ST s LzErrno
lzCompressSyncFlush :: LzEncoder s -> ST s LzErrno
lzCompressSyncFlush (LzEncoder lze :: LzEncoder
lze) = IO LzErrno -> ST s LzErrno
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> IO LzErrno
IO.lzCompressSyncFlush LzEncoder
lze)

lzCompressFinished :: LzEncoder s -> ST s Bool
lzCompressFinished :: LzEncoder s -> ST s Bool
lzCompressFinished (LzEncoder lze :: LzEncoder
lze) = IO Bool -> ST s Bool
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> IO Bool
IO.lzCompressFinished LzEncoder
lze)

lzCompressMemberFinished :: LzEncoder s -> ST s Bool
lzCompressMemberFinished :: LzEncoder s -> ST s Bool
lzCompressMemberFinished (LzEncoder lze :: LzEncoder
lze) = IO Bool -> ST s Bool
forall a s. IO a -> ST s a
unsafeIOToST (LzEncoder -> IO Bool
IO.lzCompressMemberFinished LzEncoder
lze)

----------------------------------------------------------------------------

newtype LzDecoder s = LzDecoder IO.LzDecoder

lzDecompressOpen :: ST s (Either LzErrno (LzDecoder s))
lzDecompressOpen :: ST s (Either LzErrno (LzDecoder s))
lzDecompressOpen = IO (Either LzErrno (LzDecoder s))
-> ST s (Either LzErrno (LzDecoder s))
forall a s. IO a -> ST s a
unsafeIOToST ((LzDecoder -> LzDecoder s)
-> Either LzErrno LzDecoder -> Either LzErrno (LzDecoder s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LzDecoder -> LzDecoder s
forall s. LzDecoder -> LzDecoder s
LzDecoder (Either LzErrno LzDecoder -> Either LzErrno (LzDecoder s))
-> IO (Either LzErrno LzDecoder)
-> IO (Either LzErrno (LzDecoder s))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (Either LzErrno LzDecoder)
IO.lzDecompressOpen)

lzDecompressClose :: LzDecoder s -> ST s ()
lzDecompressClose :: LzDecoder s -> ST s ()
lzDecompressClose (LzDecoder lze :: LzDecoder
lze) = IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> IO ()
IO.lzDecompressClose LzDecoder
lze)

lzDecompressWrite :: LzDecoder s -> ByteString -> ST s Int
lzDecompressWrite :: LzDecoder s -> ByteString -> ST s Int
lzDecompressWrite (LzDecoder lze :: LzDecoder
lze) ibs :: ByteString
ibs = IO Int -> ST s Int
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> ByteString -> IO Int
IO.lzDecompressWrite LzDecoder
lze ByteString
ibs)

lzDecompressRead :: LzDecoder s -> Int -> ST s ByteString
lzDecompressRead :: LzDecoder s -> Int -> ST s ByteString
lzDecompressRead (LzDecoder lze :: LzDecoder
lze) bufsize :: Int
bufsize = IO ByteString -> ST s ByteString
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> Int -> IO ByteString
IO.lzDecompressRead LzDecoder
lze Int
bufsize)

lzDecompressFinish :: LzDecoder s -> ST s LzErrno
lzDecompressFinish :: LzDecoder s -> ST s LzErrno
lzDecompressFinish (LzDecoder lze :: LzDecoder
lze) = IO LzErrno -> ST s LzErrno
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> IO LzErrno
IO.lzDecompressFinish LzDecoder
lze)

lzDecompressReset :: LzDecoder s -> ST s LzErrno
lzDecompressReset :: LzDecoder s -> ST s LzErrno
lzDecompressReset (LzDecoder lze :: LzDecoder
lze) = IO LzErrno -> ST s LzErrno
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> IO LzErrno
IO.lzDecompressReset LzDecoder
lze)

lzDecompressSyncToMember :: LzDecoder s -> ST s LzErrno
lzDecompressSyncToMember :: LzDecoder s -> ST s LzErrno
lzDecompressSyncToMember (LzDecoder lze :: LzDecoder
lze) = IO LzErrno -> ST s LzErrno
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> IO LzErrno
IO.lzDecompressSyncToMember LzDecoder
lze)

lzDecompressFinished :: LzDecoder s -> ST s Bool
lzDecompressFinished :: LzDecoder s -> ST s Bool
lzDecompressFinished (LzDecoder lze :: LzDecoder
lze) = IO Bool -> ST s Bool
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> IO Bool
IO.lzDecompressFinished LzDecoder
lze)

lzDecompressMemberFinished :: LzDecoder s -> ST s Bool
lzDecompressMemberFinished :: LzDecoder s -> ST s Bool
lzDecompressMemberFinished (LzDecoder lze :: LzDecoder
lze) = IO Bool -> ST s Bool
forall a s. IO a -> ST s a
unsafeIOToST (LzDecoder -> IO Bool
IO.lzDecompressMemberFinished LzDecoder
lze)