{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (garetxe@gmail.com)

Structure used for scatter\/gather data input when receiving multiple
messages or packets in one go. You generally pass in an array of empty
@/GInputVectors/@ and the operation will use all the buffers as if they
were one buffer, and will set /@bytesReceived@/ to the total number of bytes
received across all @/GInputVectors/@.

This structure closely mirrors @struct mmsghdr@ and @struct msghdr@ from
the POSIX sockets API (see @man 2 recvmmsg@).

If /@address@/ is non-'Nothing' then it is set to the source address the message
was received from, and the caller must free it afterwards.

If /@controlMessages@/ is non-'Nothing' then it is set to an array of control
messages received with the message (if any), and the caller must free it
afterwards. /@numControlMessages@/ is set to the number of elements in
this array, which may be zero.

Flags relevant to this message will be returned in /@flags@/. For example,
@MSG_EOR@ or @MSG_TRUNC@.

/Since: 2.48/
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Gio.Structs.InputMessage
    (

-- * Exported types
    InputMessage(..)                        ,
    newZeroInputMessage                     ,
    noInputMessage                          ,


 -- * Properties
-- ** address #attr:address#
{- | return location
  for a 'GI.Gio.Objects.SocketAddress.SocketAddress', or 'Nothing'
-}
    clearInputMessageAddress                ,
    getInputMessageAddress                  ,
#if ENABLE_OVERLOADING
    inputMessage_address                    ,
#endif
    setInputMessageAddress                  ,


-- ** bytesReceived #attr:bytesReceived#
{- | will be set to the number of bytes that have been
  received
-}
    getInputMessageBytesReceived            ,
#if ENABLE_OVERLOADING
    inputMessage_bytesReceived              ,
#endif
    setInputMessageBytesReceived            ,


-- ** flags #attr:flags#
{- | collection of 'GI.Gio.Flags.SocketMsgFlags' for the received message,
  outputted by the call
-}
    getInputMessageFlags                    ,
#if ENABLE_OVERLOADING
    inputMessage_flags                      ,
#endif
    setInputMessageFlags                    ,


-- ** numControlMessages #attr:numControlMessages#
{- | return location for the number of
  elements in /@controlMessages@/
-}
    getInputMessageNumControlMessages       ,
#if ENABLE_OVERLOADING
    inputMessage_numControlMessages         ,
#endif
    setInputMessageNumControlMessages       ,


-- ** numVectors #attr:numVectors#
{- | the number of input vectors pointed to by /@vectors@/
-}
    getInputMessageNumVectors               ,
#if ENABLE_OVERLOADING
    inputMessage_numVectors                 ,
#endif
    setInputMessageNumVectors               ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP

import {-# SOURCE #-} qualified GI.Gio.Objects.SocketAddress as Gio.SocketAddress

-- | Memory-managed wrapper type.
newtype InputMessage = InputMessage (ManagedPtr InputMessage)
instance WrappedPtr InputMessage where
    wrappedPtrCalloc = callocBytes 56
    wrappedPtrCopy = \p -> withManagedPtr p (copyBytes 56 >=> wrapPtr InputMessage)
    wrappedPtrFree = Just ptr_to_g_free

-- | Construct a `InputMessage` struct initialized to zero.
newZeroInputMessage :: MonadIO m => m InputMessage
newZeroInputMessage = liftIO $ wrappedPtrCalloc >>= wrapPtr InputMessage

instance tag ~ 'AttrSet => Constructible InputMessage tag where
    new _ attrs = do
        o <- newZeroInputMessage
        GI.Attributes.set o attrs
        return o


-- | A convenience alias for `Nothing` :: `Maybe` `InputMessage`.
noInputMessage :: Maybe InputMessage
noInputMessage = Nothing

{- |
Get the value of the “@address@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' inputMessage #address
@
-}
getInputMessageAddress :: MonadIO m => InputMessage -> m (Maybe Gio.SocketAddress.SocketAddress)
getInputMessageAddress s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO (Ptr Gio.SocketAddress.SocketAddress)
    result <- SP.convertIfNonNull val $ \val' -> do
        val'' <- (newObject Gio.SocketAddress.SocketAddress) val'
        return val''
    return result

{- |
Set the value of the “@address@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' inputMessage [ #address 'Data.GI.Base.Attributes.:=' value ]
@
-}
setInputMessageAddress :: MonadIO m => InputMessage -> Ptr Gio.SocketAddress.SocketAddress -> m ()
setInputMessageAddress s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (val :: Ptr Gio.SocketAddress.SocketAddress)

{- |
Set the value of the “@address@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #address
@
-}
clearInputMessageAddress :: MonadIO m => InputMessage -> m ()
clearInputMessageAddress s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (FP.nullPtr :: Ptr Gio.SocketAddress.SocketAddress)

#if ENABLE_OVERLOADING
data InputMessageAddressFieldInfo
instance AttrInfo InputMessageAddressFieldInfo where
    type AttrAllowedOps InputMessageAddressFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint InputMessageAddressFieldInfo = (~) (Ptr Gio.SocketAddress.SocketAddress)
    type AttrBaseTypeConstraint InputMessageAddressFieldInfo = (~) InputMessage
    type AttrGetType InputMessageAddressFieldInfo = Maybe Gio.SocketAddress.SocketAddress
    type AttrLabel InputMessageAddressFieldInfo = "address"
    type AttrOrigin InputMessageAddressFieldInfo = InputMessage
    attrGet _ = getInputMessageAddress
    attrSet _ = setInputMessageAddress
    attrConstruct = undefined
    attrClear _ = clearInputMessageAddress

inputMessage_address :: AttrLabelProxy "address"
inputMessage_address = AttrLabelProxy

#endif


-- XXX Skipped attribute for "InputMessage:vectors" :: Not implemented: "Don't know how to unpack C array of type TCArray False (-1) 2 (TInterface (Name {namespace = \"Gio\", name = \"InputVector\"}))"
{- |
Get the value of the “@num_vectors@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' inputMessage #numVectors
@
-}
getInputMessageNumVectors :: MonadIO m => InputMessage -> m Word32
getInputMessageNumVectors s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 16) :: IO Word32
    return val

{- |
Set the value of the “@num_vectors@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' inputMessage [ #numVectors 'Data.GI.Base.Attributes.:=' value ]
@
-}
setInputMessageNumVectors :: MonadIO m => InputMessage -> Word32 -> m ()
setInputMessageNumVectors s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 16) (val :: Word32)

#if ENABLE_OVERLOADING
data InputMessageNumVectorsFieldInfo
instance AttrInfo InputMessageNumVectorsFieldInfo where
    type AttrAllowedOps InputMessageNumVectorsFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint InputMessageNumVectorsFieldInfo = (~) Word32
    type AttrBaseTypeConstraint InputMessageNumVectorsFieldInfo = (~) InputMessage
    type AttrGetType InputMessageNumVectorsFieldInfo = Word32
    type AttrLabel InputMessageNumVectorsFieldInfo = "num_vectors"
    type AttrOrigin InputMessageNumVectorsFieldInfo = InputMessage
    attrGet _ = getInputMessageNumVectors
    attrSet _ = setInputMessageNumVectors
    attrConstruct = undefined
    attrClear _ = undefined

inputMessage_numVectors :: AttrLabelProxy "numVectors"
inputMessage_numVectors = AttrLabelProxy

#endif


{- |
Get the value of the “@bytes_received@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' inputMessage #bytesReceived
@
-}
getInputMessageBytesReceived :: MonadIO m => InputMessage -> m Word64
getInputMessageBytesReceived s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 24) :: IO Word64
    return val

