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

    An opaque data structure representing String Chunks.
    It should only be accessed by using the following functions.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.StringChunk
        (

    -- * Exported types
        StringChunk(..)                         ,
        noStringChunk                           ,

     -- * Methods
    -- ** clear #method:clear#

    #if ENABLE_OVERLOADING
        StringChunkClearMethodInfo              ,
    #endif
        stringChunkClear                        ,

    -- ** free #method:free#

    #if ENABLE_OVERLOADING
        StringChunkFreeMethodInfo               ,
    #endif
        stringChunkFree                         ,

    -- ** insert #method:insert#

    #if ENABLE_OVERLOADING
        StringChunkInsertMethodInfo             ,
    #endif
        stringChunkInsert                       ,

    -- ** insertConst #method:insertConst#

    #if ENABLE_OVERLOADING
        StringChunkInsertConstMethodInfo        ,
    #endif
        stringChunkInsertConst                  ,

    -- ** insertLen #method:insertLen#

    #if ENABLE_OVERLOADING
        StringChunkInsertLenMethodInfo          ,
    #endif
        stringChunkInsertLen                    ,

        ) 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

    -- | Memory-managed wrapper type.
    newtype StringChunk = StringChunk (ManagedPtr StringChunk)
    -- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
    instance WrappedPtr StringChunk where
        wrappedPtrCalloc = return nullPtr
        wrappedPtrCopy = return
        wrappedPtrFree = Nothing

    -- | A convenience alias for `Nothing` :: `Maybe` `StringChunk`.
    noStringChunk :: Maybe StringChunk
    noStringChunk = Nothing

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList StringChunk
    type instance O.AttributeList StringChunk = StringChunkAttributeList
    type StringChunkAttributeList = ('[ ] :: [(Symbol, *)])
    #endif

    -- method StringChunk::clear
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "chunk", argType = TInterface (Name {namespace = "GLib", name = "StringChunk"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GStringChunk", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_string_chunk_clear" g_string_chunk_clear ::
        Ptr StringChunk ->                      -- chunk : TInterface (Name {namespace = "GLib", name = "StringChunk"})
        IO ()

    {- |
    Frees all strings contained within the 'GI.GLib.Structs.StringChunk.StringChunk'.
    After calling 'GI.GLib.Structs.StringChunk.stringChunkClear' it is not safe to
    access any of the strings which were contained within it.

    /Since: 2.14/
    -}
    stringChunkClear ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        StringChunk
        {- ^ /@chunk@/: a 'GI.GLib.Structs.StringChunk.StringChunk' -}
        -> m ()
    stringChunkClear chunk = liftIO $ do
        chunk' <- unsafeManagedPtrGetPtr chunk
        g_string_chunk_clear chunk'
        touchManagedPtr chunk
        return ()

    #if ENABLE_OVERLOADING
    data StringChunkClearMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo StringChunkClearMethodInfo StringChunk signature where
        overloadedMethod _ = stringChunkClear

    #endif

    -- method StringChunk::free
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "chunk", argType = TInterface (Name {namespace = "GLib", name = "StringChunk"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GStringChunk", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_string_chunk_free" g_string_chunk_free ::
        Ptr StringChunk ->                      -- chunk : TInterface (Name {namespace = "GLib", name = "StringChunk"})
        IO ()

    {- |
    Frees all memory allocated by the 'GI.GLib.Structs.StringChunk.StringChunk'.
    After calling 'GI.GLib.Structs.StringChunk.stringChunkFree' it is not safe to
    access any of the strings which were contained within it.
    -}
    stringChunkFree ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        StringChunk
        {- ^ /@chunk@/: a 'GI.GLib.Structs.StringChunk.StringChunk' -}
        -> m ()
    stringChunkFree chunk = liftIO $ do
        chunk' <- unsafeManagedPtrGetPtr chunk
        g_string_chunk_free chunk'
        touchManagedPtr chunk
        return ()

    #if ENABLE_OVERLOADING
    data StringChunkFreeMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo StringChunkFreeMethodInfo StringChunk signature where
        overloadedMethod _ = stringChunkFree

    #endif

    -- method StringChunk::insert
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "chunk", argType = TInterface (Name {namespace = "GLib", name = "StringChunk"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GStringChunk", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "string", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the string to add", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TUTF8)
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_string_chunk_insert" g_string_chunk_insert ::
        Ptr StringChunk ->                      -- chunk : TInterface (Name {namespace = "GLib", name = "StringChunk"})
        CString ->                              -- string : TBasicType TUTF8
        IO CString

    {- |
    Adds a copy of /@string@/ to the 'GI.GLib.Structs.StringChunk.StringChunk'.
    It returns a pointer to the new copy of the string
    in the 'GI.GLib.Structs.StringChunk.StringChunk'. The characters in the string
    can be changed, if necessary, though you should not
    change anything after the end of the string.

    Unlike 'GI.GLib.Structs.StringChunk.stringChunkInsertConst', this function
    does not check for duplicates. Also strings added
    with 'GI.GLib.Structs.StringChunk.stringChunkInsert' will not be searched
    by 'GI.GLib.Structs.StringChunk.stringChunkInsertConst' when looking for
    duplicates.
    -}
    stringChunkInsert ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        StringChunk
        {- ^ /@chunk@/: a 'GI.GLib.Structs.StringChunk.StringChunk' -}
        -> T.Text
        {- ^ /@string@/: the string to add -}
        -> m T.Text
        {- ^ __Returns:__ a pointer to the copy of /@string@/ within
        the 'GI.GLib.Structs.StringChunk.StringChunk' -}
    stringChunkInsert chunk string = liftIO $ do
        chunk' <- unsafeManagedPtrGetPtr chunk
        string' <- textToCString string
        result <- g_string_chunk_insert chunk' string'
        checkUnexpectedReturnNULL "stringChunkInsert" result
        result' <- cstringToText result
        freeMem result
        touchManagedPtr chunk
        freeMem string'
        return result'

    #if ENABLE_OVERLOADING
    data StringChunkInsertMethodInfo
    instance (signature ~ (T.Text -> m T.Text), MonadIO m) => O.MethodInfo StringChunkInsertMethodInfo StringChunk signature where
        overloadedMethod _ = stringChunkInsert

    #endif

    -- method StringChunk::insert_const
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "chunk", argType = TInterface (Name {namespace = "GLib", name = "StringChunk"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GStringChunk", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "string", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the string to add", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TUTF8)
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_string_chunk_insert_const" g_string_chunk_insert_const ::
        Ptr StringChunk ->                      -- chunk : TInterface (Name {namespace = "GLib", name = "StringChunk"})
        CString ->                              -- string : TBasicType TUTF8
        IO CString

    {- |
    Adds a copy of /@string@/ to the 'GI.GLib.Structs.StringChunk.StringChunk', unless the same
    string has already been added to the 'GI.GLib.Structs.StringChunk.StringChunk' with
    'GI.GLib.Structs.StringChunk.stringChunkInsertConst'.

    This function is useful if you need to copy a large number
    of strings but do not want to waste space storing duplicates.
    But you must remember that there may be several pointers to
    the same string, and so any changes made to the strings
    should be done very carefully.

    Note that 'GI.GLib.Structs.StringChunk.stringChunkInsertConst' will not return a
    pointer to a string added with 'GI.GLib.Structs.StringChunk.stringChunkInsert', even
    if they do match.
    -}
    stringChunkInsertConst ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        StringChunk
        {- ^ /@chunk@/: a 'GI.GLib.Structs.StringChunk.StringChunk' -}
        -> T.Text
        {- ^ /@string@/: the string to add -}
        -> m T.Text
        {- ^ __Returns:__ a pointer to the new or existing copy of /@string@/
        within the 'GI.GLib.Structs.StringChunk.StringChunk' -}
    stringChunkInsertConst chunk string = liftIO $ do
        chunk' <- unsafeManagedPtrGetPtr chunk
        string' <- textToCString string
        result <- g_string_chunk_insert_const chunk' string'
        checkUnexpectedReturnNULL "stringChunkInsertConst" result
        result' <- cstringToText result
        freeMem result
        touchManagedPtr chunk
        freeMem string'
        return result'

    #if ENABLE_OVERLOADING
    data StringChunkInsertConstMethodInfo
    instance (signature ~ (T.Text -> m T.Text), MonadIO m) => O.MethodInfo StringChunkInsertConstMethodInfo StringChunk signature where
        overloadedMethod _ = stringChunkInsertConst

    #endif

    -- method StringChunk::insert_len
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "chunk", argType = TInterface (Name {namespace = "GLib", name = "StringChunk"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GStringChunk", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "string", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "bytes to insert", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "len", argType = TBasicType TInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "number of bytes of @string to insert, or -1 to insert a\n    nul-terminated string", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TUTF8)
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_string_chunk_insert_len" g_string_chunk_insert_len ::
        Ptr StringChunk ->                      -- chunk : TInterface (Name {namespace = "GLib", name = "StringChunk"})
        CString ->                              -- string : TBasicType TUTF8
        Int64 ->                                -- len : TBasicType TInt64
        IO CString

    {- |
    Adds a copy of the first /@len@/ bytes of /@string@/ to the 'GI.GLib.Structs.StringChunk.StringChunk'.
    The copy is nul-terminated.

    Since this function does not stop at nul bytes, it is the caller\'s
    responsibility to ensure that /@string@/ has at least /@len@/ addressable
    bytes.

    The characters in the returned string can be changed, if necessary,
    though you should not change anything after the end of the string.

    /Since: 2.4/
    -}
    stringChunkInsertLen ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        StringChunk
        {- ^ /@chunk@/: a 'GI.GLib.Structs.StringChunk.StringChunk' -}
        -> T.Text
        {- ^ /@string@/: bytes to insert -}
        -> Int64
        {- ^ /@len@/: number of bytes of /@string@/ to insert, or -1 to insert a
        nul-terminated string -}
        -> m T.Text
        {- ^ __Returns:__ a pointer to the copy of /@string@/ within the 'GI.GLib.Structs.StringChunk.StringChunk' -}
    stringChunkInsertLen chunk string len = liftIO $ do
        chunk' <- unsafeManagedPtrGetPtr chunk
        string' <- textToCString string
        result <- g_string_chunk_insert_len chunk' string' len
        checkUnexpectedReturnNULL "stringChunkInsertLen" result
        result' <- cstringToText result
        freeMem result
        touchManagedPtr chunk
        freeMem string'
        return result'

    #if ENABLE_OVERLOADING
    data StringChunkInsertLenMethodInfo
    instance (signature ~ (T.Text -> Int64 -> m T.Text), MonadIO m) => O.MethodInfo StringChunkInsertLenMethodInfo StringChunk signature where
        overloadedMethod _ = stringChunkInsertLen

    #endif

    #if ENABLE_OVERLOADING
    type family ResolveStringChunkMethod (t :: Symbol) (o :: *) :: * where
        ResolveStringChunkMethod "clear" o = StringChunkClearMethodInfo
        ResolveStringChunkMethod "free" o = StringChunkFreeMethodInfo
        ResolveStringChunkMethod "insert" o = StringChunkInsertMethodInfo
        ResolveStringChunkMethod "insertConst" o = StringChunkInsertConstMethodInfo
        ResolveStringChunkMethod "insertLen" o = StringChunkInsertLenMethodInfo
        ResolveStringChunkMethod l o = O.MethodResolutionFailed l o

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

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