-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A collection of tools for processing PDF files.
--   
--   Low level tools for processing PDF files.
--   
--   Level of abstraction: cross reference, trailer, indirect object,
--   object
--   
--   The API is based on random access input streams, and is designed to be
--   memory efficient. We don't need to parse the entire PDF file and store
--   it in memory when you need just one page or two. Usually it is also
--   leads to time efficiency, but we don't try optimize performance by
--   e.g. maintaining xref or object cache. Higher level layers should take
--   care of it.
--   
--   The library is low level. It may mean that you need to be familiar
--   with PDF file internals to actually use it.
@package pdf-toolbox-core
@version 0.0.4.1


-- | Utils
module Pdf.Toolbox.Core.Parsers.Util

-- | In pdf file EOL could be "\n", "\r" or "\n\r"
--   
--   Also space (0x20) is usually ok before EOL
endOfLine :: Parser ()


-- | Module contains definitions of pdf objects
--   
--   See PDF1.7:7.3
module Pdf.Toolbox.Core.Object.Types

-- | Any pdf object
--   
--   It is parameterized by <a>Stream</a> content
data Object a
ONumber :: Number -> Object a
OBoolean :: Boolean -> Object a
OName :: Name -> Object a
ODict :: Dict -> Object a
OArray :: Array -> Object a
OStr :: Str -> Object a
OStream :: (Stream a) -> Object a
ORef :: Ref -> Object a
ONull :: Object a

-- | Integer or real
data Number
NumInt :: Int -> Number
NumReal :: Double -> Number

-- | "true" or "false"
newtype Boolean
Boolean :: Bool -> Boolean

-- | Names usually are used as keys in dictionaries
--   
--   They starts with '/', but we strip it out, see <a>parseName</a>
newtype Name
Name :: ByteString -> Name

-- | Set of key/value pairs
newtype Dict
Dict :: [(Name, Object ())] -> Dict

-- | An array
newtype Array
Array :: [Object ()] -> Array

-- | Sequence of zero or more bytes
--   
--   Represents both the literal and hexadecimal strings
newtype Str
Str :: ByteString -> Str

-- | Contains stream dictionary and a payload
--   
--   The payload could be offset within pdf file, actual content, content
--   stream or nothing
data Stream a
Stream :: Dict -> a -> Stream a

-- | Object reference, contains object index and generation
data Ref
Ref :: Int -> Int -> Ref
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Array
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Array
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Dict
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Dict
instance GHC.Show.Show a => GHC.Show.Show (Pdf.Toolbox.Core.Object.Types.Stream a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Pdf.Toolbox.Core.Object.Types.Stream a)
instance GHC.Show.Show a => GHC.Show.Show (Pdf.Toolbox.Core.Object.Types.Object a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Pdf.Toolbox.Core.Object.Types.Object a)
instance GHC.Classes.Ord Pdf.Toolbox.Core.Object.Types.Ref
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Ref
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Ref
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Str
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Str
instance GHC.Base.Monoid Pdf.Toolbox.Core.Object.Types.Name
instance GHC.Classes.Ord Pdf.Toolbox.Core.Object.Types.Name
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Name
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Name
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Boolean
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Boolean
instance GHC.Show.Show Pdf.Toolbox.Core.Object.Types.Number
instance GHC.Classes.Eq Pdf.Toolbox.Core.Object.Types.Number
instance Data.String.IsString Pdf.Toolbox.Core.Object.Types.Name
instance Data.String.IsString Pdf.Toolbox.Core.Object.Types.Str


-- | This module contains parsers for pdf objects
module Pdf.Toolbox.Core.Parsers.Object

