GtkSharp/glib/Variant.cs
Bertrand Lorentz a1636d306b Variant: Add a NewArray (Variant[] children) convenience method
This allows you to avoid ugly calls like "NewArray (null, some_array)"
when you want the child type to be determined by the first element of
the children array.

Also throw specific exceptions when both type and children parameters
would be null.
2014-06-13 13:10:48 +02:00

344 lines
11 KiB
C#

// Copyright (c) 2011 Novell, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the Lesser GNU General
// Public License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace GLib {
public class Variant : IDisposable {
IntPtr handle;
public IntPtr Handle {
get { return handle; }
}
// Docs say that GVariant is threadsafe.
~Variant ()
{
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern void g_variant_unref (IntPtr handle);
void Dispose (bool disposing)
{
if (handle == IntPtr.Zero)
return;
g_variant_unref (handle);
handle = IntPtr.Zero;
if (disposing)
GC.SuppressFinalize (this);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_ref_sink (IntPtr handle);
public Variant (IntPtr handle)
{
this.handle = g_variant_ref_sink (handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_get_type (IntPtr val);
VariantType type;
public VariantType Type {
get {
if (type == null)
type = new VariantType (g_variant_get_type (Handle));
return type;
}
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_variant (IntPtr val);
public static Variant NewVariant (Variant val) {
return new Variant (g_variant_new_variant (val.Handle));
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_boolean (bool val);
public Variant (bool val) : this (g_variant_new_boolean (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_byte (byte val);
public Variant (byte val) : this (g_variant_new_byte (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_int16 (short val);
public Variant (short val) : this (g_variant_new_int16 (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_uint16 (ushort val);
public Variant (ushort val) : this (g_variant_new_uint16 (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_int32 (int val);
public Variant (int val) : this (g_variant_new_int32 (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_uint32 (uint val);
public Variant (uint val) : this (g_variant_new_uint32 (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_int64 (long val);
public Variant (long val) : this (g_variant_new_int64 (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_uint64 (ulong val);
public Variant (ulong val) : this (g_variant_new_uint64 (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_double (double val);
public Variant (double val) : this (g_variant_new_double (val)) {}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_string (IntPtr val);
public Variant (string val)
{
IntPtr native_val = Marshaller.StringToPtrGStrdup (val);
handle = g_variant_ref_sink (g_variant_new_string (native_val));
Marshaller.Free (native_val);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_strv (IntPtr[] strv, IntPtr length);
public Variant (string[] strv)
{
IntPtr[] native = Marshaller.StringArrayToNullTermPointer (strv);
handle = g_variant_ref_sink (g_variant_new_strv (native, new IntPtr ((long) strv.Length)));
Marshaller.Free (native);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_tuple (IntPtr[] children, UIntPtr n_children);
public static Variant NewTuple (Variant[] children)
{
if (children == null)
return new Variant (g_variant_new_tuple (null, new UIntPtr (0ul)));
IntPtr[] native = new IntPtr[children.Length];
for (int i = 0; i < children.Length; i++)
native[i] = children[i].Handle;
return new Variant (g_variant_new_tuple (native, new UIntPtr ((ulong) children.Length)));
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_array (IntPtr child_type, IntPtr[] children, UIntPtr n_children);
public static Variant NewArray (Variant[] children)
{
if (children == null) {
throw new ArgumentNullException ("children", "To create an empty array use NewArray (VariantType.<Type>, null)");
}
return NewArray (null, children);
}
public static Variant NewArray (VariantType type, Variant[] children)
{
if (children == null) {
if (type == null) {
throw new ArgumentException ("The type and children parameters cannot be both null");
} else {
return new Variant (g_variant_new_array (type.Handle, null, new UIntPtr (0ul)));
}
}
IntPtr[] native = new IntPtr[children.Length];
for (int i = 0; i < children.Length; i++)
native[i] = children[i].Handle;
return new Variant (g_variant_new_array (type == null ? (IntPtr) null : type.Handle,
native, new UIntPtr ((ulong) children.Length)));
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_new_dict_entry (IntPtr k, IntPtr v);
public static Variant NewDictEntry (Variant k, Variant v)
{
return new Variant (g_variant_new_dict_entry (k.Handle, v.Handle));
}
public Variant (IDictionary<string, Variant> dict)
{
VariantType type = VariantType.NewDictionaryEntry (
VariantType.String,
VariantType.Variant);
var pairs = new List<Variant> ();
foreach (var kvp in dict)
pairs.Add (NewDictEntry (new Variant (kvp.Key), NewVariant (kvp.Value)));
handle = g_variant_ref_sink (NewArray (type, pairs.ToArray ()).Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern bool g_variant_get_boolean (IntPtr handle);
public static explicit operator bool (Variant val)
{
return g_variant_get_boolean (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern byte g_variant_get_byte (IntPtr handle);
public static explicit operator byte (Variant val)
{
return g_variant_get_byte (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern short g_variant_get_int16 (IntPtr handle);
public static explicit operator short (Variant val)
{
return g_variant_get_int16 (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern ushort g_variant_get_uint16 (IntPtr handle);
public static explicit operator ushort (Variant val)
{
return g_variant_get_uint16 (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern int g_variant_get_int32 (IntPtr handle);
public static explicit operator int (Variant val)
{
return g_variant_get_int32 (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern uint g_variant_get_uint32 (IntPtr handle);
public static explicit operator uint (Variant val)
{
return g_variant_get_uint32 (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern long g_variant_get_int64 (IntPtr handle);
public static explicit operator long (Variant val)
{
return g_variant_get_int64 (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern ulong g_variant_get_uint64 (IntPtr handle);
public static explicit operator ulong (Variant val)
{
return g_variant_get_uint64 (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern double g_variant_get_double (IntPtr handle);
public static explicit operator double (Variant val)
{
return g_variant_get_double (val.Handle);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_get_string (IntPtr handle);
public static explicit operator string (Variant val)
{
IntPtr str = g_variant_get_string (val.Handle);
return str == IntPtr.Zero ? null : GLib.Marshaller.Utf8PtrToString (str);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_print (IntPtr variant, bool type_annotate);
public string Print (bool type_annotate)
{
IntPtr str = g_variant_print (handle, type_annotate);
return Marshaller.PtrToStringGFree (str);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_n_children (IntPtr handle);
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_get_child_value (IntPtr handle, IntPtr index);
public Variant[] ToArray ()
{
var n_children = (long) g_variant_n_children (Handle);
var ret = new Variant[n_children];
for (long i = 0; i < n_children; i++) {
var h = g_variant_get_child_value (Handle, new IntPtr (i));
ret[i] = new Variant (h);
g_variant_unref (h);
}
return ret;
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr g_variant_get_variant (IntPtr handle);
public Dictionary<string, Variant> ToAsv ()
{
var ret = new Dictionary<string, Variant> ();
foreach (var dictEntry in ToArray ()) {
var pair = dictEntry.ToArray ();
var key = (string) pair[0];
var h = g_variant_get_variant (pair[1].Handle);
var value = new Variant (h);
g_variant_unref (h);
ret.Add (key, value);
}
return ret;
}
}
}