]> git.meshlink.io Git - catta/blob - avahi-sharp/RecordBrowser.cs
* Add RecordBrowser.cs
[catta] / avahi-sharp / RecordBrowser.cs
1 /* $Id: ServiceBrowser.cs 635 2005-09-26 03:57:30Z snorp $ */
2
3 /***
4   This file is part of avahi.
5
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 using System;
23 using System.Net;
24 using System.Collections;
25 using System.Runtime.InteropServices;
26
27 namespace Avahi
28 {
29
30     public delegate void RecordInfoHandler (object o, RecordInfoArgs args);
31     
32     internal delegate void RecordBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent,
33                                                   IntPtr name, ushort clazz, ushort type, IntPtr rdata, int size,
34                                                   LookupResultFlags flags, IntPtr userdata);
35
36     public enum RecordClass {
37         In = 1
38     }
39
40     public enum RecordType {
41         A = 1,
42         Ns = 2,
43         Cname = 5,
44         Soa = 6,
45         Ptr = 12,
46         Hinfo = 13,
47         Mx = 15,
48         Txt = 16,
49         Aaa = 28,
50         Srv = 33
51     }
52     
53     public struct RecordInfo
54     {
55         public int NetworkInterface;
56         public Protocol Protocol;
57         public string Name;
58         public RecordClass Class;
59         public RecordType Type;
60         public byte[] Data;
61         public LookupResultFlags Flags;
62     }
63
64     public class RecordInfoArgs : EventArgs
65     {
66         private RecordInfo record;
67
68         public RecordInfo Record {
69             get { return record; }
70         }
71
72         public RecordInfoArgs (RecordInfo record)
73         {
74             this.record = record;
75         }
76     }
77
78     public class RecordBrowser : BrowserBase, IDisposable
79     {
80         private IntPtr handle;
81         private ArrayList infos = new ArrayList ();
82         private Client client;
83         private int iface;
84         private Protocol proto;
85         private string name;
86         private RecordClass clazz;
87         private RecordType type;
88         private LookupFlags flags;
89         private RecordBrowserCallback cb;
90
91         private ArrayList addListeners = new ArrayList ();
92         private ArrayList removeListeners = new ArrayList ();
93         
94         [DllImport ("avahi-client")]
95         private static extern IntPtr avahi_record_browser_new (IntPtr client, int iface, Protocol proto,
96                                                                IntPtr name, ushort clazz, ushort type,
97                                                                LookupFlags flags, RecordBrowserCallback cb,
98                                                                IntPtr userdata);
99
100
101         [DllImport ("avahi-client")]
102         private static extern void avahi_record_browser_free (IntPtr handle);
103
104         public event RecordInfoHandler RecordAdded
105         {
106             add {
107                 addListeners.Add (value);
108                 Start ();
109             }
110             remove {
111                 addListeners.Remove (value);
112                 Stop (false);
113             }
114         }
115         
116         public event RecordInfoHandler RecordRemoved
117         {
118             add {
119                 removeListeners.Add (value);
120                 Start ();
121             }
122             remove {
123                 removeListeners.Remove (value);
124                 Stop (false);
125             }
126         }
127
128         public RecordInfo[] Records
129         {
130             get { return (RecordInfo[]) infos.ToArray (typeof (RecordInfo)); }
131         }
132
133         public RecordBrowser (Client client, string name, RecordType type) :
134             this (client, -1, Protocol.Unspecified, name, RecordClass.In, type, LookupFlags.None)
135         {
136         }
137         
138         public RecordBrowser (Client client, int iface, Protocol proto, string name, RecordClass clazz,
139                               RecordType type, LookupFlags flags)
140         {
141             this.client = client;
142             this.iface = iface;
143             this.proto = proto;
144             this.name = name;
145             this.clazz = clazz;
146             this.type = type;
147             this.flags = flags;
148             cb = OnRecordBrowserCallback;
149         }
150
151         ~RecordBrowser ()
152         {
153             Dispose ();
154         }
155
156         public void Dispose ()
157         {
158             Stop (true);
159         }
160
161         private void Start ()
162         {
163             if (client.Handle == IntPtr.Zero || handle != IntPtr.Zero ||
164                 (addListeners.Count == 0 && removeListeners.Count == 0))
165                 return;
166
167             IntPtr namePtr = Utility.StringToPtr (name);
168
169             lock (client) {
170                 handle = avahi_record_browser_new (client.Handle, iface, proto, namePtr, (ushort) clazz, (ushort) type,
171                                                    flags, cb, IntPtr.Zero);
172             }
173
174             Utility.Free (namePtr);
175         }
176
177         private void Stop (bool force)
178         {
179             if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero &&
180                 (force || (addListeners.Count == 0 && removeListeners.Count == 0))) {
181                 
182                 lock (client) {
183                     avahi_record_browser_free (handle);
184                     handle = IntPtr.Zero;
185                 }
186             }
187         }
188
189         private void OnRecordBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent,
190                                               IntPtr name, ushort clazz, ushort type, IntPtr rdata, int size,
191                                               LookupResultFlags flags, IntPtr userdata)
192         {
193             RecordInfo info;
194             info.NetworkInterface = iface;
195             info.Protocol = proto;
196             info.Name = Utility.PtrToString (name);
197             info.Class = (RecordClass) clazz;
198             info.Type = (RecordType) type;
199             info.Flags = flags;
200             info.Data = new byte[size];
201
202             if (rdata != IntPtr.Zero) {
203                 Marshal.Copy (rdata, info.Data, 0, size);
204             }
205
206             switch (bevent) {
207             case BrowserEvent.Added:
208                 infos.Add (info);
209
210                 foreach (RecordInfoHandler handler in addListeners)
211                     handler (this, new RecordInfoArgs (info));
212
213                 break;
214             case BrowserEvent.Removed:
215                 infos.Remove (info);
216
217                 foreach (RecordInfoHandler handler in removeListeners)
218                     handler (this, new RecordInfoArgs (info));
219
220                 break;
221             default:
222                 EmitBrowserEvent (bevent);
223                 break;
224             }
225         }
226     }
227 }