]> git.meshlink.io Git - catta/blob - avahi-sharp/RecordBrowser.cs
f65f8ac17b0f89fa14f45bedf501cc811b5feefe
[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 using System.Text;
27
28 namespace Avahi
29 {
30
31     public delegate void RecordInfoHandler (object o, RecordInfoArgs args);
32     
33     internal delegate void RecordBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent,
34                                                   IntPtr name, ushort clazz, ushort type, IntPtr rdata, int size,
35                                                   LookupResultFlags flags, IntPtr userdata);
36
37     public enum RecordClass {
38         In = 1
39     }
40
41     public enum RecordType {
42         A = 1,
43         Ns = 2,
44         Cname = 5,
45         Soa = 6,
46         Ptr = 12,
47         Hinfo = 13,
48         Mx = 15,
49         Txt = 16,
50         Aaa = 28,
51         Srv = 33
52     }
53     
54     public struct RecordInfo
55     {
56         public int NetworkInterface;
57         public Protocol Protocol;
58         public string Name;
59         public RecordClass Class;
60         public RecordType Type;
61         public byte[] Data;
62         public LookupResultFlags Flags;
63     }
64
65     public class RecordInfoArgs : EventArgs
66     {
67         private RecordInfo record;
68
69         public RecordInfo Record {
70             get { return record; }
71         }
72
73         public RecordInfoArgs (RecordInfo record)
74         {
75             this.record = record;
76         }
77     }
78
79     public class RecordBrowser : BrowserBase, IDisposable
80     {
81         private IntPtr handle;
82         private ArrayList infos = new ArrayList ();
83         private Client client;
84         private int iface;
85         private Protocol proto;
86         private string name;
87         private RecordClass clazz;
88         private RecordType type;
89         private LookupFlags flags;
90         private RecordBrowserCallback cb;
91
92         private ArrayList addListeners = new ArrayList ();
93         private ArrayList removeListeners = new ArrayList ();
94         
95         [DllImport ("avahi-client")]
96         private static extern IntPtr avahi_record_browser_new (IntPtr client, int iface, Protocol proto,
97                                                                byte[] name, ushort clazz, ushort type,
98                                                                LookupFlags flags, RecordBrowserCallback cb,
99                                                                IntPtr userdata);
100
101
102         [DllImport ("avahi-client")]
103         private static extern void avahi_record_browser_free (IntPtr handle);
104
105         public event RecordInfoHandler RecordAdded
106         {
107             add {
108                 addListeners.Add (value);
109                 Start ();
110             }
111             remove {
112                 addListeners.Remove (value);
113                 Stop (false);
114             }
115         }
116         
117         public event RecordInfoHandler RecordRemoved
118         {
119             add {
120                 removeListeners.Add (value);
121                 Start ();
122             }
123             remove {
124                 removeListeners.Remove (value);
125                 Stop (false);
126             }
127         }
128
129         public RecordInfo[] Records
130         {
131             get { return (RecordInfo[]) infos.ToArray (typeof (RecordInfo)); }
132         }
133
134         public RecordBrowser (Client client, string name, RecordType type) :
135             this (client, -1, Protocol.Unspecified, name, RecordClass.In, type, LookupFlags.None)
136         {
137         }
138         
139         public RecordBrowser (Client client, int iface, Protocol proto, string name, RecordClass clazz,
140                               RecordType type, LookupFlags flags)
141         {
142             this.client = client;
143             this.iface = iface;
144             this.proto = proto;
145             this.name = name;
146             this.clazz = clazz;
147             this.type = type;
148             this.flags = flags;
149             cb = OnRecordBrowserCallback;
150         }
151
152         ~RecordBrowser ()
153         {
154             Dispose ();
155         }
156
157         public void Dispose ()
158         {
159             Stop (true);
160         }
161
162         private void Start ()
163         {
164             if (client.Handle == IntPtr.Zero || handle != IntPtr.Zero ||
165                 (addListeners.Count == 0 && removeListeners.Count == 0))
166                 return;
167
168             lock (client) {
169                 handle = avahi_record_browser_new (client.Handle, iface, proto, Utility.StringToBytes (name),
170                                                    (ushort) clazz, (ushort) type, flags, cb, IntPtr.Zero);
171
172                 if (handle == IntPtr.Zero)
173                     client.ThrowError ();
174             }
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 }