- old_buf@Buffer{ bufRaw=old_raw, bufR=w, bufSize=size }
- <- readIORef ref
-
- buf_ret <-
- -- enough room in handle buffer?
- if (not flush && (size - w > count))
- -- The > is to be sure that we never exactly fill
- -- up the buffer, which would require a flush. So
- -- if copying the new data into the buffer would
- -- make the buffer full, we just flush the existing
- -- buffer and the new data immediately, rather than
- -- copying before flushing.
-
- -- not flushing, and there's enough room in the buffer:
- -- just copy the data in and update bufR.
- then do withRawBuffer raw $ \praw ->
- copyToRawBuffer old_raw (w*charSize)
- praw (fromIntegral (count*charSize))
- writeIORef ref old_buf{ bufR = w + count }
- return (emptyBuffer raw sz WriteBuffer)
-
- -- else, we have to flush
- else do flushed_buf <- flushWriteBuffer_ handle_ old_buf
-
- let this_buf =
- Buffer{ bufRaw=raw, bufState=WriteBuffer,
- bufL=0, bufR=count, bufSize=sz }
-
- -- if: (a) we don't have to flush, and
- -- (b) size(new buffer) == size(old buffer), and
- -- (c) new buffer is not full,
- -- we can just just swap them over...
- if (not flush && sz == size && count /= sz)
- then do
- writeIORef ref this_buf
- return flushed_buf
-
- -- otherwise, we have to flush the new data too,
- -- and start with a fresh buffer
- else do
- -- We're aren't going to use this buffer again
- -- so we ignore the result of flushWriteBuffer_
- _ <- flushWriteBuffer_ handle_ this_buf
- writeIORef ref flushed_buf
- -- if the sizes were different, then allocate
- -- a new buffer of the correct size.
- if sz == size
- then return (emptyBuffer raw sz WriteBuffer)
- else newCharBuffer size WriteBuffer