{-# LANGUAGE TypeApplications #-}


-- | Copyright  : Will Thompson and Iñaki García Etxebarria
-- License    : LGPL-2.1
-- Maintainer : Iñaki García Etxebarria
-- 
-- @GStringChunk@ provides efficient storage of groups of strings
-- 
-- String chunks are used to store groups of strings. Memory is
-- allocated in blocks, and as strings are added to the @GStringChunk@
-- they are copied into the next free position in a block. When a block
-- is full a new block is allocated.
-- 
-- When storing a large number of strings, string chunks are more
-- efficient than using 'GI.GLib.Functions.strdup' since fewer calls to @malloc()@
-- are needed, and less memory is wasted in memory allocation overheads.
-- 
-- By adding strings with 'GI.GLib.Structs.StringChunk.stringChunkInsertConst' it is also
-- possible to remove duplicates.
-- 
-- To create a new @GStringChunk@ use t'GI.GLib.Structs.StringChunk.StringChunk'.@/new/@().
-- 
-- To add strings to a @GStringChunk@ use 'GI.GLib.Structs.StringChunk.stringChunkInsert'.
-- 
-- To add strings to a @GStringChunk@, but without duplicating strings
-- which are already in the @GStringChunk@, use 'GI.GLib.Structs.StringChunk.stringChunkInsertConst'.
-- 
-- To free the entire @GStringChunk@ use 'GI.GLib.Structs.StringChunk.stringChunkFree'.
-- It is not possible to free individual strings.

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

module GI.GLib.Structs.StringChunk
    ( 

-- * Exported types
    StringChunk(..)                         ,


 -- * Methods
-- | 
-- 
--  === __Click to display all available methods, including inherited ones__
-- ==== Methods
-- [clear]("GI.GLib.Structs.StringChunk#g:method:clear"), [insert]("GI.GLib.Structs.StringChunk#g:method:insert"), [insertConst]("GI.GLib.Structs.StringChunk#g:method:insertConst"), [insertLen]("GI.GLib.Structs.StringChunk#g:method:insertLen").
-- 
-- ==== Getters
-- /None/.
-- 
-- ==== Setters
-- /None/.

#if defined(ENABLE_OVERLOADING)
    ResolveStringChunkMethod                ,
#endif

-- ** clear #method:clear#

#if defined(ENABLE_OVERLOADING)
    StringChunkClearMethodInfo              ,
#endif
    stringChunkClear                        ,


-- ** insert #method:insert#

#if defined(ENABLE_OVERLOADING)
    StringChunkInsertMethodInfo             ,
#endif
    stringChunkInsert                       ,


-- ** insertConst #method:insertConst#

#if defined(ENABLE_OVERLOADING)
    StringChunkInsertConstMethodInfo        ,
#endif
    stringChunkInsertConst                  ,


-- ** insertLen #method:insertLen#

#if defined(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.BasicTypes as B.Types
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GArray as B.GArray
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GHashTable as B.GHT
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.GI.Base.Properties as B.Properties
import qualified Data.GI.Base.Signals as B.Signals
import qualified Control.Monad.IO.Class as MIO
import qualified Data.Coerce as Coerce
import qualified Data.Text as T
import qualified Data.Kind as DK
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL
import qualified GHC.Records as R
import qualified Data.Word as DW
import qualified Data.Int as DI
import qualified System.Posix.Types as SPT
import qualified Foreign.C.Types as FCT

-- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/23392
#if MIN_VERSION_base(4,18,0)

#else

#endif

-- | Memory-managed wrapper type.
newtype StringChunk = StringChunk (SP.ManagedPtr StringChunk)
    deriving (Eq)

instance SP.ManagedPtrNewtype StringChunk where
    toManagedPtr (StringChunk p) = p

-- XXX Wrapping a foreign struct/union with no known destructor or size, leak?
instance BoxedPtr StringChunk where
    boxedPtrCopy = return
    boxedPtrFree = \_x -> return ()


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

-- method StringChunk::clear
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "chunk"
--           , argType =
--               TInterface Name { namespace = "GLib" , name = "StringChunk" }
--           , argCType = Just "GStringChunk*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GStringChunk" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = 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 t'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 t'GI.GLib.Structs.StringChunk.StringChunk'
    -> m ()
stringChunkClear chunk = liftIO $ do
    chunk' <- unsafeManagedPtrGetPtr chunk
    g_string_chunk_clear chunk'
    touchManagedPtr chunk
    return ()

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

instance O.OverloadedMethodInfo StringChunkClearMethodInfo StringChunk where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.StringChunk.stringChunkClear",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-StringChunk.html#v:stringChunkClear"
        })


