packages feed

hinstaller-2007.4.23: src/System/Installer/Foreign.hs

module System.Installer.Foreign
where

import Foreign
import Foreign.C
import System.Directory
import System.FilePath
import System.IO
import Data.Word
import qualified Data.ByteString as B

writeCHeaderFile :: Handle -> String -> IO ()
writeCHeaderFile outH name
    = do { hPutStrLn outH lenDeclFuncSig
         ; hPutStrLn outH arrayDeclFuncSig
         }
    where
      lenDeclFuncSig = "const int " ++ name ++ "_length ();"
      arrayDeclFuncSig = "const unsigned char* " ++ name ++ " ();"

writeCFile :: Handle -> String -> B.ByteString -> FilePath -> IO ()
writeCFile outH name content header
    = do { hPutStrLn outH includeLine
         ; hPutStrLn outH lenDecl
         ; hPutStrLn outH arrayDecl
         ; mapM_ writeWord (B.unpack content)
         ; hPutStrLn outH tailDecl
         ; hPutStrLn outH lenDeclFunc
         ; hPutStrLn outH arrayDeclFunc
         }
    where
      len = show . B.length $ content
      includeLine = "#include \"" ++ header ++ "\""
      lenDecl = "const int " ++ name ++ "_length_raw = " ++ len ++ ";"
      arrayDecl = "const unsigned char " ++ name ++
                  "_raw[" ++ len ++ "] = {"
      tailDecl = "};"
      lenDeclFunc = "const int " ++ name ++ "_length () { return " ++
                    name ++ "_length_raw" ++ "; }"
      arrayDeclFunc = "const unsigned char* " ++ name ++ " () { return " ++
                      name ++ "_raw" ++ "; }"
      writeWord :: Word8 -> IO ()
      writeWord wrd = hPutStrLn outH numTxt
          where
            numTxt = (show wrd) ++ ","

convertFileToCHeader :: FilePath -> String -> IO (FilePath)
convertFileToCHeader file clauseName
    = do { (tmpFileHPath, tmpFileHHdl) <- openBinaryTempFile "" leafNameH
         ; writeCHeaderFile tmpFileHHdl clauseName
         ; hClose tmpFileHHdl
         ; contentsB <- B.readFile file
         ; (tmpFileCPath, tmpFileCHdl) <- openBinaryTempFile "" leafNameC
         ; writeCFile tmpFileCHdl clauseName contentsB tmpFileHPath
         ; hClose tmpFileCHdl
         ; return tmpFileCPath
         }
    where
      leafName = takeFileName file
      leafNameNoExts = dropExtensions leafName
      leafNameH = addExtension leafNameNoExts "h"
      leafNameC = addExtension leafNameNoExts "c"

writeFromPtrToFile :: Ptr CUChar -> Int -> FilePath -> IO ()
writeFromPtrToFile ptr len filePath
    = do { outH <- openBinaryFile filePath WriteMode
         ; hPutBuf outH ptr len
         ; hClose outH
         }

writeFileData :: Ptr CUChar -> CInt -> String -> FilePath -> IO ()
writeFileData ptr len origName path
    = do { isDir <- doesDirectoryExist path
         ; let path' = if isDir then combine path origName else path
         ; writeFromPtrToFile ptr (fromIntegral len) path'
         }