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


-- | Common lower-level functions needed by various streaming data libraries
--   
--   Provides low-dependency functionality commonly needed by various
--   streaming data libraries, such as conduit and pipes.
@package streaming-commons
@version 0.1.2

module Data.Streaming.Zlib.Lowlevel
data ZStreamStruct
type ZStream' = Ptr ZStreamStruct
zstreamNew :: IO ZStream'
data Strategy
StrategyDefault :: Strategy
StrategyFiltered :: Strategy
StrategyHuffman :: Strategy
StrategyRLE :: Strategy
StrategyFixed :: Strategy
deflateInit2 :: ZStream' -> Int -> WindowBits -> Int -> Strategy -> IO ()
inflateInit2 :: ZStream' -> WindowBits -> IO ()
c_free_z_stream_inflate :: FunPtr (ZStream' -> IO ())
c_free_z_stream_deflate :: FunPtr (ZStream' -> IO ())
c_set_avail_in :: ZStream' -> Ptr CChar -> CUInt -> IO ()
c_set_avail_out :: ZStream' -> Ptr CChar -> CUInt -> IO ()
c_get_avail_out :: ZStream' -> IO CUInt
c_get_avail_in :: ZStream' -> IO CUInt
c_get_next_in :: ZStream' -> IO (Ptr CChar)
c_call_inflate_noflush :: ZStream' -> IO CInt
c_call_deflate_noflush :: ZStream' -> IO CInt
c_call_deflate_finish :: ZStream' -> IO CInt
c_call_deflate_flush :: ZStream' -> IO CInt
c_call_deflate_set_dictionary :: ZStream' -> Ptr CChar -> CUInt -> IO ()
c_call_inflate_set_dictionary :: ZStream' -> Ptr CChar -> CUInt -> IO ()
instance Show Strategy
instance Eq Strategy
instance Ord Strategy
instance Enum Strategy


-- | This is a middle-level wrapper around the zlib C API. It allows you to
--   work fully with bytestrings and not touch the FFI at all, but is still
--   low-level enough to allow you to implement high-level abstractions
--   such as enumerators. Significantly, it does not use lazy IO.
--   
--   You'll probably need to reference the docs a bit to understand the
--   WindowBits parameters below, but a basic rule of thumb is 15 is for
--   zlib compression, and 31 for gzip compression.
--   
--   A simple streaming compressor in pseudo-code would look like:
--   
--   <pre>
--   def &lt;- initDeflate ...
--   popper &lt;- feedDeflate def rawContent
--   pullPopper popper
--   ...
--   finishDeflate def sendCompressedData
--   </pre>
--   
--   You can see a more complete example is available in the included
--   file-test.hs.
module Data.Streaming.Zlib

-- | The state of an inflation (eg, decompression) process. All allocated
--   memory is automatically reclaimed by the garbage collector. Also can
--   contain the inflation dictionary that is used for decompression.
data Inflate

-- | Initialize an inflation process with the given <a>WindowBits</a>. You
--   will need to call <a>feedInflate</a> to feed compressed data to this
--   and <a>finishInflate</a> to extract the final chunk of decompressed
--   data.
initInflate :: WindowBits -> IO Inflate

-- | Initialize an inflation process with the given <a>WindowBits</a>.
--   Unlike initInflate a dictionary for inflation is set which must match
--   the one set during compression.
initInflateWithDictionary :: WindowBits -> ByteString -> IO Inflate

-- | Feed the given <a>ByteString</a> to the inflater. Return a
--   <a>Popper</a>, an IO action that returns the decompressed data a chunk
--   at a time. The <a>Popper</a> must be called to exhaustion before using
--   the <a>Inflate</a> object again.
--   
--   Note that this function automatically buffers the output to
--   <a>defaultChunkSize</a>, and therefore you won't get any data from the
--   popper until that much decompressed data is available. After you have
--   fed all of the compressed data to this function, you can extract your
--   final chunk of decompressed data using <a>finishInflate</a>.
feedInflate :: Inflate -> ByteString -> IO Popper

-- | As explained in <a>feedInflate</a>, inflation buffers your
--   decompressed data. After you call <a>feedInflate</a> with your last
--   chunk of compressed data, you will likely have some data still sitting
--   in the buffer. This function will return it to you.
finishInflate :: Inflate -> IO ByteString

-- | Flush the inflation buffer. Useful for interactive application.
--   
--   This is actually a synonym for <a>finishInflate</a>. It is provided
--   for its more semantic name.
--   
--   Since 0.0.3
flushInflate :: Inflate -> IO ByteString

-- | The state of a deflation (eg, compression) process. All allocated
--   memory is automatically reclaimed by the garbage collector.
data Deflate

-- | Initialize a deflation process with the given compression level and
--   <a>WindowBits</a>. You will need to call <a>feedDeflate</a> to feed
--   uncompressed data to this and <a>finishDeflate</a> to extract the
--   final chunks of compressed data.
initDeflate :: Int -> WindowBits -> IO Deflate

-- | Initialize an deflation process with the given compression level and
--   <a>WindowBits</a>. Unlike initDeflate a dictionary for deflation is
--   set.
initDeflateWithDictionary :: Int -> ByteString -> WindowBits -> IO Deflate

-- | Feed the given <a>ByteString</a> to the deflater. Return a
--   <a>Popper</a>, an IO action that returns the compressed data a chunk
--   at a time. The <a>Popper</a> must be called to exhaustion before using
--   the <a>Deflate</a> object again.
--   
--   Note that this function automatically buffers the output to
--   <a>defaultChunkSize</a>, and therefore you won't get any data from the
--   popper until that much compressed data is available. After you have
--   fed all of the decompressed data to this function, you can extract
--   your final chunks of compressed data using <a>finishDeflate</a>.
feedDeflate :: Deflate -> ByteString -> IO Popper

-- | As explained in <a>feedDeflate</a>, deflation buffers your compressed
--   data. After you call <a>feedDeflate</a> with your last chunk of
--   uncompressed data, use this to flush the rest of the data and signal
--   end of input.
finishDeflate :: Deflate -> Popper

-- | Flush the deflation buffer. Useful for interactive application.
--   Internally this passes Z_SYNC_FLUSH to the zlib library.
--   
--   Unlike <a>finishDeflate</a>, <a>flushDeflate</a> does not signal end
--   of input, meaning you can feed more uncompressed data afterward.
--   
--   Since 0.0.3
flushDeflate :: Deflate -> Popper

-- | This specifies the size of the compression window. Larger values of
--   this parameter result in better compression at the expense of higher
--   memory usage.
--   
--   The compression window size is the value of the the window bits raised
--   to the power 2. The window bits must be in the range <tt>8..15</tt>
--   which corresponds to compression window sizes of 256b to 32Kb. The
--   default is 15 which is also the maximum size.
--   
--   The total amount of memory used depends on the window bits and the
--   <a>MemoryLevel</a>. See the <a>MemoryLevel</a> for the details.
data WindowBits :: *
WindowBits :: Int -> WindowBits

-- | The default <a>WindowBits</a> is 15 which is also the maximum size.
defaultWindowBits :: WindowBits

-- | Exception that can be thrown from the FFI code. The parameter is the
--   numerical error code from the zlib library. Quoting the zlib.h file
--   directly:
--   
--   <ul>
--   <li>#define Z_OK 0</li>
--   <li>#define Z_STREAM_END 1</li>
--   <li>#define Z_NEED_DICT 2</li>
--   <li>#define Z_ERRNO (-1)</li>
--   <li>#define Z_STREAM_ERROR (-2)</li>
--   <li>#define Z_DATA_ERROR (-3)</li>
--   <li>#define Z_MEM_ERROR (-4)</li>
--   <li>#define Z_BUF_ERROR (-5)</li>
--   <li>#define Z_VERSION_ERROR (-6)</li>
--   </ul>
data ZlibException
ZlibException :: Int -> ZlibException

-- | An IO action that returns the next chunk of data, returning
--   <a>Nothing</a> when there is no more data to be popped.
type Popper = IO PopperRes
data PopperRes
PRDone :: PopperRes
PRNext :: !ByteString -> PopperRes
PRError :: !ZlibException -> PopperRes
instance Typeable ZlibException
instance Typeable PopperRes
instance Show ZlibException
instance Show PopperRes
instance Exception ZlibException


-- | Provides a stream-based approach to decoding Unicode data. Each
--   function below works the same way: you give it a chunk of data, and it
--   gives back a <tt>DecodeResult</tt>. If the parse was a success, then
--   you get a chunk of <tt>Text</tt> (possibly empty) and a continuation
--   parsing function. If the parse was a failure, you get a chunk of
--   successfully decoded <tt>Text</tt> (possibly empty) and the unconsumed
--   bytes.
--   
--   In order to indicate end of stream, you pass an empty
--   <tt>ByteString</tt> to the decode function. This call may result in a
--   failure, if there were unused bytes left over from a previous step
--   which formed part of a code sequence.
module Data.Streaming.Text

-- | <i>O(n)</i> Convert a lazy <a>ByteString</a> into a 'Stream Char',
--   using UTF-8 encoding.
decodeUtf8 :: ByteString -> DecodeResult

-- | <i>O(n)</i> Convert a lazy <a>ByteString</a> into a 'Stream Char',
--   using UTF-8 encoding.
decodeUtf8Pure :: ByteString -> DecodeResult

-- | <i>O(n)</i> Convert a <a>ByteString</a> into a 'Stream Char', using
--   little endian UTF-16 encoding.
decodeUtf16LE :: ByteString -> DecodeResult

-- | <i>O(n)</i> Convert a <a>ByteString</a> into a 'Stream Char', using
--   big endian UTF-16 encoding.
decodeUtf16BE :: ByteString -> DecodeResult

-- | <i>O(n)</i> Convert a <a>ByteString</a> into a 'Stream Char', using
--   little endian UTF-32 encoding.
decodeUtf32LE :: ByteString -> DecodeResult

-- | <i>O(n)</i> Convert a <a>ByteString</a> into a 'Stream Char', using
--   big endian UTF-32 encoding.
decodeUtf32BE :: ByteString -> DecodeResult
data DecodeResult
DecodeResultSuccess :: !Text -> !(ByteString -> DecodeResult) -> DecodeResult
DecodeResultFailure :: !Text -> !ByteString -> DecodeResult
instance Show S
instance Eq CodePoint
instance Show CodePoint
instance Num CodePoint
instance Storable CodePoint
instance Eq DecoderState
instance Show DecoderState
instance Num DecoderState
instance Storable DecoderState

module Data.Streaming.Network.Internal

-- | Settings for a TCP server. It takes a port to listen on, and an
--   optional hostname to bind to.
data ServerSettings
ServerSettings :: !Int -> !HostPreference -> !(Maybe Socket) -> !(Socket -> IO ()) -> !Bool -> ServerSettings
serverPort :: ServerSettings -> !Int
serverHost :: ServerSettings -> !HostPreference

-- | listening socket
serverSocket :: ServerSettings -> !(Maybe Socket)
serverAfterBind :: ServerSettings -> !(Socket -> IO ())
serverNeedLocalAddr :: ServerSettings -> !Bool

-- | Settings for a TCP client, specifying how to connect to the server.
data ClientSettings
ClientSettings :: !Int -> !ByteString -> ClientSettings
clientPort :: ClientSettings -> !Int
clientHost :: ClientSettings -> !ByteString

-- | Which host to bind.
--   
--   Note: The <tt>IsString</tt> instance recognizes the following special
--   values:
--   
--   <ul>
--   <li><tt>*</tt> means <tt>HostAny</tt></li>
--   <li><tt>*4</tt> means <tt>HostIPv4</tt></li>
--   <li><tt>!4</tt> means <tt>HostIPv4Only</tt></li>
--   <li><tt>*6</tt> means <tt>HostIPv6</tt></li>
--   <li><tt>!6</tt> means <tt>HostIPv6Only</tt></li>
--   </ul>
data HostPreference
HostAny :: HostPreference
HostIPv4 :: HostPreference
HostIPv4Only :: HostPreference
HostIPv6 :: HostPreference
HostIPv6Only :: HostPreference
Host :: String -> HostPreference

-- | Representation of a single UDP message
data Message
Message :: {-# UNPACK #-} !ByteString -> !SockAddr -> Message
msgData :: Message -> {-# UNPACK #-} !ByteString
msgSender :: Message -> !SockAddr

-- | The data passed to an <tt>Application</tt>.
data AppData
AppData :: !(IO ByteString) -> !(ByteString -> IO ()) -> !SockAddr -> !(Maybe SockAddr) -> AppData
appRead' :: AppData -> !(IO ByteString)
appWrite' :: AppData -> !(ByteString -> IO ())
appSockAddr' :: AppData -> !SockAddr
appLocalAddr' :: AppData -> !(Maybe SockAddr)

-- | Settings for a Unix domain sockets server.
data ServerSettingsUnix
ServerSettingsUnix :: !FilePath -> !(Socket -> IO ()) -> ServerSettingsUnix
serverPath :: ServerSettingsUnix -> !FilePath
serverAfterBindUnix :: ServerSettingsUnix -> !(Socket -> IO ())

-- | Settings for a Unix domain sockets client.
data ClientSettingsUnix
ClientSettingsUnix :: !FilePath -> ClientSettingsUnix
clientPath :: ClientSettingsUnix -> !FilePath

-- | The data passed to a Unix domain sockets <tt>Application</tt>.
data AppDataUnix
AppDataUnix :: !(IO ByteString) -> !(ByteString -> IO ()) -> AppDataUnix
appReadUnix :: AppDataUnix -> !(IO ByteString)
appWriteUnix :: AppDataUnix -> !(ByteString -> IO ())
instance Eq HostPreference
instance Ord HostPreference
instance Show HostPreference
instance Read HostPreference
instance IsString HostPreference

module Data.Streaming.Network

-- | Settings for a TCP server. It takes a port to listen on, and an
--   optional hostname to bind to.
data ServerSettings

-- | Settings for a TCP client, specifying how to connect to the server.
data ClientSettings

-- | Which host to bind.
--   
--   Note: The <tt>IsString</tt> instance recognizes the following special
--   values:
--   
--   <ul>
--   <li><tt>*</tt> means <tt>HostAny</tt></li>
--   <li><tt>*4</tt> means <tt>HostIPv4</tt></li>
--   <li><tt>!4</tt> means <tt>HostIPv4Only</tt></li>
--   <li><tt>*6</tt> means <tt>HostIPv6</tt></li>
--   <li><tt>!6</tt> means <tt>HostIPv6Only</tt></li>
--   </ul>
data HostPreference

-- | Representation of a single UDP message
data Message
Message :: {-# UNPACK #-} !ByteString -> !SockAddr -> Message
msgData :: Message -> {-# UNPACK #-} !ByteString
msgSender :: Message -> !SockAddr

-- | The data passed to an <tt>Application</tt>.
data AppData

-- | Settings for a Unix domain sockets server.
data ServerSettingsUnix

-- | Settings for a Unix domain sockets client.
data ClientSettingsUnix

-- | The data passed to a Unix domain sockets <tt>Application</tt>.
data AppDataUnix

-- | Smart constructor.
serverSettingsTCP :: Int -> HostPreference -> ServerSettings

-- | Create a server settings that uses an already available listening
--   socket. Any port and host modifications made to this value will be
--   ignored.
--   
--   Since 0.1.1
serverSettingsTCPSocket :: Socket -> ServerSettings

-- | Smart constructor.
clientSettingsTCP :: Int -> ByteString -> ClientSettings

-- | Smart constructor.
serverSettingsUDP :: Int -> HostPreference -> ServerSettings

-- | Smart constructor.
clientSettingsUDP :: Int -> ByteString -> ClientSettings

-- | Smart constructor.
serverSettingsUnix :: FilePath -> ServerSettingsUnix

-- | Smart constructor.
clientSettingsUnix :: FilePath -> ClientSettingsUnix
message :: ByteString -> SockAddr -> Message
class HasPort a
portLens :: (HasPort a, Functor f) => (Int -> f Int) -> a -> f a
class HasAfterBind a
afterBindLens :: (HasAfterBind a, Functor f) => ((Socket -> IO ()) -> f (Socket -> IO ())) -> a -> f a
class HasReadWrite a
readLens :: (HasReadWrite a, Functor f) => (IO ByteString -> f (IO ByteString)) -> a -> f a
writeLens :: (HasReadWrite a, Functor f) => ((ByteString -> IO ()) -> f (ByteString -> IO ())) -> a -> f a
class HasPath a
pathLens :: (HasPath a, Functor f) => (FilePath -> f FilePath) -> a -> f a
setPort :: HasPort a => Int -> a -> a
setHost :: ByteString -> ClientSettings -> ClientSettings
setAfterBind :: HasAfterBind a => (Socket -> IO ()) -> a -> a
setNeedLocalAddr :: Bool -> ServerSettings -> ServerSettings
setPath :: HasPath a => FilePath -> a -> a
getPort :: HasPort a => a -> Int
getHost :: ClientSettings -> ByteString
getAfterBind :: HasAfterBind a => a -> (Socket -> IO ())
getNeedLocalAddr :: ServerSettings -> Bool
getPath :: HasPath a => a -> FilePath
appRead :: HasReadWrite a => a -> IO ByteString
appWrite :: HasReadWrite a => a -> ByteString -> IO ()
appSockAddr :: AppData -> SockAddr
appLocalAddr :: AppData -> Maybe SockAddr

-- | Attempt to bind a listening <tt>Socket</tt> on the given host/port
--   using given <tt>SocketType</tt>. If no host is given, will use the
--   first address available.
bindPortGen :: SocketType -> Int -> HostPreference -> IO Socket

-- | Bind to a random port number. Especially useful for writing network
--   tests.
--   
--   This will attempt 30 different port numbers before giving up and
--   throwing an exception.
--   
--   Since 0.1.1
bindRandomPortGen :: SocketType -> HostPreference -> IO (Int, Socket)

-- | Attempt to connect to the given host/port using given
--   <tt>SocketType</tt>.
getSocketGen :: SocketType -> String -> Int -> IO (Socket, AddrInfo)

-- | Try to accept a connection, recovering automatically from exceptions.
--   
--   As reported by Kazu against Warp, <a>resource exhausted (Too many open
--   files)</a> may be thrown by accept(). This function will catch that
--   exception, wait a second, and then try again.
acceptSafe :: Socket -> IO (Socket, SockAddr)
unassignedPorts :: UArray Int Int

-- | Get a port from the IANA list of unassigned ports.
--   
--   Internally, this function uses an <tt>IORef</tt> to cycle through the
--   list of ports
getUnassignedPort :: IO Int

-- | Attempt to bind a listening <tt>Socket</tt> on the given host/port. If
--   no host is given, will use the first address available.
--   <tt>maxListenQueue</tt> is topically 128 which is too short for high
--   performance servers. So, we specify 'max 2048 maxListenQueue' to the
--   listen queue.
bindPortTCP :: Int -> HostPreference -> IO Socket

-- | Bind a random TCP port.
--   
--   See <a>bindRandomPortGen</a>.
--   
--   Since 0.1.1
bindRandomPortTCP :: HostPreference -> IO (Int, Socket)

-- | Attempt to connect to the given host/port.
getSocketTCP :: ByteString -> Int -> IO (Socket, SockAddr)
safeRecv :: Socket -> Int -> IO ByteString

-- | Run an <tt>Application</tt> with the given settings. This function
--   will create a new listening socket, accept connections on it, and
--   spawn a new thread for each connection.
runTCPServer :: ServerSettings -> (AppData -> IO ()) -> IO ()

-- | Run an <tt>Application</tt> by connecting to the specified server.
runTCPClient :: ClientSettings -> (AppData -> IO a) -> IO a
type ConnectionHandle = Socket -> SockAddr -> Maybe SockAddr -> IO ()
runTCPServerWithHandle :: ServerSettings -> ConnectionHandle -> IO ()

-- | Attempt to bind a listening <tt>Socket</tt> on the given host/port. If
--   no host is given, will use the first address available.
bindPortUDP :: Int -> HostPreference -> IO Socket

-- | Bind a random UDP port.
--   
--   See <a>bindRandomPortGen</a>
--   
--   Since 0.1.1
bindRandomPortUDP :: HostPreference -> IO (Int, Socket)

-- | Attempt to connect to the given host/port.
getSocketUDP :: String -> Int -> IO (Socket, AddrInfo)

-- | Attempt to bind a listening Unix domain socket at the given path.
bindPath :: FilePath -> IO Socket

-- | Attempt to connect to the given Unix domain socket path.
getSocketUnix :: FilePath -> IO Socket

-- | Run an <tt>Application</tt> with the given settings. This function
--   will create a new listening socket, accept connections on it, and
--   spawn a new thread for each connection.
runUnixServer :: ServerSettingsUnix -> (AppDataUnix -> IO ()) -> IO ()

-- | Run an <tt>Application</tt> by connecting to the specified server.
runUnixClient :: ClientSettingsUnix -> (AppDataUnix -> IO a) -> IO a
instance HasReadWrite AppDataUnix
instance HasReadWrite AppData
instance HasAfterBind ServerSettingsUnix
instance HasAfterBind ServerSettings
instance HasPath ClientSettingsUnix
instance HasPath ServerSettingsUnix
instance HasPort ClientSettings
instance HasPort ServerSettings


-- | Streaming functions for interacting with the filesystem.
module Data.Streaming.Filesystem
data DirStream :: *

-- | <tt>openDirStream dir</tt> calls <tt>opendir</tt> to obtain a
--   directory stream for <tt>dir</tt>.
openDirStream :: FilePath -> IO DirStream
readDirStream :: DirStream -> IO (Maybe FilePath)

-- | <tt>closeDirStream dp</tt> calls <tt>closedir</tt> to close the
--   directory stream <tt>dp</tt>.
closeDirStream :: DirStream -> IO ()
data FileType
FTFile :: FileType

-- | symlink to file
FTFileSym :: FileType
FTDirectory :: FileType

-- | symlink to a directory
FTDirectorySym :: FileType
FTOther :: FileType
getFileType :: FilePath -> IO FileType
instance Typeable FileType
instance Show FileType
instance Read FileType
instance Eq FileType
instance Ord FileType


-- | The standard <tt>openFile</tt> call on Windows causing problematic
--   file locking in some cases. This module provides a cross-platform file
--   reading API without the file locking problems on Windows.
--   
--   This module <i>always</i> opens files in binary mode.
--   
--   <tt>readChunk</tt> will return an empty <tt>ByteString</tt> on EOF.
module Data.Streaming.FileRead
data ReadHandle
openFile :: FilePath -> IO ReadHandle
closeFile :: ReadHandle -> IO ()
readChunk :: ReadHandle -> IO ByteString


-- | Convert a stream of blaze-builder <tt>Builder</tt>s into a stream of
--   <tt>ByteString</tt>s.
--   
--   Adapted from blaze-builder-enumerator, written by myself and Simon
--   Meier.
--   
--   Note that the functions here can work in any monad built on top of
--   <tt>IO</tt> or <tt>ST</tt>.
module Data.Streaming.Blaze
type BlazeRecv = Builder -> IO BlazePopper

-- | Provides a series of <tt>ByteString</tt>s until empty, at which point
--   it provides an empty <tt>ByteString</tt>.
--   
--   Since 0.1.2
type BlazePopper = IO ByteString
type BlazeFinish = IO (Maybe ByteString)
newBlazeRecv :: BufferAllocStrategy -> IO (BlazeRecv, BlazeFinish)

-- | A buffer <tt>Buffer fpbuf p0 op ope</tt> describes a buffer with the
--   underlying byte array <tt>fpbuf..ope</tt>, the currently written slice
--   <tt>p0..op</tt> and the free space <tt>op..ope</tt>.
data Buffer :: *

-- | The size of the free space of the buffer.
freeSize :: Buffer -> Int

-- | The size of the written slice in the buffer.
sliceSize :: Buffer -> Int

-- | The size of the whole byte array underlying the buffer.
bufferSize :: Buffer -> Int

-- | <tt>allocBuffer size</tt> allocates a new buffer of size
--   <tt>size</tt>.
allocBuffer :: Int -> IO Buffer

-- | Resets the beginning of the next slice and the next free byte such
--   that the whole buffer can be filled again.
reuseBuffer :: Buffer -> Buffer

-- | Move the beginning of the slice to the next free byte such that the
--   remaining free space of the buffer can be filled further. This
--   operation is safe and can be used to fill the remaining part of the
--   buffer after a direct insertion of a bytestring or a flush.
nextSlice :: Int -> Buffer -> Maybe Buffer

-- | Convert the buffer to a bytestring. This operation is unsafe in the
--   sense that created bytestring shares the underlying byte array with
--   the buffer. Hence, depending on the later use of this buffer (e.g., if
--   it gets reset and filled again) referential transparency may be lost.
unsafeFreezeBuffer :: Buffer -> ByteString

-- | Convert a buffer to a non-empty bytestring. See
--   <a>unsafeFreezeBuffer</a> for the explanation of why this operation
--   may be unsafe.
unsafeFreezeNonEmptyBuffer :: Buffer -> Maybe ByteString

-- | A buffer allocation strategy <tt>(buf0, nextBuf)</tt> specifies the
--   initial buffer to use and how to compute a new buffer <tt>nextBuf
--   minSize buf</tt> with at least size <tt>minSize</tt> from a filled
--   buffer <tt>buf</tt>. The double nesting of the <tt>IO</tt> monad helps
--   to ensure that the reference to the filled buffer <tt>buf</tt> is lost
--   as soon as possible, but the new buffer doesn't have to be allocated
--   too early.
type BufferAllocStrategy = (IO Buffer, Int -> Buffer -> IO (IO Buffer))

-- | The simplest buffer allocation strategy: whenever a buffer is
--   requested, allocate a new one that is big enough for the next build
--   step to execute.
--   
--   NOTE that this allocation strategy may spill quite some memory upon
--   direct insertion of a bytestring by the builder. Thats no problem for
--   garbage collection, but it may lead to unreasonably high memory
--   consumption in special circumstances.
allNewBuffersStrategy :: Int -> BufferAllocStrategy

-- | An unsafe, but possibly more efficient buffer allocation strategy:
--   reuse the buffer, if it is big enough for the next build step to
--   execute.
reuseBufferStrategy :: IO Buffer -> BufferAllocStrategy
defaultStrategy :: BufferAllocStrategy
