{-# LINE 1 "src/System/Posix/Poll.hsc" #-}
module System.Posix.Poll (
{-# LINE 2 "src/System/Posix/Poll.hsc" #-}
  Fd(..),
  Event(..),
  Events,
  inp, pri, out, err, hup, nVal,
  ) where


{-# LINE 9 "src/System/Posix/Poll.hsc" #-}

import Foreign.C.Types (CShort, )
import Foreign.Storable
          (Storable(sizeOf, alignment, peek, poke),
           peekByteOff, pokeByteOff, )
import qualified System.Posix.Types as Posix
import Data.Ix (Ix, range, index, inRange, rangeSize, )
import Data.Maybe (fromMaybe, )
import qualified Data.Ix.Enum as IxEnum
import qualified Data.EnumSet as EnumSet

data Event 
  = Other Int
  | In
  | Pri
  | Out
  | Err
  | Hup
  | NVal
  deriving (Eq, Ord, Show)

eventFlagSet :: Event -> Events
eventFlagSet cap =
   case cap of
      Other n -> EnumSet.singletonByPosition n
      In      -> inp
      Pri     -> pri
      Out     -> out
      Err     -> err
      Hup     -> hup
      NVal    -> nVal

{- |
The Enum instance may not be very efficient,
but it should hardly be used, at all.
Better use constants such as 'inp' and set manipulation.
If the binary logarithm is computed by constant unfolding,
performance would be better, but direct set manipulation is still faster.
We implement the 'Enum' instance in this way,
in order to stay independent from the particular Poll definitions,
that may differ between platforms.
-}
instance Enum Event where
   fromEnum cap =
      case cap of
         Other n -> n
         _ -> EnumSet.mostSignificantPosition (eventFlagSet cap)
   toEnum n =
      fromMaybe (Other n) $
      lookup (EnumSet.singletonByPosition n) $
      map (\ev -> (eventFlagSet ev, ev)) $
         In :
         Pri :
         Out :
         Err :
         Hup :
         NVal :
         []

instance Ix Event where
   range     = IxEnum.range
   index     = IxEnum.index
   inRange   = IxEnum.inRange
   rangeSize = IxEnum.rangeSize

{-
pollMask :: PollEvent -> CShort
pollMask PollIn	  = #{const POLLIN}
pollMask PollPri  = #{const POLLPRI}
pollMask PollOut  = #{const POLLOUT}
pollMask PollErr  = #{const POLLERR}
pollMask PollHup  = #{const POLLHUP}
pollMask PollNVal = #{const POLLNVAL}
-}

inp, pri, out, err, hup, nVal :: Events
inp  = EnumSet.Cons 1
{-# LINE 86 "src/System/Posix/Poll.hsc" #-}
pri  = EnumSet.Cons 2
{-# LINE 87 "src/System/Posix/Poll.hsc" #-}
out  = EnumSet.Cons 4
{-# LINE 88 "src/System/Posix/Poll.hsc" #-}
err  = EnumSet.Cons 8
{-# LINE 89 "src/System/Posix/Poll.hsc" #-}
hup  = EnumSet.Cons 16
{-# LINE 90 "src/System/Posix/Poll.hsc" #-}
nVal = EnumSet.Cons 32
{-# LINE 91 "src/System/Posix/Poll.hsc" #-}


type Events = EnumSet.T CShort Event

data Fd = Fd
  { fd :: Posix.Fd
  , events :: Events
  , rEvents :: Events
  }

instance Storable Fd where
  sizeOf _    = (8)
{-# LINE 103 "src/System/Posix/Poll.hsc" #-}
  alignment _ = 4
  peek p      = do
    f <- (\hsc_ptr -> peekByteOff hsc_ptr 0)      p
{-# LINE 106 "src/System/Posix/Poll.hsc" #-}
    e <- (\hsc_ptr -> peekByteOff hsc_ptr 4)  p
{-# LINE 107 "src/System/Posix/Poll.hsc" #-}
    r <- (\hsc_ptr -> peekByteOff hsc_ptr 6) p
{-# LINE 108 "src/System/Posix/Poll.hsc" #-}
    return $ Fd (Posix.Fd f) e r
  poke p (Fd (Posix.Fd f) e r) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0)      p f
{-# LINE 111 "src/System/Posix/Poll.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 4)  p e
{-# LINE 112 "src/System/Posix/Poll.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 6) p r
{-# LINE 113 "src/System/Posix/Poll.hsc" #-}