#endif

-- XXX Could not generate method StringChunk::free
-- Bad introspection data: Transferring a non-boxed struct with unknown size!
-- method StringChunk::insert
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "chunk"
--           , argType =
--               TInterface Name { namespace = "GLib" , name = "StringChunk" }
--           , argCType = Just "GStringChunk*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GStringChunk" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "string"
--           , argType = TBasicType TUTF8
--           , argCType = Just "const gchar*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the string to add" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = 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 t'GI.GLib.Structs.StringChunk.StringChunk'.
-- It returns a pointer to the new copy of the string
-- in the t'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 t'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 t'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 defined(ENABLE_OVERLOADING)
data StringChunkInsertMethodInfo
instance (signature ~ (T.Text -> m T.Text), MonadIO m) => O.OverloadedMethod StringChunkInsertMethodInfo StringChunk signature where
    overloadedMethod = stringChunkInsert

instance O.OverloadedMethodInfo StringChunkInsertMethodInfo StringChunk where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.StringChunk.stringChunkInsert",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-StringChunk.html#v:stringChunkInsert"
        })


#endif

-- method StringChunk::insert_const
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "chunk"
--           , argType =
--               TInterface Name { namespace = "GLib" , name = "StringChunk" }
--           , argCType = Just "GStringChunk*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GStringChunk" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "string"
--           , argType = TBasicType TUTF8
--           , argCType = Just "const gchar*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the string to add" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = 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 t'GI.GLib.Structs.StringChunk.StringChunk', unless the same
-- string has already been added to the t'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 t'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 t'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 defined(ENABLE_OVERLOADING)
data StringChunkInsertConstMethodInfo
instance (signature ~ (T.Text -> m T.Text), MonadIO m) => O.OverloadedMethod StringChunkInsertConstMethodInfo StringChunk signature where
    overloadedMethod = stringChunkInsertConst

instance O.OverloadedMethodInfo StringChunkInsertConstMethodInfo StringChunk where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.StringChunk.stringChunkInsertConst",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-StringChunk.html#v:stringChunkInsertConst"
        })


#endif

-- method StringChunk::insert_len
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "chunk"
--           , argType =
--               TInterface Name { namespace = "GLib" , name = "StringChunk" }
--           , argCType = Just "GStringChunk*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "a #GStringChunk" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "string"
--           , argType = TBasicType TUTF8
--           , argCType = Just "const gchar*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "bytes to insert" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "len"
--           , argType = TBasicType TSSize
--           , argCType = Just "gssize"
--           , 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
--           , argCallbackUserData = 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
    DI.Int64 ->                             -- len : TBasicType TSSize
    IO CString

-- | Adds a copy of the first /@len@/ bytes of /@string@/ to the t'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 t'GI.GLib.Structs.StringChunk.StringChunk'
    -> T.Text
    -- ^ /@string@/: bytes to insert
    -> DI.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 t'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 defined(ENABLE_OVERLOADING)
data StringChunkInsertLenMethodInfo
instance (signature ~ (T.Text -> DI.Int64 -> m T.Text), MonadIO m) => O.OverloadedMethod StringChunkInsertLenMethodInfo StringChunk signature where
    overloadedMethod = stringChunkInsertLen

instance O.OverloadedMethodInfo StringChunkInsertLenMethodInfo StringChunk where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.GLib.Structs.StringChunk.stringChunkInsertLen",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Structs-StringChunk.html#v:stringChunkInsertLen"
        })


#endif

#if defined(ENABLE_OVERLOADING)
type family ResolveStringChunkMethod (t :: Symbol) (o :: DK.Type) :: DK.Type where
    ResolveStringChunkMethod "clear" o = StringChunkClearMethodInfo
    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.OverloadedMethod info StringChunk p) => OL.IsLabel t (StringChunk -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod @info
#else
    fromLabel _ = O.overloadedMethod @info
#endif

#if MIN_VERSION_base(4,13,0)
instance (info ~ ResolveStringChunkMethod t StringChunk, O.OverloadedMethod info StringChunk p, R.HasField t StringChunk p) => R.HasField t StringChunk p where
    getField = O.overloadedMethod @info

#endif

instance (info ~ ResolveStringChunkMethod t StringChunk, O.OverloadedMethodInfo info StringChunk) => OL.IsLabel t (O.MethodProxy info StringChunk) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.MethodProxy
#else
    fromLabel _ = O.MethodProxy
#endif

#endif


