{-# LANGUAGE ScopedTypeVariables #-}-- |Random and Binary IO with generic Iteratees. These functions use Handles-- for IO operations, and are provided for compatibility. When available,-- the File Descriptor based functions are preferred as these wastefully-- allocate memory rather than running in constant space.moduleData.Iteratee.IO.Handle(-- * File enumeratorsenumHandle,enumHandleCatch,enumHandleRandom,enumFile,enumFileRandom-- * Iteratee drivers,fileDriverHandle,fileDriverRandomHandle)whereimportData.Iteratee.Base.ReadableChunkimportData.Iteratee.IterateeimportData.Iteratee.Binary()importControl.ExceptionimportControl.MonadimportControl.Monad.CatchIOasCIOimportControl.Monad.IO.ClassimportForeign.PtrimportForeign.StorableimportForeign.Marshal.AllocimportSystem.IO-- -------------------------------------------------------------------------- Binary Random IO enumeratorsmakeHandleCallback::(MonadCatchIOm,NullPoints,ReadableChunksel)=>Ptrel->Int->Handle->st->m(EitherSomeException((Bool,st),s))makeHandleCallbackpbsizehst=don'<-liftIO(CIO.try$hGetBufhpbsize::IO(EitherSomeExceptionInt))casen'ofLefte->return$LefteRight0->return$Right((False,st),empty)Rightn->liftM(\s->Right((True,st),s))$readFromPtrp(fromIntegraln)-- |The (monadic) enumerator of a file Handle. This version enumerates-- over the entire contents of a file, in order, unless stopped by-- the iteratee. In particular, seeking is not supported.-- Data is read into a buffer of the specified size.enumHandle::forallselma.(NullPoints,ReadableChunksel,MonadCatchIOm)=>Int-- ^Buffer size (number of elements per read)->Handle->EnumeratorsmaenumHandlebshi=letbufsize=bs*sizeOf(undefined::el)inCIO.bracket(liftIO$mallocBytesbufsize)(liftIO.free)(\p->enumFromCallback(makeHandleCallbackpbufsizeh)()i)-- |An enumerator of a file handle that catches exceptions raised by-- the Iteratee.enumHandleCatch::foralleselma.(IExceptione,NullPoints,ReadableChunksel,MonadCatchIOm)=>Int-- ^Buffer size (number of elements per read)->Handle->(e->m(MaybeEnumException))->EnumeratorsmaenumHandleCatchbshhandleri=letbufsize=bs*sizeOf(undefined::el)inCIO.bracket(liftIO$mallocBytesbufsize)(liftIO.free)(\p->enumFromCallbackCatch(makeHandleCallbackpbufsizeh)handler()i)-- |The enumerator of a Handle: a variation of enumHandle that-- supports RandomIO (seek requests).-- Data is read into a buffer of the specified size.enumHandleRandom::forallselma.(NullPoints,ReadableChunksel,MonadCatchIOm)=>Int-- ^ Buffer size (number of elements per read)->Handle->EnumeratorsmaenumHandleRandombshi=enumHandleCatchbshhandleriwherehandler(SeekExceptionoff)=liftM(either(Just.EnumException::IOException->MaybeEnumException)(constNothing)).liftIO.CIO.try$hSeekhAbsoluteSeek$fromIntegraloff-- ------------------------------------------------ File Driver wrapper functions.enumFile'::(NullPoints,MonadCatchIOm,ReadableChunksel)=>(Int->Handle->Enumeratorsma)->Int-- ^Buffer size->FilePath->EnumeratorsmaenumFile'enumfbufsizefilepathiter=CIO.bracket(liftIO$openBinaryFilefilepathReadMode)(liftIO.hClose)(flip(enumfbufsize)iter)enumFile::(NullPoints,MonadCatchIOm,ReadableChunksel)=>Int-- ^Buffer size->FilePath->EnumeratorsmaenumFile=enumFile'enumHandleenumFileRandom::(NullPoints,MonadCatchIOm,ReadableChunksel)=>Int-- ^Buffer size->FilePath->EnumeratorsmaenumFileRandom=enumFile'enumHandleRandom-- |Process a file using the given @Iteratee@. This function wraps-- @enumHandle@ as a convenience.fileDriverHandle::(NullPoints,MonadCatchIOm,ReadableChunksel)=>Int-- ^Buffer size (number of elements)->Iterateesma->FilePath->mafileDriverHandlebufsizeiterfilepath=enumFilebufsizefilepathiter>>=run-- |A version of @fileDriverHandle@ that supports seeking.fileDriverRandomHandle::(NullPoints,MonadCatchIOm,ReadableChunksel)=>Int-- ^ Buffer size (number of elements)->Iterateesma->FilePath->mafileDriverRandomHandlebufsizeiterfilepath=enumFileRandombufsizefilepathiter>>=run