    {-# LANGUAGE RecordWildCards #-}

    module System.Log.FastLogger.Write (
        writeLogStr,
        writeBigLogStr,
        Loggers (..),
    ) where

    import Foreign.Marshal.Alloc (allocaBytes)
    import Foreign.Ptr (plusPtr)

    import System.Log.FastLogger.FileIO
    import System.Log.FastLogger.IO
    import System.Log.FastLogger.Imports
    import System.Log.FastLogger.LogStr

    ----------------------------------------------------------------

    -- | Writting 'LogStr' using a buffer in blocking mode.
    --   The size of 'LogStr' must be smaller or equal to
    --   the size of buffer.
    writeLogStr :: Buffer -> IORef FD -> LogStr -> IO ()
    writeLogStr :: Buffer -> IORef FD -> LogStr -> IO ()
    writeLogStr Buffer
    buf IORef FD
    fdref (LogStr Int
    len Builder
    builder) =
        Buffer -> Int -> (Buffer -> Int -> IO ()) -> Builder -> IO ()
    toBufIOWith Buffer
    buf Int
    len (IORef FD -> Buffer -> Int -> IO ()
    write IORef FD
    fdref) Builder
    builder

    -- | Writting 'LogStr' using a temporary buffer.
    writeBigLogStr :: IORef FD -> LogStr -> IO ()
    writeBigLogStr :: IORef FD -> LogStr -> IO ()
    writeBigLogStr IORef FD
    fdref (LogStr Int
    len Builder
    builder) = Int -> (Buffer -> IO ()) -> IO ()
    forall a b. Int -> (Ptr a -> IO b) -> IO b
    allocaBytes Int
    len ((Buffer -> IO ()) -> IO ()) -> (Buffer -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Buffer
    buf ->
        Buffer -> Int -> (Buffer -> Int -> IO ()) -> Builder -> IO ()
    toBufIOWith Buffer
    buf Int
    len (IORef FD -> Buffer -> Int -> IO ()
    write IORef FD
    fdref) Builder
    builder

    write :: IORef FD -> Buffer -> Int -> IO ()
    write :: IORef FD -> Buffer -> Int -> IO ()
    write IORef FD
    fdref Buffer
    buf Int
    len' = Buffer -> Int -> IO ()
    loop Buffer
    buf (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    len')
      where
        loop :: Buffer -> Int -> IO ()
    loop Buffer
    bf Int
    len = do
            written <- IORef FD -> Buffer -> Int -> IO Int
    writeRawBufferPtr2FD IORef FD
    fdref Buffer
    bf Int
    len
            when (0 <= written && written < len) $
                loop (bf `plusPtr` fromIntegral written) (len - written)

    ----------------------------------------------------------------

    -- | A class for internal loggers.
    class Loggers a where
        stopLoggers :: a -> IO ()
        pushLog :: a -> LogStr -> IO ()
        flushAllLog :: a -> IO ()