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

module GI.GLib.Structs.StringChunk
    ( 

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


 -- * Methods
-- ** clear #method:clear#
#ifdef ENABLE_OVERLOADING
    StringChunkClearMethodInfo              ,
#endif
    stringChunkClear                        ,


-- ** free #method:free#
#ifdef ENABLE_OVERLOADING
    StringChunkFreeMethodInfo               ,
#endif
    stringChunkFree                         ,


-- ** insert #method:insert#
#ifdef ENABLE_OVERLOADING
    StringChunkInsertMethodInfo             ,
#endif
    stringChunkInsert                       ,


-- ** insertConst #method:insertConst#
#ifdef ENABLE_OVERLOADING
    StringChunkInsertConstMethodInfo        ,
#endif
    stringChunkInsertConst                  ,


-- ** insertLen #method:insertLen#
#ifdef 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.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


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

noStringChunk :: Maybe StringChunk
noStringChunk = Nothing


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

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

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

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

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

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

#endif

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