    {-# LINE 1 "Magic/Operations.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.Init
       Copyright  : Copyright (C) 2005 John Goerzen
       License    : BSD

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

    Initialization and shutdown for magic programs

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

    module Magic.Operations(-- * Guessing the type
                            magicFile, magicStdin,
                            magicString, magicCString,
                            -- * Other operations
                            magicSetFlags, magicCompile)
    where

    import Foreign.Ptr
    import Foreign.C.String
    import Magic.Types
    import Foreign.C.Types
    import Data.Word
    import Foreign.C.String
    import Foreign.C.Error
    import Magic.Utils
    import Magic.TypesLL
    import Foreign.Marshal.Utils

    {- | Calls the Magic system on the specified file. -}
    magicFile :: Magic -> FilePath -> IO String
    magicFile :: Magic -> FilePath -> IO FilePath
    magicFile Magic
    magic FilePath
    fp =
        Magic -> (Ptr CMagic -> IO FilePath) -> IO FilePath
    forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    magic (\Ptr CMagic
    cmagic ->
        FilePath -> (CString -> IO FilePath) -> IO FilePath
    forall a. FilePath -> (CString -> IO a) -> IO a
    withCString FilePath
    fp (\CString
    cfp ->
         do res <- FilePath -> Magic -> IO CString -> IO CString
    forall a. FilePath -> Magic -> IO (Ptr a) -> IO (Ptr a)
    throwErrorIfNull FilePath
    "magicFile" Magic
    magic (Ptr CMagic -> CString -> IO CString
    magic_file Ptr CMagic
    cmagic CString
    cfp)
            peekCString res
                        )
                           )

    {- | Calls the Magic system on stdin. -}
    magicStdin :: Magic -> IO String
    magicStdin :: Magic -> IO FilePath
    magicStdin Magic
    magic =
        Magic -> (Ptr CMagic -> IO FilePath) -> IO FilePath
    forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    magic (\Ptr CMagic
    cmagic ->
         do res <- FilePath -> Magic -> IO CString -> IO CString
    forall a. FilePath -> Magic -> IO (Ptr a) -> IO (Ptr a)
    throwErrorIfNull FilePath
    "magicStdin" Magic
    magic (Ptr CMagic -> CString -> IO CString
    magic_file Ptr CMagic
    cmagic CString
    forall a. Ptr a
    nullPtr)
            peekCString res
                           )

    {- | Calls the Magic system to process the given String.  Please note:
    it is not evaluated lazily. -}
    magicString :: Magic -> String -> IO String
    magicString :: Magic -> FilePath -> IO FilePath
    magicString Magic
    m FilePath
    s = FilePath -> (CStringLen -> IO FilePath) -> IO FilePath
    forall a. FilePath -> (CStringLen -> IO a) -> IO a
    withCStringLen FilePath
    s (Magic -> CStringLen -> IO FilePath
    magicCString Magic
    m)

    {- | Lower-level function used to call the Magic system to process a C
    string. -}
    magicCString :: Magic -> CStringLen -> IO String
    magicCString :: Magic -> CStringLen -> IO FilePath
    magicCString Magic
    magic (CString
    cstr, Int
    len) =
        Magic -> (Ptr CMagic -> IO FilePath) -> IO FilePath
    forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    magic (\Ptr CMagic
    cmagic ->
         do res <- FilePath -> Magic -> IO CString -> IO CString
    forall a. FilePath -> Magic -> IO (Ptr a) -> IO (Ptr a)
    throwErrorIfNull FilePath
    "magicCString" Magic
    magic (Ptr CMagic -> CString -> Word64 -> IO CString
    magic_buffer Ptr CMagic
    cmagic CString
    cstr (Int -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    len))
            peekCString res
                        )

    {- | Change the flags on an already-created object. -}
    magicSetFlags :: Magic -> [MagicFlag] -> IO ()
    magicSetFlags :: Magic -> [MagicFlag] -> IO ()
    magicSetFlags Magic
    m [MagicFlag]
    mfl = Magic -> (Ptr CMagic -> IO ()) -> IO ()
    forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    m (\Ptr CMagic
    cmagic ->
         FilePath -> Magic -> IO CInt -> IO ()
    checkIntError FilePath
    "magicSetFlags" Magic
    m (IO CInt -> IO ()) -> IO CInt -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr CMagic -> CInt -> IO CInt
    magic_setflags Ptr CMagic
    cmagic CInt
    flags)
        where flags :: CInt
    flags = [MagicFlag] -> CInt
    flaglist2int [MagicFlag]
    mfl

    {- | Compile the colon-separated list of database file(s).  The compiled files
    created have .mgc added to the names of the argument.
    -}
    magicCompile :: Magic           -- ^ Object to use
                 -> Maybe String    -- ^ Colon separated list of databases, or Nothing for default
                 -> IO ()
    magicCompile :: Magic -> Maybe FilePath -> IO ()
    magicCompile Magic
    m Maybe FilePath
    mstr = Magic -> (Ptr CMagic -> IO ()) -> IO ()
    forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
    withMagicPtr Magic
    m (\Ptr CMagic
    cm ->
         case Maybe FilePath
    mstr of
                   Maybe FilePath
    Nothing -> Ptr CMagic -> CString -> IO ()
    worker Ptr CMagic
    cm CString
    forall a. Ptr a
    nullPtr
                   Just FilePath
    x -> FilePath -> (CString -> IO ()) -> IO ()
    forall a. FilePath -> (CString -> IO a) -> IO a
    withCString FilePath
    x (Ptr CMagic -> CString -> IO ()
    worker Ptr CMagic
    cm)
                                         )
        where worker :: Ptr CMagic -> CString -> IO ()
    worker Ptr CMagic
    cm CString
    cs = FilePath -> Magic -> IO CInt -> IO ()
    checkIntError FilePath
    "magicCompile" Magic
    m (IO CInt -> IO ()) -> IO CInt -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Ptr CMagic -> CString -> IO CInt
    magic_compile Ptr CMagic
    cm CString
    cs

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

    foreign import ccall unsafe "magic.h magic_buffer"
      magic_buffer :: Ptr CMagic -> CString -> Word64 -> IO CString
    {-# LINE 97 "Magic/Operations.hsc" #-}

    foreign import ccall unsafe "magic.h magic_setflags"
      magic_setflags :: Ptr CMagic -> CInt -> IO CInt

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