{-# LINE 1 "src/Magic/Init.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-3-Clause

   Maintainer : Philippe <philippedev101\@gmail.com>
   Stability  : provisional
   Portability: portable

Creating a magic handle and loading magic databases into it. A handle returned
by 'magicOpen' must be given a database with 'magicLoadDefault' or 'magicLoad'
before it can be queried with the functions in "Magic.Operations".

Written by John Goerzen.
-}

module Magic.Init(magicOpen, magicLoad, magicLoadDefault)
where

import Foreign.Ptr
import Foreign.C.String
import Magic.Types
import Foreign.C.Types
import Magic.Utils

{- | Create a new magic handle configured with the given flags (see
'MagicFlag'). Before querying anything you must load a database with
'magicLoadDefault' or 'magicLoad'.

The handle is freed automatically when it is garbage-collected. Raises an
'IOError' if the handle cannot be created.
-}
magicOpen :: [MagicFlag] -> IO Magic
magicOpen :: [MagicFlag] -> IO Magic
magicOpen [MagicFlag]
mfl =
    String -> IO (Ptr CMagic) -> IO Magic
fromMagicPtr String
"magicOpen" (CInt -> IO (Ptr CMagic)
magic_open CInt
flags)
    where flags :: CInt
flags = [MagicFlag] -> CInt
flaglist2int [MagicFlag]
mfl

{- | Load the system's default magic database into the handle. Raises an
'IOError' if the database cannot be loaded. -}
magicLoadDefault :: Magic -> IO ()
magicLoadDefault :: Magic -> IO ()
magicLoadDefault Magic
m = Magic -> (Ptr CMagic -> IO ()) -> IO ()
forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
withMagicPtr Magic
m (\Ptr CMagic
cmagic ->
    String -> Magic -> IO CInt -> IO ()
checkIntError String
"magicLoadDefault" Magic
m (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr CMagic -> CString -> IO CInt
magic_load Ptr CMagic
cmagic CString
forall a. Ptr a
nullPtr)

{- | Load the given magic database(s) into the handle. The argument may be a
single path or several colon-separated paths. Raises an 'IOError' if a database
cannot be loaded. -}
magicLoad :: Magic -> String -> IO ()
magicLoad :: Magic -> String -> IO ()
magicLoad Magic
m String
s = Magic -> (Ptr CMagic -> IO ()) -> IO ()
forall a. Magic -> (Ptr CMagic -> IO a) -> IO a
withMagicPtr Magic
m (\Ptr CMagic
cmagic ->
    String -> (CString -> IO ()) -> IO ()
forall a. String -> (CString -> IO a) -> IO a
withCString String
s (\CString
cs ->
     String -> Magic -> IO CInt -> IO ()
checkIntError String
"magicLoad" Magic
m (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr CMagic -> CString -> IO CInt
magic_load Ptr CMagic
cmagic CString
cs))
    
-- Allocates the cookie, no file I/O -> unsafe
foreign import ccall unsafe "magic.h magic_open"
  magic_open :: CInt -> IO (Ptr CMagic)

-- Reads and parses the (potentially multi-megabyte) magic database from disk:
-- blocking I/O, so this must be a safe call. A safe call lets other Haskell
-- threads run during the load and does not stall garbage collection, whereas
-- an unsafe call would block the capability for the whole load.
foreign import ccall safe "magic.h magic_load"
  magic_load :: Ptr CMagic -> CString -> IO CInt