{-# LINE 1 "src/System/Socket/Internal/Msg.hsc" #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LINE 2 "src/System/Socket/Internal/Msg.hsc" #-}
module System.Socket.Internal.Msg (
    MsgFlags (..)
  , Msg
  , IoVec
  , msgDONTWAIT
  , msgEOR
  , msgMORE
  , msgNOSIGNAL
  , msgOOB
  , msgTRUNC
  , msgWAITALL
  ) where

import Data.Bits
import Data.Monoid
import Data.Maybe
import Data.List (intersperse)

import Foreign.C.Types
import Foreign.Storable


{-# LINE 24 "src/System/Socket/Internal/Msg.hsc" #-}

-- | Use the `Data.Monoid.Monoid` instance to combine several flags:
--
--   > mconcat [msgNOSIGNAL, msgWAITALL]
--
--   Use the `Data.Bits.Bits` instance to check whether a flag is set:
--
--   > if flags .&. msgEOR /= mempty then ...
newtype MsgFlags
      = MsgFlags CInt
      deriving (Eq, Bits, Storable)

data Msg a t p

data IoVec

instance Monoid MsgFlags where
  mempty  = MsgFlags 0
  mappend = (.|.)

instance Show MsgFlags where
  show msg = "mconcat [" ++ y ++ "]"
    where
      x = [ if msg .&. msgEOR      /= mempty then Just "msgEOR"      else Nothing
          , if msg .&. msgNOSIGNAL /= mempty then Just "msgNOSIGNAL" else Nothing
          , if msg .&. msgOOB      /= mempty then Just "msgOOB"      else Nothing
          , if msg .&. msgWAITALL  /= mempty then Just "msgWAITALL"  else Nothing
          , if msg .&. msgTRUNC    /= mempty then Just "msgTRUNC"    else Nothing
          , if msg .&. msgMORE     /= mempty then Just "msgMORE"     else Nothing
          , if msg .&. msgDONTWAIT /= mempty then Just "msgDONTWAIT" else Nothing
          , let (MsgFlags i) = msg `xor` (mconcat [msgEOR,msgNOSIGNAL,msgOOB,msgWAITALL,msgTRUNC,msgMORE,msgDONTWAIT] .&. msg)
            in if i /= 0 then Just ("MsgFlags " ++ show i) else Nothing 
          ]
      y = concat $ intersperse "," $ catMaybes x

msgEOR      :: MsgFlags
msgEOR       = MsgFlags (128)
{-# LINE 61 "src/System/Socket/Internal/Msg.hsc" #-}

msgNOSIGNAL :: MsgFlags
msgNOSIGNAL  = MsgFlags (16384)
{-# LINE 64 "src/System/Socket/Internal/Msg.hsc" #-}

msgOOB      :: MsgFlags
msgOOB       = MsgFlags (1)
{-# LINE 67 "src/System/Socket/Internal/Msg.hsc" #-}

msgWAITALL  :: MsgFlags
msgWAITALL   = MsgFlags (256)
{-# LINE 70 "src/System/Socket/Internal/Msg.hsc" #-}

msgTRUNC    :: MsgFlags
msgTRUNC     = MsgFlags (32)
{-# LINE 73 "src/System/Socket/Internal/Msg.hsc" #-}

msgMORE     :: MsgFlags
msgMORE      = MsgFlags (32768)
{-# LINE 76 "src/System/Socket/Internal/Msg.hsc" #-}

msgDONTWAIT :: MsgFlags
msgDONTWAIT  = MsgFlags (64)
{-# LINE 79 "src/System/Socket/Internal/Msg.hsc" #-}