// This file was generated by the Gtk# code generator.
// Any changes made will be lost if regenerated.

namespace GstSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate bool ValueDeserializeWithPSpecFuncNative(IntPtr dest, IntPtr s, IntPtr pspec);

	internal class ValueDeserializeWithPSpecFuncInvoker {

		ValueDeserializeWithPSpecFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

		~ValueDeserializeWithPSpecFuncInvoker ()
		{
			if (__notify == null)
				return;
			__notify (__data);
		}

		internal ValueDeserializeWithPSpecFuncInvoker (ValueDeserializeWithPSpecFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal ValueDeserializeWithPSpecFuncInvoker (ValueDeserializeWithPSpecFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

		internal ValueDeserializeWithPSpecFuncInvoker (ValueDeserializeWithPSpecFuncNative native_cb, IntPtr data, GLib.DestroyNotify notify)
		{
			this.native_cb = native_cb;
			__data = data;
			__notify = notify;
		}

		internal Gst.ValueDeserializeWithPSpecFunc Handler {
			get {
				return new Gst.ValueDeserializeWithPSpecFunc(InvokeNative);
			}
		}

		bool InvokeNative (GLib.Value dest, string s, IntPtr pspec)
		{
			IntPtr native_dest = GLib.Marshaller.StructureToPtrAlloc (dest);
			IntPtr native_s = GLib.Marshaller.StringToPtrGStrdup (s);
			bool __result = native_cb (native_dest, native_s, pspec);
			Marshal.FreeHGlobal (native_dest);
			GLib.Marshaller.Free (native_s);
			return __result;
		}
	}

	internal class ValueDeserializeWithPSpecFuncWrapper {

		public bool NativeCallback (IntPtr dest, IntPtr s, IntPtr pspec)
		{
			try {
				bool __ret = managed ((GLib.Value) Marshal.PtrToStructure (dest, typeof (GLib.Value)), GLib.Marshaller.Utf8PtrToString (s), pspec);
				if (release_on_call)
					gch.Free ();
				return __ret;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
				return false;
			}
		}

		bool release_on_call = false;
		GCHandle gch;

		public void PersistUntilCalled ()
		{
			release_on_call = true;
			gch = GCHandle.Alloc (this);
		}

		internal ValueDeserializeWithPSpecFuncNative NativeDelegate;
		Gst.ValueDeserializeWithPSpecFunc managed;

		public ValueDeserializeWithPSpecFuncWrapper (Gst.ValueDeserializeWithPSpecFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new ValueDeserializeWithPSpecFuncNative (NativeCallback);
		}

		public static Gst.ValueDeserializeWithPSpecFunc GetManagedDelegate (ValueDeserializeWithPSpecFuncNative native)
		{
			if (native == null)
				return null;
			ValueDeserializeWithPSpecFuncWrapper wrapper = (ValueDeserializeWithPSpecFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
