{- | Copyright : Will Thompson, Iñaki García Etxebarria and Jonas Platte License : LGPL-2.1 Maintainer : Iñaki García Etxebarria (garetxe@gmail.com) 'GI.Gio.Interfaces.Seekable.Seekable' is implemented by streams (implementations of 'GI.Gio.Objects.InputStream.InputStream' or 'GI.Gio.Objects.OutputStream.OutputStream') that support seeking. Seekable streams largely fall into two categories: resizable and fixed-size. 'GI.Gio.Interfaces.Seekable.Seekable' on fixed-sized streams is approximately the same as POSIX @/lseek()/@ on a block device (for example: attmepting to seek past the end of the device is an error). Fixed streams typically cannot be truncated. 'GI.Gio.Interfaces.Seekable.Seekable' on resizable streams is approximately the same as POSIX @/lseek()/@ on a normal file. Seeking past the end and writing data will usually cause the stream to resize by introducing zero bytes. -} #define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \ && !defined(__HADDOCK_VERSION__)) module GI.Gio.Interfaces.Seekable ( -- * Exported types Seekable(..) , noSeekable , IsSeekable , toSeekable , -- * Methods -- ** canSeek #method:canSeek# #if ENABLE_OVERLOADING SeekableCanSeekMethodInfo , #endif seekableCanSeek , -- ** canTruncate #method:canTruncate# #if ENABLE_OVERLOADING SeekableCanTruncateMethodInfo , #endif seekableCanTruncate , -- ** seek #method:seek# #if ENABLE_OVERLOADING SeekableSeekMethodInfo , #endif seekableSeek , -- ** tell #method:tell# #if ENABLE_OVERLOADING SeekableTellMethodInfo , #endif seekableTell , -- ** truncate #method:truncate# #if ENABLE_OVERLOADING SeekableTruncateMethodInfo , #endif seekableTruncate , ) 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 qualified GI.GLib.Enums as GLib.Enums import qualified GI.GObject.Objects.Object as GObject.Object import {-# SOURCE #-} qualified GI.Gio.Objects.Cancellable as Gio.Cancellable -- interface Seekable -- | Memory-managed wrapper type. newtype Seekable = Seekable (ManagedPtr Seekable) -- | A convenience alias for `Nothing` :: `Maybe` `Seekable`. noSeekable :: Maybe Seekable noSeekable = Nothing #if ENABLE_OVERLOADING type instance O.SignalList Seekable = SeekableSignalList type SeekableSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)]) #endif foreign import ccall "g_seekable_get_type" c_g_seekable_get_type :: IO GType instance GObject Seekable where gobjectType _ = c_g_seekable_get_type -- | Type class for types which can be safely cast to `Seekable`, for instance with `toSeekable`. class GObject o => IsSeekable o #if MIN_VERSION_base(4,9,0) instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError Seekable a) => IsSeekable a #endif instance IsSeekable Seekable instance GObject.Object.IsObject Seekable -- | Cast to `Seekable`, for types for which this is known to be safe. For general casts, use `Data.GI.Base.ManagedPtr.castTo`. toSeekable :: (MonadIO m, IsSeekable o) => o -> m Seekable toSeekable = liftIO . unsafeCastTo Seekable #if ENABLE_OVERLOADING instance O.HasAttributeList Seekable type instance O.AttributeList Seekable = SeekableAttributeList type SeekableAttributeList = ('[ ] :: [(Symbol, *)]) #endif #if ENABLE_OVERLOADING #endif #if ENABLE_OVERLOADING type family ResolveSeekableMethod (t :: Symbol) (o :: *) :: * where ResolveSeekableMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo ResolveSeekableMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo ResolveSeekableMethod "canSeek" o = SeekableCanSeekMethodInfo ResolveSeekableMethod "canTruncate" o = SeekableCanTruncateMethodInfo ResolveSeekableMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo ResolveSeekableMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo ResolveSeekableMethod "getv" o = GObject.Object.ObjectGetvMethodInfo ResolveSeekableMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo ResolveSeekableMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo ResolveSeekableMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo ResolveSeekableMethod "ref" o = GObject.Object.ObjectRefMethodInfo ResolveSeekableMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo ResolveSeekableMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo ResolveSeekableMethod "seek" o = SeekableSeekMethodInfo ResolveSeekableMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo ResolveSeekableMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo ResolveSeekableMethod "tell" o = SeekableTellMethodInfo ResolveSeekableMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo ResolveSeekableMethod "truncate" o = SeekableTruncateMethodInfo ResolveSeekableMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo ResolveSeekableMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo ResolveSeekableMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo ResolveSeekableMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo ResolveSeekableMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo ResolveSeekableMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo ResolveSeekableMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo ResolveSeekableMethod l o = O.MethodResolutionFailed l o instance (info ~ ResolveSeekableMethod t Seekable, O.MethodInfo info Seekable p) => O.IsLabelProxy t (Seekable -> p) where fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #if MIN_VERSION_base(4,9,0) instance (info ~ ResolveSeekableMethod t Seekable, O.MethodInfo info Seekable p) => O.IsLabel t (Seekable -> 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 -- method Seekable::can_seek -- method type : OrdinaryMethod -- Args : [Arg {argCName = "seekable", argType = TInterface (Name {namespace = "Gio", name = "Seekable"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GSeekable.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TBoolean) -- throws : False -- Skip return : False foreign import ccall "g_seekable_can_seek" g_seekable_can_seek :: Ptr Seekable -> -- seekable : TInterface (Name {namespace = "Gio", name = "Seekable"}) IO CInt {- | Tests if the stream supports the 'GI.Gio.Structs.SeekableIface.SeekableIface'. -} seekableCanSeek :: (B.CallStack.HasCallStack, MonadIO m, IsSeekable a) => a {- ^ /@seekable@/: a 'GI.Gio.Interfaces.Seekable.Seekable'. -} -> m Bool {- ^ __Returns:__ 'True' if /@seekable@/ can be seeked. 'False' otherwise. -} seekableCanSeek seekable = liftIO $ do seekable' <- unsafeManagedPtrCastPtr seekable result <- g_seekable_can_seek seekable' let result' = (/= 0) result touchManagedPtr seekable return result' #if ENABLE_OVERLOADING data SeekableCanSeekMethodInfo instance (signature ~ (m Bool), MonadIO m, IsSeekable a) => O.MethodInfo SeekableCanSeekMethodInfo a signature where overloadedMethod _ = seekableCanSeek #endif -- method Seekable::can_truncate -- method type : OrdinaryMethod -- Args : [Arg {argCName = "seekable", argType = TInterface (Name {namespace = "Gio", name = "Seekable"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GSeekable.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TBoolean) -- throws : False -- Skip return : False foreign import ccall "g_seekable_can_truncate" g_seekable_can_truncate :: Ptr Seekable -> -- seekable : TInterface (Name {namespace = "Gio", name = "Seekable"}) IO CInt {- | Tests if the length of the stream can be adjusted with 'GI.Gio.Interfaces.Seekable.seekableTruncate'. -} seekableCanTruncate :: (B.CallStack.HasCallStack, MonadIO m, IsSeekable a) => a {- ^ /@seekable@/: a 'GI.Gio.Interfaces.Seekable.Seekable'. -} -> m Bool {- ^ __Returns:__ 'True' if the stream can be truncated, 'False' otherwise. -} seekableCanTruncate seekable = liftIO $ do seekable' <- unsafeManagedPtrCastPtr seekable result <- g_seekable_can_truncate seekable' let result' = (/= 0) result touchManagedPtr seekable return result' #if ENABLE_OVERLOADING data SeekableCanTruncateMethodInfo instance (signature ~ (m Bool), MonadIO m, IsSeekable a) => O.MethodInfo SeekableCanTruncateMethodInfo a signature where overloadedMethod _ = seekableCanTruncate #endif -- method Seekable::seek -- method type : OrdinaryMethod -- Args : [Arg {argCName = "seekable", argType = TInterface (Name {namespace = "Gio", name = "Seekable"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GSeekable.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "offset", argType = TBasicType TInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #goffset.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "type", argType = TInterface (Name {namespace = "GLib", name = "SeekType"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GSeekType.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "cancellable", argType = TInterface (Name {namespace = "Gio", name = "Cancellable"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "optional #GCancellable object, %NULL to ignore.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TBoolean) -- throws : True -- Skip return : False foreign import ccall "g_seekable_seek" g_seekable_seek :: Ptr Seekable -> -- seekable : TInterface (Name {namespace = "Gio", name = "Seekable"}) Int64 -> -- offset : TBasicType TInt64 CUInt -> -- type : TInterface (Name {namespace = "GLib", name = "SeekType"}) Ptr Gio.Cancellable.Cancellable -> -- cancellable : TInterface (Name {namespace = "Gio", name = "Cancellable"}) Ptr (Ptr GError) -> -- error IO CInt {- | Seeks in the stream by the given /@offset@/, modified by /@type@/. Attempting to seek past the end of the stream will have different results depending on if the stream is fixed-sized or resizable. If the stream is resizable then seeking past the end and then writing will result in zeros filling the empty space. Seeking past the end of a resizable stream and reading will result in EOF. Seeking past the end of a fixed-sized stream will fail. Any operation that would result in a negative offset will fail. If /@cancellable@/ is not 'Nothing', then the operation can be cancelled by triggering the cancellable object from another thread. If the operation was cancelled, the error 'GI.Gio.Enums.IOErrorEnumCancelled' will be returned. -} seekableSeek :: (B.CallStack.HasCallStack, MonadIO m, IsSeekable a, Gio.Cancellable.IsCancellable b) => a {- ^ /@seekable@/: a 'GI.Gio.Interfaces.Seekable.Seekable'. -} -> Int64 {- ^ /@offset@/: a @/goffset/@. -} -> GLib.Enums.SeekType {- ^ /@type@/: a 'GI.GLib.Enums.SeekType'. -} -> Maybe (b) {- ^ /@cancellable@/: optional 'GI.Gio.Objects.Cancellable.Cancellable' object, 'Nothing' to ignore. -} -> m () {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -} seekableSeek seekable offset type_ cancellable = liftIO $ do seekable' <- unsafeManagedPtrCastPtr seekable let type_' = (fromIntegral . fromEnum) type_ maybeCancellable <- case cancellable of Nothing -> return nullPtr Just jCancellable -> do jCancellable' <- unsafeManagedPtrCastPtr jCancellable return jCancellable' onException (do _ <- propagateGError $ g_seekable_seek seekable' offset type_' maybeCancellable touchManagedPtr seekable whenJust cancellable touchManagedPtr return () ) (do return () ) #if ENABLE_OVERLOADING data SeekableSeekMethodInfo instance (signature ~ (Int64 -> GLib.Enums.SeekType -> Maybe (b) -> m ()), MonadIO m, IsSeekable a, Gio.Cancellable.IsCancellable b) => O.MethodInfo SeekableSeekMethodInfo a signature where overloadedMethod _ = seekableSeek #endif -- method Seekable::tell -- method type : OrdinaryMethod -- Args : [Arg {argCName = "seekable", argType = TInterface (Name {namespace = "Gio", name = "Seekable"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GSeekable.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TInt64) -- throws : False -- Skip return : False foreign import ccall "g_seekable_tell" g_seekable_tell :: Ptr Seekable -> -- seekable : TInterface (Name {namespace = "Gio", name = "Seekable"}) IO Int64 {- | Tells the current position within the stream. -} seekableTell :: (B.CallStack.HasCallStack, MonadIO m, IsSeekable a) => a {- ^ /@seekable@/: a 'GI.Gio.Interfaces.Seekable.Seekable'. -} -> m Int64 {- ^ __Returns:__ the offset from the beginning of the buffer. -} seekableTell seekable = liftIO $ do seekable' <- unsafeManagedPtrCastPtr seekable result <- g_seekable_tell seekable' touchManagedPtr seekable return result #if ENABLE_OVERLOADING data SeekableTellMethodInfo instance (signature ~ (m Int64), MonadIO m, IsSeekable a) => O.MethodInfo SeekableTellMethodInfo a signature where overloadedMethod _ = seekableTell #endif -- method Seekable::truncate -- method type : OrdinaryMethod -- Args : [Arg {argCName = "seekable", argType = TInterface (Name {namespace = "Gio", name = "Seekable"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GSeekable.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "offset", argType = TBasicType TInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "new length for @seekable, in bytes.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "cancellable", argType = TInterface (Name {namespace = "Gio", name = "Cancellable"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "optional #GCancellable object, %NULL to ignore.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TBoolean) -- throws : True -- Skip return : False foreign import ccall "g_seekable_truncate" g_seekable_truncate :: Ptr Seekable -> -- seekable : TInterface (Name {namespace = "Gio", name = "Seekable"}) Int64 -> -- offset : TBasicType TInt64 Ptr Gio.Cancellable.Cancellable -> -- cancellable : TInterface (Name {namespace = "Gio", name = "Cancellable"}) Ptr (Ptr GError) -> -- error IO CInt {- | Sets the length of the stream to /@offset@/. If the stream was previously larger than /@offset@/, the extra data is discarded. If the stream was previouly shorter than /@offset@/, it is extended with NUL (\'\\0\') bytes. If /@cancellable@/ is not 'Nothing', then the operation can be cancelled by triggering the cancellable object from another thread. If the operation was cancelled, the error 'GI.Gio.Enums.IOErrorEnumCancelled' will be returned. If an operation was partially finished when the operation was cancelled the partial result will be returned, without an error. -} seekableTruncate :: (B.CallStack.HasCallStack, MonadIO m, IsSeekable a, Gio.Cancellable.IsCancellable b) => a {- ^ /@seekable@/: a 'GI.Gio.Interfaces.Seekable.Seekable'. -} -> Int64 {- ^ /@offset@/: new length for /@seekable@/, in bytes. -} -> Maybe (b) {- ^ /@cancellable@/: optional 'GI.Gio.Objects.Cancellable.Cancellable' object, 'Nothing' to ignore. -} -> m () {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -} seekableTruncate seekable offset cancellable = liftIO $ do seekable' <- unsafeManagedPtrCastPtr seekable maybeCancellable <- case cancellable of Nothing -> return nullPtr Just jCancellable -> do jCancellable' <- unsafeManagedPtrCastPtr jCancellable return jCancellable' onException (do _ <- propagateGError $ g_seekable_truncate seekable' offset maybeCancellable touchManagedPtr seekable whenJust cancellable touchManagedPtr return () ) (do return () ) #if ENABLE_OVERLOADING data SeekableTruncateMethodInfo instance (signature ~ (Int64 -> Maybe (b) -> m ()), MonadIO m, IsSeekable a, Gio.Cancellable.IsCancellable b) => O.MethodInfo SeekableTruncateMethodInfo a signature where overloadedMethod _ = seekableTruncate #endif