{- |
Set the value of the “@bytes_received@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' inputMessage [ #bytesReceived 'Data.GI.Base.Attributes.:=' value ]
@
-}
setInputMessageBytesReceived :: MonadIO m => InputMessage -> Word64 -> m ()
setInputMessageBytesReceived s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (val :: Word64)

#if ENABLE_OVERLOADING
data InputMessageBytesReceivedFieldInfo
instance AttrInfo InputMessageBytesReceivedFieldInfo where
    type AttrAllowedOps InputMessageBytesReceivedFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint InputMessageBytesReceivedFieldInfo = (~) Word64
    type AttrBaseTypeConstraint InputMessageBytesReceivedFieldInfo = (~) InputMessage
    type AttrGetType InputMessageBytesReceivedFieldInfo = Word64
    type AttrLabel InputMessageBytesReceivedFieldInfo = "bytes_received"
    type AttrOrigin InputMessageBytesReceivedFieldInfo = InputMessage
    attrGet _ = getInputMessageBytesReceived
    attrSet _ = setInputMessageBytesReceived
    attrConstruct = undefined
    attrClear _ = undefined

inputMessage_bytesReceived :: AttrLabelProxy "bytesReceived"
inputMessage_bytesReceived = AttrLabelProxy

#endif


{- |
Get the value of the “@flags@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' inputMessage #flags
@
-}
getInputMessageFlags :: MonadIO m => InputMessage -> m Int32
getInputMessageFlags s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 32) :: IO Int32
    return val

