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

    Contains the public fields of a GByteArray.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.ByteArray
        (

    -- * Exported types
        ByteArray(..)                           ,
        newZeroByteArray                        ,
        noByteArray                             ,

     -- * Methods
    -- ** free #method:free#

        byteArrayFree                           ,

    -- ** freeToBytes #method:freeToBytes#

        byteArrayFreeToBytes                    ,

    -- ** new #method:new#

        byteArrayNew                            ,

    -- ** newTake #method:newTake#

        byteArrayNewTake                        ,

    -- ** unref #method:unref#

        byteArrayUnref                          ,

     -- * Properties
    -- ** data #attr:data#
    {- | a pointer to the element data. The data may be moved as
        elements are added to the 'GI.GLib.Structs.ByteArray.ByteArray'
    -}
    #if ENABLE_OVERLOADING
        byteArray_data                          ,
    #endif
        getByteArrayData                        ,
        setByteArrayData                        ,

    -- ** len #attr:len#
    {- | the number of elements in the 'GI.GLib.Structs.ByteArray.ByteArray'
    -}
    #if ENABLE_OVERLOADING
        byteArray_len                           ,
    #endif
        getByteArrayLen                         ,
        setByteArrayLen                         ,

        ) 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.GLib.Structs.Bytes as GLib.Bytes

    -- | Memory-managed wrapper type.
    newtype ByteArray = ByteArray (ManagedPtr ByteArray)
    foreign import ccall "g_byte_array_get_type" c_g_byte_array_get_type ::
        IO GType

    instance BoxedObject ByteArray where
        boxedType _ = c_g_byte_array_get_type

    -- | Construct a `ByteArray` struct initialized to zero.
    newZeroByteArray :: MonadIO m => m ByteArray
    newZeroByteArray = liftIO $ callocBoxedBytes 16 >>= wrapBoxed ByteArray

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

    -- | A convenience alias for `Nothing` :: `Maybe` `ByteArray`.
    noByteArray :: Maybe ByteArray
    noByteArray = Nothing

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

    @
    'Data.GI.Base.Attributes.get' byteArray #data
    @
    -}
    getByteArrayData :: MonadIO m => ByteArray -> m Word8
    getByteArrayData s = liftIO $ withManagedPtr s $ \ptr -> do
        val <- peek (ptr `plusPtr` 0) :: IO Word8
        return val

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

    @
    'Data.GI.Base.Attributes.set' byteArray [ #data 'Data.GI.Base.Attributes.:=' value ]
    @
    -}
    setByteArrayData :: MonadIO m => ByteArray -> Word8 -> m ()
    setByteArrayData s val = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 0) (val :: Word8)

    #if ENABLE_OVERLOADING
    data ByteArrayDataFieldInfo
    instance AttrInfo ByteArrayDataFieldInfo where
        type AttrAllowedOps ByteArrayDataFieldInfo = '[ 'AttrSet, 'AttrGet]
        type AttrSetTypeConstraint ByteArrayDataFieldInfo = (~) Word8
        type AttrBaseTypeConstraint ByteArrayDataFieldInfo = (~) ByteArray
        type AttrGetType ByteArrayDataFieldInfo = Word8
        type AttrLabel ByteArrayDataFieldInfo = "data"
        type AttrOrigin ByteArrayDataFieldInfo = ByteArray
        attrGet _ = getByteArrayData
        attrSet _ = setByteArrayData
        attrConstruct = undefined
        attrClear _ = undefined

    byteArray_data :: AttrLabelProxy "data"
    byteArray_data = AttrLabelProxy

    #endif

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

    @
    'Data.GI.Base.Attributes.get' byteArray #len
    @
    -}
    getByteArrayLen :: MonadIO m => ByteArray -> m Word32
    getByteArrayLen s = liftIO $ withManagedPtr s $ \ptr -> do
        val <- peek (ptr `plusPtr` 8) :: IO Word32
        return val

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

    @
    'Data.GI.Base.Attributes.set' byteArray [ #len 'Data.GI.Base.Attributes.:=' value ]
    @
    -}
    setByteArrayLen :: MonadIO m => ByteArray -> Word32 -> m ()
    setByteArrayLen s val = liftIO $ withManagedPtr s $ \ptr -> do
        poke (ptr `plusPtr` 8) (val :: Word32)

    #if ENABLE_OVERLOADING
    data ByteArrayLenFieldInfo
    instance AttrInfo ByteArrayLenFieldInfo where
        type AttrAllowedOps ByteArrayLenFieldInfo = '[ 'AttrSet, 'AttrGet]
        type AttrSetTypeConstraint ByteArrayLenFieldInfo = (~) Word32
        type AttrBaseTypeConstraint ByteArrayLenFieldInfo = (~) ByteArray
        type AttrGetType ByteArrayLenFieldInfo = Word32
        type AttrLabel ByteArrayLenFieldInfo = "len"
        type AttrOrigin ByteArrayLenFieldInfo = ByteArray
        attrGet _ = getByteArrayLen
        attrSet _ = setByteArrayLen
        attrConstruct = undefined
        attrClear _ = undefined

    byteArray_len :: AttrLabelProxy "len"
    byteArray_len = AttrLabelProxy

    #endif

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList ByteArray
    type instance O.AttributeList ByteArray = ByteArrayAttributeList
    type ByteArrayAttributeList = ('[ '("data", ByteArrayDataFieldInfo), '("len", ByteArrayLenFieldInfo)] :: [(Symbol, *)])
    #endif

    -- method ByteArray::free
    -- method type : MemberFunction
    -- Args : [Arg {argCName = "array", argType = TByteArray, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GByteArray", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "free_segment", argType = TBasicType TBoolean, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "if %TRUE the actual byte data is freed as well", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TUInt8)
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_byte_array_free" g_byte_array_free ::
        Ptr GByteArray ->                       -- array : TByteArray
        CInt ->                                 -- free_segment : TBasicType TBoolean
        IO Word8

    {- |
    Frees the memory allocated by the 'GI.GLib.Structs.ByteArray.ByteArray'. If /@freeSegment@/ is
    'True' it frees the actual byte data. If the reference count of
    /@array@/ is greater than one, the 'GI.GLib.Structs.ByteArray.ByteArray' wrapper is preserved but
    the size of /@array@/ will be set to zero.
    -}
    byteArrayFree ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        ByteString
        {- ^ /@array@/: a 'GI.GLib.Structs.ByteArray.ByteArray' -}
        -> Bool
        {- ^ /@freeSegment@/: if 'True' the actual byte data is freed as well -}
        -> m Word8
        {- ^ __Returns:__ the element data if /@freeSegment@/ is 'False', otherwise
             'Nothing'.  The element data should be freed using 'GI.GLib.Functions.free'. -}
    byteArrayFree array freeSegment = liftIO $ do
        array' <- packGByteArray array
        let freeSegment' = (fromIntegral . fromEnum) freeSegment
        result <- g_byte_array_free array' freeSegment'
        unrefGByteArray array'
        return result

    #if ENABLE_OVERLOADING
    #endif

    -- method ByteArray::free_to_bytes
    -- method type : MemberFunction
    -- Args : [Arg {argCName = "array", argType = TByteArray, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GByteArray", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "Bytes"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_byte_array_free_to_bytes" g_byte_array_free_to_bytes ::
        Ptr GByteArray ->                       -- array : TByteArray
        IO (Ptr GLib.Bytes.Bytes)

    {- |
    Transfers the data from the 'GI.GLib.Structs.ByteArray.ByteArray' into a new immutable 'GI.GLib.Structs.Bytes.Bytes'.

    The 'GI.GLib.Structs.ByteArray.ByteArray' is freed unless the reference count of /@array@/ is greater
    than one, the 'GI.GLib.Structs.ByteArray.ByteArray' wrapper is preserved but the size of /@array@/
    will be set to zero.

    This is identical to using 'GI.GLib.Structs.Bytes.bytesNewTake' and 'GI.GLib.Functions.byteArrayFree'
    together.

    /Since: 2.32/
    -}
    byteArrayFreeToBytes ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        ByteString
        {- ^ /@array@/: a 'GI.GLib.Structs.ByteArray.ByteArray' -}
        -> m GLib.Bytes.Bytes
        {- ^ __Returns:__ a new immutable 'GI.GLib.Structs.Bytes.Bytes' representing same
        byte data that was in the array -}
    byteArrayFreeToBytes array = liftIO $ do
        array' <- packGByteArray array
        result <- g_byte_array_free_to_bytes array'
        checkUnexpectedReturnNULL "byteArrayFreeToBytes" result
        result' <- (wrapBoxed GLib.Bytes.Bytes) result
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method ByteArray::new
    -- method type : MemberFunction
    -- Args : []
    -- Lengths : []
    -- returnType : Just TByteArray
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_byte_array_new" g_byte_array_new ::
        IO (Ptr GByteArray)

    {- |
    Creates a new 'GI.GLib.Structs.ByteArray.ByteArray' with a reference count of 1.
    -}
    byteArrayNew ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        m ByteString
        {- ^ __Returns:__ the new 'GI.GLib.Structs.ByteArray.ByteArray' -}
    byteArrayNew  = liftIO $ do
        result <- g_byte_array_new
        checkUnexpectedReturnNULL "byteArrayNew" result
        result' <- unpackGByteArray result
        unrefGByteArray result
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method ByteArray::new_take
    -- method type : MemberFunction
    -- Args : [Arg {argCName = "data", argType = TCArray False (-1) 1 (TBasicType TUInt8), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "byte data for the array", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "len", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "length of @data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : [Arg {argCName = "len", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "length of @data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- returnType : Just TByteArray
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_byte_array_new_take" g_byte_array_new_take ::
        Ptr Word8 ->                            -- data : TCArray False (-1) 1 (TBasicType TUInt8)
        Word64 ->                               -- len : TBasicType TUInt64
        IO (Ptr GByteArray)

    {- |
    Create byte array containing the data. The data will be owned by the array
    and will be freed with 'GI.GLib.Functions.free', i.e. it could be allocated using 'GI.GLib.Functions.strdup'.

    /Since: 2.32/
    -}
    byteArrayNewTake ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        ByteString
        {- ^ /@data@/: byte data for the array -}
        -> m ByteString
        {- ^ __Returns:__ a new 'GI.GLib.Structs.ByteArray.ByteArray' -}
    byteArrayNewTake data_ = liftIO $ do
        let len = fromIntegral $ B.length data_
        data_' <- packByteString data_
        result <- g_byte_array_new_take data_' len
        checkUnexpectedReturnNULL "byteArrayNewTake" result
        result' <- unpackGByteArray result
        unrefGByteArray result
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method ByteArray::unref
    -- method type : MemberFunction
    -- Args : [Arg {argCName = "array", argType = TByteArray, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "A #GByteArray", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_byte_array_unref" g_byte_array_unref ::
        Ptr GByteArray ->                       -- array : TByteArray
        IO ()

    {- |
    Atomically decrements the reference count of /@array@/ by one. If the
    reference count drops to 0, all memory allocated by the array is
    released. This function is thread-safe and may be called from any
    thread.

    /Since: 2.22/
    -}
    byteArrayUnref ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        ByteString
        {- ^ /@array@/: A 'GI.GLib.Structs.ByteArray.ByteArray' -}
        -> m ()
    byteArrayUnref array = liftIO $ do
        array' <- packGByteArray array
        g_byte_array_unref array'
        unrefGByteArray array'
        return ()

    #if ENABLE_OVERLOADING
    #endif

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

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

    #if MIN_VERSION_base(4,9,0)
    instance (info ~ ResolveByteArrayMethod t ByteArray, O.MethodInfo info ByteArray p) => O.IsLabel t (ByteArray -> 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