    {- |
    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 \
           (!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