{- |
Set the value of the “@flags@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' inputMessage [ #flags 'Data.GI.Base.Attributes.:=' value ]
@
-}
setInputMessageFlags :: MonadIO m => InputMessage -> Int32 -> m ()
setInputMessageFlags s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 32) (val :: Int32)

#if ENABLE_OVERLOADING
data InputMessageFlagsFieldInfo
instance AttrInfo InputMessageFlagsFieldInfo where
    type AttrAllowedOps InputMessageFlagsFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint InputMessageFlagsFieldInfo = (~) Int32
    type AttrBaseTypeConstraint InputMessageFlagsFieldInfo = (~) InputMessage
    type AttrGetType InputMessageFlagsFieldInfo = Int32
    type AttrLabel InputMessageFlagsFieldInfo = "flags"
    type AttrOrigin InputMessageFlagsFieldInfo = InputMessage
    attrGet _ = getInputMessageFlags
    attrSet _ = setInputMessageFlags
    attrConstruct = undefined
    attrClear _ = undefined

inputMessage_flags :: AttrLabelProxy "flags"
inputMessage_flags = AttrLabelProxy

#endif


-- XXX Skipped attribute for "InputMessage:control_messages" :: Not implemented: "Don't know how to unpack C array of type TCArray False (-1) 6 (TInterface (Name {namespace = \"Gio\", name = \"SocketControlMessage\"}))"
{- |
Get the value of the “@num_control_messages@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' inputMessage #numControlMessages
@
-}
getInputMessageNumControlMessages :: MonadIO m => InputMessage -> m Word32
getInputMessageNumControlMessages s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 48) :: IO Word32
    return val

{- |
Set the value of the “@num_control_messages@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' inputMessage [ #numControlMessages 'Data.GI.Base.Attributes.:=' value ]
@
-}
setInputMessageNumControlMessages :: MonadIO m => InputMessage -> Word32 -> m ()
setInputMessageNumControlMessages s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 48) (val :: Word32)

#if ENABLE_OVERLOADING
data InputMessageNumControlMessagesFieldInfo
instance AttrInfo InputMessageNumControlMessagesFieldInfo where
    type AttrAllowedOps InputMessageNumControlMessagesFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint InputMessageNumControlMessagesFieldInfo = (~) Word32
    type AttrBaseTypeConstraint InputMessageNumControlMessagesFieldInfo = (~) InputMessage
    type AttrGetType InputMessageNumControlMessagesFieldInfo = Word32
    type AttrLabel InputMessageNumControlMessagesFieldInfo = "num_control_messages"
    type AttrOrigin InputMessageNumControlMessagesFieldInfo = InputMessage
    attrGet _ = getInputMessageNumControlMessages
    attrSet _ = setInputMessageNumControlMessages
    attrConstruct = undefined
    attrClear _ = undefined

inputMessage_numControlMessages :: AttrLabelProxy "numControlMessages"
inputMessage_numControlMessages = AttrLabelProxy

#endif



#if ENABLE_OVERLOADING
instance O.HasAttributeList InputMessage
type instance O.AttributeList InputMessage = InputMessageAttributeList
type InputMessageAttributeList = ('[ '("address", InputMessageAddressFieldInfo), '("numVectors", InputMessageNumVectorsFieldInfo), '("bytesReceived", InputMessageBytesReceivedFieldInfo), '("flags", InputMessageFlagsFieldInfo), '("numControlMessages", InputMessageNumControlMessagesFieldInfo)] :: [(Symbol, *)])
#endif

#if ENABLE_OVERLOADING
type family ResolveInputMessageMethod (t :: Symbol) (o :: *) :: * where
    ResolveInputMessageMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveInputMessageMethod t InputMessage, O.MethodInfo info InputMessage p) => O.IsLabelProxy t (InputMessage -> p) where
    fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveInputMessageMethod t InputMessage, O.MethodInfo info InputMessage p) => O.IsLabel t (InputMessage -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif
#endif

#endif