pdftotext-0.0.1.0: src/Pdftotext/Foreign.hs
{-# LANGUAGE BlockArguments #-}
{- ORMOLU_DISABLE -}
{-|
Module : Pdftotext.Foreign
Description : Foreign interface
Copyright : (c) 2020 G. Eyaeb
License : BSD-3-Clause
Maintainer : geyaeb@protonmail.com
Stability : experimental
Portability : POSIX
-}
{- ORMOLU_ENABLE -}
module Pdftotext.Foreign
( -- * C++ objects
Poppler_Document,
Poppler_Page,
-- * 'std::string' helper
StdString,
asText,
stringToText,
-- * FFI
ffiOpenPdf,
ffiOpenData,
ffiDocumentDelete,
ffiDocumentPages,
ffiDocumentOpenPage,
ffiPageDelete,
ffiPageText,
ffiStringLength,
ffiStringDelete,
ffiStringCopy,
)
where
import qualified Data.Text as T
import qualified Data.Text.Foreign as T
import Foreign
import Foreign.C
data Poppler_Document
data Poppler_Page
data CStdString
type StdString = Ptr CStdString
foreign import ccall unsafe "poppler_document_open_pdf"
ffiOpenPdf :: CString -> IO (Ptr Poppler_Document)
foreign import ccall unsafe "poppler_document_open_data"
ffiOpenData :: Ptr Word8 -> CInt -> IO (Ptr Poppler_Document)
foreign import ccall unsafe "&poppler_document_delete"
ffiDocumentDelete :: FunPtr (Ptr Poppler_Document -> IO ())
foreign import ccall unsafe "poppler_document_pages"
ffiDocumentPages :: Ptr Poppler_Document -> IO CInt
foreign import ccall unsafe "poppler_document_open_page"
ffiDocumentOpenPage :: Ptr Poppler_Document -> CInt -> IO (Ptr Poppler_Page)
foreign import ccall unsafe "&poppler_page_delete"
ffiPageDelete :: FunPtr (Ptr Poppler_Page -> IO ())
foreign import ccall unsafe "poppler_page_text"
ffiPageText :: Ptr Poppler_Page -> CBool -> IO StdString
foreign import ccall unsafe "string_get_length"
ffiStringLength :: StdString -> IO CUInt
foreign import ccall unsafe "string_delete"
ffiStringDelete :: StdString -> IO ()
foreign import ccall unsafe "string_copy"
ffiStringCopy :: StdString -> Ptr CChar -> IO ()
-- | Converts `std::string` wrapped in IO into `Data.Text`.
asText :: IO StdString -> IO T.Text
asText = (>>= stringToText)
-- | Converts `std::string` into `Data.Text`.
stringToText :: StdString -> IO T.Text
stringToText ptr = do
len <- fromIntegral <$> ffiStringLength ptr
allocaBytes len \out ->
ffiStringCopy ptr out
>> T.peekCStringLen (out, len)
<* ffiStringDelete ptr