-- | It parses any <a>Object</a> except <a>Stream</a> cos for <a>Stream</a>
--   we need offset of data in file
--   
--   <pre>
--   &gt;&gt;&gt; parseOnly parseObject "/Name"
--   Right (OName (Name "Name"))
--   </pre>
parseObject :: Parser (Object ())

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseDict "&lt;&lt;/Key1(some string)/Key2 123&gt;&gt;"
--   Right (Dict [(Name "Key1",OStr (Str "some string")),(Name "Key2",ONumber (NumInt 123))])
--   </pre>
parseDict :: Parser Dict

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseArray "[1 (string) /Name []]"
--   Right (Array [ONumber (NumInt 1),OStr (Str "string"),OName (Name "Name"),OArray (Array [])])
--   </pre>
parseArray :: Parser Array

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseName "/Name"
--   Right (Name "Name")
--   </pre>
parseName :: Parser Name

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseStr "(hello)"
--   Right (Str "hello")
--   </pre>
parseStr :: Parser Str

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseHexStr "&lt;68656C6C6F&gt;"
--   Right (Str "hello")
--   </pre>
parseHexStr :: Parser Str

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseRef "0 2 R"
--   Right (Ref 0 2)
--   </pre>
parseRef :: Parser Ref

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseNumber "123"
--   Right (NumInt 123)
--   
--   &gt;&gt;&gt; parseOnly parseNumber "12.3"
--   Right (NumReal 12.3)
--   
--   &gt;&gt;&gt; parseOnly parseNumber ".01"
--   Right (NumReal 1.0e-2)
--   </pre>
parseNumber :: Parser Number

-- | <pre>
--   &gt;&gt;&gt; parseOnly parseBoolean "true"
--   Right (Boolean True)
--   
--   &gt;&gt;&gt; parseOnly parseBoolean "false"
--   Right (Boolean False)
--   </pre>
parseBoolean :: Parser Boolean

-- | Consumes input till stream's data
--   
--   Use <a>parseDict</a> then <a>parseTillStreamData</a> to determine
--   whether the object is dictionary or stream. If
--   <a>parseTillStreamData</a> fails, then it is a dictionary. Otherwise
--   it is stream, and current position in input data will point to
--   stream's data start
--   
--   <pre>
--   &gt;&gt;&gt; parse (parseDict &gt;&gt;= \dict -&gt; parseTillStreamData &gt;&gt; return dict) "&lt;&lt;/Key 123&gt;&gt;\nstream\n1234\nendstream"
--   Done "1234\nendstream" Dict [(Name "Key",ONumber (NumInt 123))]
--   </pre>
parseTillStreamData :: Parser ()

-- | Parse object. Input position should point to offset defined in XRef
--   
--   <pre>
--   &gt;&gt;&gt; parseOnly parseIndirectObject "1 2 obj\n12"
--   Right (Ref 1 2,ONumber (NumInt 12))
--   </pre>
parseIndirectObject :: Parser (Ref, Object ())

-- | Whether the character can appear in <a>Name</a>
isRegularChar :: Char -> Bool


-- | Parsers for XRef
module Pdf.Toolbox.Core.Parsers.XRef

-- | Offset of the very last xref table
--   
--   Before calling it, make sure your are currently somewhere near the end
--   of pdf file. Otherwice it can eat all the memory. E.g. examine only
--   the last 1KB
--   
--   <pre>
--   &gt;&gt;&gt; parseOnly startXRef "anything...startxref\n222\n%%EOF...blah\nstartxref\n123\n%%EOF"
--   Right 123
--   </pre>
startXRef :: Parser Int64

-- | When current input position points to xref stream (or doesn't point to
--   xref at all), the parser will fail. When it points to xref table, the
--   parser will succeed and input position will point to the first xref
--   subsection
--   
--   <pre>
--   &gt;&gt;&gt; parseOnly tableXRef "xref\n"
--   Right ()
--   
--   &gt;&gt;&gt; parseOnly tableXRef "not xref"
--   Left "Failed reading: takeWith"
--   </pre>
tableXRef :: Parser ()

-- | Parse subsection header, return (the first object index, number of
--   object)
--   
--   Input position will point to the first object
parseSubsectionHeader :: Parser (Int, Int)

-- | Parse trailer located after XRef table
--   
--   Input position should point to the "trailer" keyword
parseTrailerAfterTable :: Parser Dict

-- | Parse XRef table entry. Returns offset, generation and whether the
--   object is free.
parseTableEntry :: Parser (Int64, Int, Bool)


-- | Render <a>Object</a> to bytestring
module Pdf.Toolbox.Core.Object.Builder

-- | Build indirect object
buildIndirectObject :: Ref -> Object ByteString -> Builder

-- | Render inline object (without "obj/endobj"). It is <a>error</a> to
--   supply <a>Stream</a>, because it could not be inlined, but should
--   always be an indirect object
buildObject :: Object a -> Builder
buildNumber :: Number -> Builder
buildBoolean :: Boolean -> Builder
buildName :: Name -> Builder
buildDict :: Dict -> Builder
buildArray :: Array -> Builder
buildStr :: Str -> Builder
buildRef :: Ref -> Builder
buildStream :: Stream ByteString -> Builder


