packages feed

libmagic-1.3: 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 : Joey Hess,
   Maintainer : id\@joeyh.name
   Stability  : provisional
   Portability: portable

Operations for magic programs

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

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

import Foreign.Ptr
import Foreign.C.String
import Magic.Types
import Foreign.C.Types
import Data.Word
import Magic.Utils
import Magic.TypesLL
import System.OsPath.Types
import System.OsString.Internal.Types
import Data.Type.Coercion
import qualified Data.ByteString as BS
import qualified Data.ByteString.Short as SBS

{- | Calls the Magic system on the specified file. -}
magicFile :: Magic -> OsPath -> IO BS.ByteString
magicFile magic fp =
    withMagicPtr magic $ \cmagic ->
      SBS.useAsCString sbsfp $ \cfp -> do
        res <- throwErrorIfNull "magicFile" cmagic (magic_file cmagic cfp)
        BS.packCString res
  where
      sbsfp = case coercionToPlatformTypes of
        Left (_, co) -> getWindowsString (coerceWith co fp)
        Right (_, co) -> getPosixString (coerceWith co fp)

{- | Calls the Magic system on stdin. -}
magicStdin :: Magic -> IO BS.ByteString
magicStdin magic =
    withMagicPtr magic $ \cmagic ->
     do res <- throwErrorIfNull "magicStdin" cmagic (magic_file cmagic nullPtr)
        BS.packCString res

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

{- | Lower-level function used to call the Magic system to process a C 
string. -}
magicCString :: Magic -> CStringLen -> IO BS.ByteString
magicCString magic (cstr, len) =
    withMagicPtr magic $ \cmagic ->
     do res <- throwErrorIfNull "magicCString" cmagic (magic_buffer cmagic cstr (fromIntegral len))
        BS.packCString res

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

-- Does file I/O -> safe
foreign import ccall safe "magic.h magic_file"
  magic_file :: Ptr CMagic -> CString -> IO CString

-- Does not do I/O -> unsafe
foreign import ccall unsafe "magic.h magic_buffer"
  magic_buffer :: Ptr CMagic -> CString -> #{type size_t} -> IO CString

-- Does not do I/O -> unsafe
foreign import ccall unsafe "magic.h magic_setflags"
  magic_setflags :: Ptr CMagic -> CInt -> IO CInt