-- | Error handling functions. module Codec.Archive.LibZip.Errors ( errFromCInt , get_error , get_file_error , catchZipError ) where import Data.Typeable (Typeable, typeOf) import Foreign.C.Types import Foreign.Marshal.Alloc (alloca) import Foreign.Ptr (nullPtr) import Foreign.Storable (peek) import qualified Control.Exception as E import Bindings.LibZip import Codec.Archive.LibZip.Types errFromCInt :: CInt -> ZipError errFromCInt = toEnum . fromEnum get_error :: Zip -> IO ZipError get_error z | z == nullPtr = E.throwIO ErrINVAL get_error z = alloca $ \zep -> do c'zip_error_get z zep nullPtr peek zep >>= return . errFromCInt get_file_error :: ZipFile -> IO ZipError get_file_error zf | zf == nullPtr = E.throwIO ErrINVAL | otherwise = alloca $ \zep -> do c'zip_file_error_get zf zep nullPtr peek zep >>= return . errFromCInt -- | Wrapper to catch library errors. catchZipError :: IO a -> (ZipError -> IO a) -> IO a catchZipError f h = E.catchJust ifZipError f h where ifZipError :: (Typeable e, E.Exception e) => e -> Maybe e ifZipError x | typeOf x == typeOf ErrOK = Just x ifZipError _ | otherwise = Nothing