-- | Write PDF files
--   
--   It could be used to generate new PDF file or to incrementally update
--   the existent one
--   
--   To generate new file, first call <a>writePdfHeader</a>, then a number
--   of <a>writeObject</a> and finally <a>writeXRefTable</a>
--   
--   To incrementally update PDF file just ommit the <a>writePdfHeader</a>
--   and append the result to the existent file
module Pdf.Toolbox.Core.Writer

-- | The monad
data PdfWriter m a

-- | Execute writer action
runPdfWriter :: MonadIO m => OutputStream ByteString -> PdfWriter m a -> m a

-- | Write PDF header. Used for generating new PDF files. Should be the
--   first call. Not used fo incremental updates
writePdfHeader :: MonadIO m => PdfWriter m ()

-- | Write object
writeObject :: MonadIO m => Ref -> Object ByteString -> PdfWriter m ()

-- | Delete object
deleteObject :: MonadIO m => Ref -> Int64 -> PdfWriter m ()

-- | Write xref table. Should be the last call. Used for generating and
--   incremental updates.
writeXRefTable :: MonadIO m => Int64 -> Dict -> PdfWriter m ()
instance Control.Monad.Trans.Class.MonadTrans Pdf.Toolbox.Core.Writer.PdfWriter
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Pdf.Toolbox.Core.Writer.PdfWriter m)
instance GHC.Base.Monad m => GHC.Base.Monad (Pdf.Toolbox.Core.Writer.PdfWriter m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Pdf.Toolbox.Core.Writer.PdfWriter m)
instance GHC.Base.Functor m => GHC.Base.Functor (Pdf.Toolbox.Core.Writer.PdfWriter m)
instance GHC.Classes.Eq Pdf.Toolbox.Core.Writer.Elem
instance GHC.Classes.Ord Pdf.Toolbox.Core.Writer.Elem


-- | Input stream with random access
module Pdf.Toolbox.Core.IO.RIS

-- | Sequential input stream
type IS = InputStream ByteString

