// 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 IntPtr ValueSerializeFuncNative(IntPtr value1);

	internal class ValueSerializeFuncInvoker {

		ValueSerializeFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

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

		internal ValueSerializeFuncInvoker (ValueSerializeFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal ValueSerializeFuncInvoker (ValueSerializeFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

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

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

		string InvokeNative (GLib.Value value1)
		{
			IntPtr native_value1 = GLib.Marshaller.StructureToPtrAlloc (value1);
			string __result = GLib.Marshaller.PtrToStringGFree(native_cb (native_value1));
			Marshal.FreeHGlobal (native_value1);
			return __result;
		}
	}

	internal class ValueSerializeFuncWrapper {

		public IntPtr NativeCallback (IntPtr value1)
		{
			try {
				string __ret = managed ((GLib.Value) Marshal.PtrToStructure (value1, typeof (GLib.Value)));
				if (release_on_call)
					gch.Free ();
				return GLib.Marshaller.StringToPtrGStrdup(__ret);
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: Above call does not return.
				throw e;
			}
		}

		bool release_on_call = false;
		GCHandle gch;

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

		internal ValueSerializeFuncNative NativeDelegate;
		Gst.ValueSerializeFunc managed;

		public ValueSerializeFuncWrapper (Gst.ValueSerializeFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new ValueSerializeFuncNative (NativeCallback);
		}

		public static Gst.ValueSerializeFunc GetManagedDelegate (ValueSerializeFuncNative native)
		{
			if (native == null)
				return null;
			ValueSerializeFuncWrapper wrapper = (ValueSerializeFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
