Files
go-gst/gst/gst_message.go

149 lines
5.3 KiB
Go

package gst
// #include "gst.go.h"
import "C"
import (
"strings"
"unsafe"
)
// Message is a Go wrapper around a GstMessage. It provides convenience methods for
// unref-ing and parsing the underlying messages.
type Message struct {
msg *C.GstMessage
}
// Native returns the underlying GstMessage object.
func (m *Message) Native() *C.GstMessage { return C.toGstMessage(unsafe.Pointer(m.msg)) }
// Type returns the MessageType of the message.
func (m *Message) Type() MessageType {
return MessageType(m.Native()._type)
}
// TypeName returns a Go string of the GstMessageType name.
func (m *Message) TypeName() string {
return C.GoString(C.gst_message_type_get_name((C.GstMessageType)(m.Type())))
}
// GetStructure returns the GstStructure of this message, using the type of the message
// to determine the method to use. The returned structure must not be freed.
func (m *Message) GetStructure() *Structure {
var st *C.GstStructure
switch m.Type() {
case MessageError:
C.gst_message_parse_error_details((*C.GstMessage)(m.Native()), (**C.GstStructure)(unsafe.Pointer(&st)))
case MessageInfo:
C.gst_message_parse_info_details((*C.GstMessage)(m.Native()), (**C.GstStructure)(unsafe.Pointer(&st)))
case MessageWarning:
C.gst_message_parse_warning_details((*C.GstMessage)(m.Native()), (**C.GstStructure)(unsafe.Pointer(&st)))
}
// if no structure was returned, immediately return nil
if st == nil {
return nil
}
// The returned structure must not be freed. Applies to all methods.
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstmessage.html#gst_message_parse_error_details
return wrapStructure(st)
}
// parseToError returns a new GoGError from this message instance. There are multiple
// message types that parse to this interface.
func (m *Message) parseToError() *GoGError {
var gerr *C.GError
var debugInfo *C.gchar
switch m.Type() {
case MessageError:
C.gst_message_parse_error((*C.GstMessage)(m.Native()), (**C.GError)(unsafe.Pointer(&gerr)), (**C.gchar)(unsafe.Pointer(&debugInfo)))
case MessageInfo:
C.gst_message_parse_info((*C.GstMessage)(m.Native()), (**C.GError)(unsafe.Pointer(&gerr)), (**C.gchar)(unsafe.Pointer(&debugInfo)))
case MessageWarning:
C.gst_message_parse_warning((*C.GstMessage)(m.Native()), (**C.GError)(unsafe.Pointer(&gerr)), (**C.gchar)(unsafe.Pointer(&debugInfo)))
}
// if error was nil return immediately
if gerr == nil {
return nil
}
// cleanup the C error immediately and let the garbage collector
// take over from here.
defer C.g_error_free((*C.GError)(gerr))
defer C.g_free((C.gpointer)(debugInfo))
return &GoGError{
errMsg: C.GoString(gerr.message),
structure: m.GetStructure(),
debugStr: strings.TrimSpace(C.GoString((*C.gchar)(debugInfo))),
}
}
// ParseInfo is identical to ParseError. The returned types are the same. However,
// this is intended for use with GstMessageType `GST_MESSAGE_INFO`.
func (m *Message) ParseInfo() *GoGError {
return m.parseToError()
}
// ParseWarning is identical to ParseError. The returned types are the same. However,
// this is intended for use with GstMessageType `GST_MESSAGE_WARNING`.
func (m *Message) ParseWarning() *GoGError {
return m.parseToError()
}
// ParseError will return a GoGError from the contents of this message. This will only work
// if the GstMessageType is `GST_MESSAGE_ERROR`.
func (m *Message) ParseError() *GoGError {
return m.parseToError()
}
// ParseStateChanged will return the old and new states as Go strings. This will only work
// if the GstMessageType is `GST_MESSAGE_STATE_CHANGED`.
func (m *Message) ParseStateChanged() (oldState, newState State) {
var gOldState, gNewState C.GstState
C.gst_message_parse_state_changed((*C.GstMessage)(m.Native()), (*C.GstState)(unsafe.Pointer(&gOldState)), (*C.GstState)(unsafe.Pointer(&gNewState)), nil)
oldState = State(gOldState)
newState = State(gNewState)
return
}
// Unref will call `gst_message_unref` on the underlying GstMessage, freeing it from memory.
func (m *Message) Unref() { C.gst_message_unref((*C.GstMessage)(m.Native())) }
// Ref will increase the ref count on this message. This increases the total amount of times
// Unref needs to be called before the object is freed from memory. It returns the underlying
// message object for convenience.
func (m *Message) Ref() *Message {
C.gst_message_ref((*C.GstMessage)(m.Native()))
return m
}
// Copy will copy this object into a new Message that can be Unrefed separately.
func (m *Message) Copy() *Message {
newNative := C.gst_message_copy((*C.GstMessage)(m.Native()))
return wrapMessage(newNative)
}
// GoGError is a Go wrapper for a C GError. It implements the error interface
// and provides additional functions for retrieving debug strings and details.
type GoGError struct {
errMsg, debugStr string
structure *Structure
}
// Message is an alias to `Error()`. It's for clarity when this object
// is parsed from a `GST_MESSAGE_INFO` or `GST_MESSAGE_WARNING`.
func (e *GoGError) Message() string { return e.Error() }
// Error implements the error interface and returns the error message.
func (e *GoGError) Error() string { return e.errMsg }
// DebugString returns any debug info alongside the error.
func (e *GoGError) DebugString() string { return e.debugStr }
// Structure returns the structure of the error message which may contain additional metadata.
func (e *GoGError) Structure() *Structure { return e.structure }