-- | Random access Input Stream
newtype RIS
RIS :: (IORef RIS') -> RIS

-- | Internal state of <a>RIS</a>
data RIS'
RIS' :: (Int64 -> IO (IO (Maybe ByteString))) -> IS -> IO Int64 -> Int64 -> RIS'
[risSeek] :: RIS' -> Int64 -> IO (IO (Maybe ByteString))
[risInputStream] :: RIS' -> IS
[risPos] :: RIS' -> IO Int64
[risSize] :: RIS' -> Int64

-- | Seek the stream
seek :: RIS -> Int64 -> IO ()

-- | Number of bytes in the stream
size :: RIS -> IO Int64

-- | Current position in bytes
tell :: RIS -> IO Int64

-- | Get sequential input stream, that is valid until the next <a>seek</a>
inputStream :: RIS -> IO IS

-- | Create RIS from <a>Handle</a> with default chunk size
fromHandle :: Handle -> IO RIS

-- | Create RIS from <a>Handle</a> with the specified chunk size
fromHandle' :: Handle -> Int -> IO RIS


-- | Error used by API
module Pdf.Toolbox.Core.Error

-- | Errors
data PdfError

-- | Parser error
ParseError :: [String] -> String -> PdfError
IOError :: IOError -> PdfError
AnnotatedError :: String -> PdfError -> PdfError

-- | Something unexpected
UnexpectedError :: String -> PdfError

-- | API uses this for error handling
type PdfE m = ExceptT PdfError m

-- | Wrap any <a>PdfError</a> into <a>AnnotatedError</a>
--   
--   Usefull when you want to add high-level description to error, returned
--   by low-level function
annotateError :: Monad m => String -> PdfE m a -> PdfE m a

-- | <a>annotateError</a> with fliped arguments
annotatingError :: Monad m => PdfE m a -> String -> PdfE m a

-- | Catch exception if any and convert to <a>IOError</a>
tryPdfIO :: MonadIO m => IO a -> PdfE m a
instance GHC.Show.Show Pdf.Toolbox.Core.Error.PdfError


-- | Basic IO operations for PDF
module Pdf.Toolbox.Core.IO

-- | Sequential input stream
type IS = InputStream ByteString

-- | Random access Input Stream
data RIS

-- | Create RIS from <a>Handle</a> with default chunk size
fromHandle :: Handle -> IO RIS

-- | Create RIS from <a>Handle</a> with the specified chunk size
fromHandle' :: Handle -> Int -> IO RIS

-- | Monads in which <a>IO</a> computations may be embedded. Any monad
--   built by applying a sequence of monad transformers to the <a>IO</a>
--   monad will be an instance of this class.
--   
--   Instances should satisfy the following laws, which state that
--   <a>liftIO</a> is a transformer of monads:
--   
--   <ul>
--   <li><pre><a>liftIO</a> . <a>return</a> = <a>return</a></pre></li>
--   <li><pre><a>liftIO</a> (m &gt;&gt;= f) = <a>liftIO</a> m &gt;&gt;=
--   (<a>liftIO</a> . f)</pre></li>
--   </ul>
class Monad m => MonadIO (m :: * -> *)

-- | Lift a computation from the <a>IO</a> monad.
liftIO :: MonadIO m => IO a -> m a

-- | Lift a computation from the <a>IO</a> monad.
liftIO :: MonadIO m => forall a. IO a -> m a

-- | Total number of bytes in <a>RIS</a>
size :: MonadIO m => RIS -> PdfE m Int64

-- | Change input position in <a>RIS</a>
seek :: MonadIO m => RIS -> Int64 -> PdfE m ()

-- | Current input position
tell :: MonadIO m => RIS -> PdfE m Int64

-- | Parse from <a>IS</a>
parse :: MonadIO m => Parser r -> IS -> PdfE m r

-- | Convert random access stream to sequential
inputStream :: MonadIO m => RIS -> PdfE m IS

-- | See <a>takeBytes</a>
takeBytes :: MonadIO m => Int64 -> IS -> PdfE m IS

-- | See <a>readExactly</a>
readExactly :: MonadIO m => Int -> IS -> PdfE m ByteString

-- | Same as <a>readExactly</a>, but ignores the result
dropExactly :: MonadIO m => Int -> IS -> PdfE m ()


-- | Stream filter
module Pdf.Toolbox.Core.Stream.Filter.Type

-- | Stream filter
data StreamFilter
StreamFilter :: Name -> (Maybe Dict -> IS -> IO IS) -> StreamFilter

-- | as "Filter" key value in stream dictionary
[filterName] :: StreamFilter -> Name

-- | decode params -&gt; content -&gt; decoded content
[filterDecode] :: StreamFilter -> Maybe Dict -> IS -> IO IS

-- | Exception that should be thrown by the decoder in case of any error
--   User code could catch it when reading from decoded stream content
data DecodeException
DecodeException :: (SomeException) -> DecodeException
instance GHC.Show.Show Pdf.Toolbox.Core.Stream.Filter.Type.DecodeException
instance GHC.Exception.Exception Pdf.Toolbox.Core.Stream.Filter.Type.DecodeException


-- | Utils relayted to pdf objects
module Pdf.Toolbox.Core.Object.Util

-- | Allows you to cast <a>Object</a> to specific type
class FromObject c
fromObject :: (FromObject c, Show a, Monad m) => Object a -> PdfE m c
toNumber :: (Show a, Monad m) => Object a -> PdfE m Number
toBoolean :: (Show a, Monad m) => Object a -> PdfE m Boolean
toName :: (Show a, Monad m) => Object a -> PdfE m Name
toDict :: (Show a, Monad m) => Object a -> PdfE m Dict
toArray :: (Show a, Monad m) => Object a -> PdfE m Array
toStr :: (Show a, Monad m) => Object a -> PdfE m Str
toRef :: (Show a, Monad m) => Object a -> PdfE m Ref
toStream :: (Show a, Monad m) => Object a -> PdfE m (Stream a)

-- | Apply function to all stream contents
mapObject :: (a -> b) -> Object a -> Object b
lookupDict :: Monad m => Name -> Dict -> PdfE m (Object ())
lookupDict' :: Name -> Dict -> Maybe (Object ())
setValueForKey :: Name -> Object () -> Dict -> Dict
deleteValueForKey :: Name -> Dict -> Dict
intValue :: Monad m => Number -> PdfE m Int
realValue :: Monad m => Number -> PdfE m Double
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Number
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Boolean
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Name
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Dict
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Str
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Ref
instance Pdf.Toolbox.Core.Object.Util.FromObject Pdf.Toolbox.Core.Object.Types.Array


-- | Flate decode filter
module Pdf.Toolbox.Core.Stream.Filter.FlateDecode

-- | Vary basic implementation. Only PNG-UP prediction is implemented
flateDecode :: StreamFilter


-- | Stream related tools
module Pdf.Toolbox.Core.Stream

-- | Stream filter
data StreamFilter

-- | All stream filters implemented by the toolbox
--   
--   Right now it contains only FlateDecode filter
knownFilters :: [StreamFilter]

-- | Raw content of stream. Filters are not applyed
--   
--   The <a>IS</a> is valid only until the next <a>seek</a>
--   
--   Note: "Length" could be an indirect object, but we don't want to read
--   indirect objects here. So we require length to be provided
rawStreamContent :: MonadIO m => RIS -> Int -> Stream Int64 -> PdfE m (Stream IS)

-- | Decoded stream content
--   
--   The <a>IS</a> is valid only until the next <a>seek</a>
--   
--   Note: "Length" could be an indirect object, that is why we cann't read
--   it ourself
decodedStreamContent :: MonadIO m => RIS -> [StreamFilter] -> (IS -> IO IS) -> Int -> Stream Int64 -> PdfE m (Stream IS)

-- | Read <a>Stream</a> at the current position in the <a>RIS</a>
readStream :: MonadIO m => RIS -> PdfE m (Stream Int64)

-- | Decode stream content
--   
--   The <a>IS</a> is valid only until the next <a>RIS</a> operation
decodeStream :: MonadIO m => [StreamFilter] -> (IS -> IO IS) -> Stream IS -> PdfE m (Stream IS)


-- | Unclassified tools
module Pdf.Toolbox.Core.Util

-- | Read indirect object at the specified offset
readObjectAtOffset :: MonadIO m => RIS -> Int64 -> Int -> PdfE m (Object Int64)

-- | Read object from object stream
readCompressedObject :: MonadIO m => IS -> Int64 -> Int -> PdfE m (Object ())


-- | Cross reference
module Pdf.Toolbox.Core.XRef

-- | Cross reference
data XRef

-- | Offset
XRefTable :: Int64 -> XRef

-- | Offset and stream with content offset
XRefStream :: Int64 -> (Stream Int64) -> XRef

-- | Entry in cross reference
data XRefEntry
XRefTableEntry :: TableEntry -> XRefEntry
XRefStreamEntry :: StreamEntry -> XRefEntry

-- | Entry in cross reference table
data TableEntry
TableEntry :: Int64 -> Int -> Bool -> TableEntry
[teOffset] :: TableEntry -> Int64
[teGen] :: TableEntry -> Int
[teIsFree] :: TableEntry -> Bool

-- | Entry in cross reference stream
data StreamEntry

-- | Object number and generation
StreamEntryFree :: Int -> Int -> StreamEntry

-- | Object offset (in bytes from the beginning of file) and generation
StreamEntryUsed :: Int64 -> Int -> StreamEntry

-- | Object number of object stream and index within the object stream
StreamEntryCompressed :: Int -> Int -> StreamEntry

-- | Find the last cross reference
lastXRef :: MonadIO m => RIS -> PdfE m XRef

-- | Find prev cross reference
prevXRef :: MonadIO m => RIS -> XRef -> PdfE m (Maybe XRef)

-- | Read trailer for the xref
trailer :: MonadIO m => RIS -> XRef -> PdfE m Dict

-- | Read xref entry for the indirect object from xref table
--   
--   RIS position should point to the begining of the next line after
--   "xref" keyword
lookupTableEntry :: MonadIO m => RIS -> Ref -> PdfE m (Maybe TableEntry)

-- | Read xref entry for the indirect object from xref stream
--   
--   See pdf1.7 spec: 7.5.8 Cross-Reference Streams
lookupStreamEntry :: MonadIO m => Stream IS -> Ref -> PdfE m (Maybe StreamEntry)

-- | Check whether the stream starts with "xref" keyword. The keyword
--   iyself is consumed
isTable :: MonadIO m => IS -> PdfE m Bool
instance GHC.Show.Show Pdf.Toolbox.Core.XRef.XRef
instance GHC.Show.Show Pdf.Toolbox.Core.XRef.XRefEntry
instance GHC.Show.Show Pdf.Toolbox.Core.XRef.StreamEntry
instance GHC.Show.Show Pdf.Toolbox.Core.XRef.TableEntry


-- | Low level tools for processing PDF file
module Pdf.Toolbox.Core
