{-# 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
  , msgEOR
  , msgNOSIGNAL
  , msgOOB
  , msgWAITALL
  ) where

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

import Foreign.C.Types
import Foreign.Storable


{-# LINE 21 "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
          , let (MsgFlags i) = msg `xor` (mconcat [msgEOR,msgNOSIGNAL,msgOOB,msgWAITALL] .&. msg)
            in if i /= 0 then Just ("MsgFlags " ++ show i) else Nothing 
          ]
      y = concat $ intersperse "," $ catMaybes x

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

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

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

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