{- |
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.
-}

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#
#ifdef ENABLE_OVERLOADING
    byteArray_data                          ,
#endif
    getByteArrayData                        ,
    setByteArrayData                        ,


-- ** len #attr:len#
#ifdef 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.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

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


noByteArray :: Maybe ByteArray
noByteArray = Nothing

getByteArrayData :: MonadIO m => ByteArray -> m Word8
getByteArrayData s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO Word8
    return val

setByteArrayData :: MonadIO m => ByteArray -> Word8 -> m ()
setByteArrayData s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (val :: Word8)

#ifdef 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


getByteArrayLen :: MonadIO m => ByteArray -> m Word32
getByteArrayLen s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 8) :: IO Word32
    return val

setByteArrayLen :: MonadIO m => ByteArray -> Word32 -> m ()
setByteArrayLen s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (val :: Word32)

#ifdef 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



#ifdef 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

#ifdef 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'

#ifdef 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'

#ifdef 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'

#ifdef 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 ()

#ifdef ENABLE_OVERLOADING
#endif

#ifdef 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