Embryonic CIL bindings for libvlc-control
[vlc.git] / bindings / cil / marshal.cs
1 /*
2  * libvlc.cs - libvlc-control CIL bindings
3  *
4  * $Id$
5  */
6
7 /**********************************************************************
8  *  Copyright (C) 2007 RĂ©mi Denis-Courmont.                           *
9  *  This program is free software; you can redistribute and/or modify *
10  *  it under the terms of the GNU General Public License as published *
11  *  by the Free Software Foundation; version 2 of the license, or (at *
12  *  your option) any later version.                                   *
13  *                                                                    *
14  *  This program is distributed in the hope that it will be useful,   *
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of    *
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              *
17  *  See the GNU General Public License for more details.              *
18  *                                                                    *
19  *  You should have received a copy of the GNU General Public License *
20  *  along with this program; if not, you can get it from:             *
21  *  http://www.gnu.org/copyleft/gpl.html                              *
22  **********************************************************************/
23
24 using System;
25 using System.Runtime.InteropServices;
26
27 namespace VideoLAN.VLC
28 {
29     internal class MediaControlAPI
30     {
31         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_new")]
32         public static extern MediaControlHandle New (int argc, U8String[] argv, ref NativeException e);
33         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_exit")]
34         public static extern void Exit (IntPtr self);
35
36         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_start")]
37         public static extern void Start (MediaControlHandle self, IntPtr pos, ref NativeException e);
38         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_pause")]
39         public static extern void Pause (MediaControlHandle self, IntPtr dummy, ref NativeException e);
40         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_resume")]
41         public static extern void Resume (MediaControlHandle self, IntPtr dummy, ref NativeException e);
42         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_stop")]
43         public static extern void Stop (MediaControlHandle self, IntPtr dummy, ref NativeException e);
44
45         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_add_item")]
46         public static extern void PlaylistAddItem (MediaControlHandle self, U8String mrl, ref NativeException e);
47         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_clear")]
48         public static extern void PlaylistClear (MediaControlHandle self, ref NativeException e);
49         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_get_list")]
50         public static extern IntPtr PlaylistGetList (MediaControlHandle self, ref NativeException e);
51         [DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_next_item")]
52         public static extern void PlaylistNextItem (MediaControlHandle self, ref NativeException e);
53     }
54
55     /**
56      * Abstract safe handle class for non-NULL pointers
57      * (Microsoft.* namespace has a similar class, but lets stick to System.*)
58      */
59     internal abstract class NonNullHandle : SafeHandle
60     {
61         protected NonNullHandle ()
62             : base (IntPtr.Zero, true)
63         {
64         }
65
66         public override bool IsInvalid
67         {
68             get
69             {
70                 return IsClosed || (handle == IntPtr.Zero);
71             }
72         }
73     };
74
75     internal sealed class MediaControlHandle : NonNullHandle
76     {
77         private MediaControlHandle ()
78         {
79         }
80
81         protected override bool ReleaseHandle ()
82         {
83             MediaControlAPI.Exit (handle);
84             return true;
85         }
86     };
87
88     /**
89      * Wrapper around native UTF-8 nul-terminated character arrays
90      */
91     [StructLayout (LayoutKind.Sequential)]
92     internal sealed struct U8String
93     {
94         byte[] mb_str;
95
96         public U8String (string value)
97         {
98             byte[] bytes = System.Text.Encoding.UTF8.GetBytes (value);
99             mb_str = new byte[bytes.Length + 1];
100             Array.Copy (bytes, mb_str, bytes.Length);
101             mb_str[bytes.Length] = 0;
102         }
103
104         public U8String (IntPtr ptr)
105         {
106             if (ptr == IntPtr.Zero)
107                 return;
108
109             int i = 0;
110             while (Marshal.ReadByte (ptr, i) != 0)
111                 i++;
112             i++;
113
114             mb_str = new byte[i];
115             Marshal.Copy (ptr, mb_str, 0, i);
116         }
117
118         public override string ToString ()
119         {
120             if (mb_str == null)
121                 return null;
122
123             byte[] bytes = new byte[mb_str.Length - 1];
124             Array.Copy (mb_str, bytes, bytes.Length);
125
126             return System.Text.Encoding.UTF8.GetString (bytes);
127         }
128     };
129
130
131     /**
132      * LibVLC native exception structure
133      */
134     [StructLayout (LayoutKind.Sequential)]
135     internal sealed struct NativeException
136     {
137         public int code;
138         public IntPtr message;
139
140         public string Message
141         {
142             get
143             {
144                 return new U8String (message).ToString ();
145             }
146         }
147
148         [DllImport ("libvlc-control.dll")]
149         static extern void mediacontrol_exception_init (ref NativeException e);
150         [DllImport ("libvlc-control.dll")]
151         static extern void mediacontrol_exception_cleanup (ref NativeException e);
152
153         public static NativeException Prepare ()
154         {
155             NativeException e = new NativeException ();
156             mediacontrol_exception_init (ref e);
157             return e;
158         }
159
160         public void Consume ()
161         {
162             try
163             {
164                 Exception e;
165                 string m = Message;
166
167                 switch (this.code)
168                 {
169                     case 0:
170                         e = null;
171                         break;
172                     case 1:
173                         e = new PositionKeyNotSupportedException (m);
174                         break;
175                     case 2:
176                         e = new PositionOriginNotSupportedException (m);
177                         break;
178                     case 3:
179                         e = new InvalidPositionException (m);
180                         break;
181                     case 4:
182                         e = new PlaylistException (m);
183                         break;
184                     case 5:
185                         e = new InternalException (m);
186                         break;
187                     default:
188                         e = new MediaException (m);
189                         break;
190                 }
191                 if (e != null)
192                     throw e;
193             }
194             finally
195             {
196                 mediacontrol_exception_cleanup (ref this);
197             }
198         }
199     };
200 };