    {-# LINE 1 "Magic/Utils.hsc" #-}
    {- -*- Mode: haskell; -*-
    Haskell magic Interface
    Copyright (C) 2005 John Goerzen <jgoerzen@complete.org>

    This code is under a 3-clause BSD license; see COPYING for details.
    -}

    {- |
       Module     : Magic.Utils
       Copyright  : Copyright (C) 2005 John Goerzen
       License    : BSD

       Maintainer : John Goerzen,
       Maintainer : jgoerzen\@complete.org
       Stability  : provisional
       Portability: portable

    Utils

    Written by John Goerzen, jgoerzen\@complete.org
    -}

    module Magic.Utils (flaglist2int, fromMagicPtr, withMagicPtr, checkIntError,
                        throwErrorIfNull)
    where

    import Foreign
    import Foreign.C.Error
    import Foreign.C.String
    import Foreign.ForeignPtr
    import Magic.TypesLL
    import Magic.Types
    import Data.Bits
    import Foreign.C.Types
    import Magic.Data

    flaglist2int :: [MagicFlag] -> CInt
    flaglist2int :: [MagicFlag] -> CInt
    flaglist2int [MagicFlag]
    mfl =
        (CInt -> MagicFlag -> CInt) -> CInt -> [MagicFlag] -> CInt
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl (\CInt
    c MagicFlag
    f -> CInt
    c CInt -> CInt -> CInt
    forall a. Bits a => a -> a -> a
    .|. (Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> CInt) -> (MagicFlag -> Int) -> MagicFlag -> CInt
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MagicFlag -> Int
    forall a. Enum a => a -> Int
    fromEnum (MagicFlag -> CInt) -> MagicFlag -> CInt
    forall a b. (a -> b) -> a -> b
    $ MagicFlag
    f)) CInt
    0 [MagicFlag]
    mfl

    fromMagicPtr :: String -> IO (Ptr CMagic) -> IO Magic
    fromMagicPtr :: String -> IO (Ptr CMagic) -> IO Magic
    fromMagicPtr String
    caller IO (Ptr CMagic)
    action =
        do ptr <- String -> IO (Ptr CMagic) -> IO (Ptr CMagic)
    forall a. String -> IO (Ptr a) -> IO (Ptr a)
    throwErrnoIfNull String
    caller IO (Ptr CMagic)
    action
           newForeignPtr magic_close ptr

    throwErrorIfNull :: String -> Magic -> IO (Ptr a) -> IO (Ptr a)
    throwErrorIfNull :: forall a. String -> Magic -> IO (Ptr a) -> IO (Ptr a)
    throwErrorIfNull String
    caller Magic
    m IO (Ptr a)
    action =
        do res <- IO (Ptr a)
    action
           if res == nullPtr
              then throwError caller m
              else return res

    withMagicPtr :: Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr :: forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    m = Magic -> (Ptr CMagic -> IO a) -> IO a
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr Magic
    m

    throwError :: String -> Magic -> IO a
    throwError :: forall a. String -> Magic -> IO a
    throwError String
    caller Magic
    m = Magic -> (Ptr CMagic -> IO a) -> IO a
    forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    m (\Ptr CMagic
    cmagic ->
                   do errormsg <- Ptr CMagic -> IO CString
    magic_error Ptr CMagic
    cmagic
                      if errormsg /= nullPtr
                         then do em <- peekCString errormsg
                                 fail $ caller ++ ": " ++ em
                         else fail $ caller ++ ": got error code but no error message"
                                         )

    checkIntError :: String -> Magic -> IO CInt -> IO ()
    checkIntError :: String -> Magic -> IO CInt -> IO ()
    checkIntError String
    caller Magic
    m IO CInt
    action =
        do res <- IO CInt
    action
           if res == 0
              then return ()
              else throwError caller m

    foreign import ccall unsafe "magic.h &magic_close"
      magic_close :: FunPtr (Ptr CMagic -> IO ())

    foreign import ccall unsafe "magic.h magic_error"
      magic_error :: Ptr CMagic -> IO CString