{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}

module Network.Wai.Handler.Warp.IO where

import Data.ByteString (ByteString)
import Data.ByteString.Builder (Builder)
import Data.ByteString.Builder.Extra (runBuilder, Next(Done, More, Chunk))
import Network.Wai.Handler.Warp.Buffer
import Network.Wai.Handler.Warp.Types

toBufIOWith :: Buffer -> BufSize -> (ByteString -> IO ()) -> Builder -> IO ()
toBufIOWith buf !size io builder = loop firstWriter
  where
    firstWriter = runBuilder builder
    runIO len = bufferIO buf len io
    loop writer = do
        (len, signal) <- writer buf size
        case signal of
             Done -> runIO len
             More minSize next
               | size < minSize -> error "toBufIOWith: BufferFull: minSize"
               | otherwise      -> do
                   runIO len
                   loop next
             Chunk bs next -> do
                 runIO len
                 io bs
                 loop next