]> git.meshlink.io Git - catta/blob - avahi-sharp/HostNameResolver.cs
62f4149e0572063f079b1e4db5523a4e92690435
[catta] / avahi-sharp / HostNameResolver.cs
1 using System;
2 using System.Collections;
3 using System.Net;
4 using System.Runtime.InteropServices;
5 using Mono.Unix;
6
7 namespace Avahi
8 {
9
10     internal delegate void HostNameResolverCallback (IntPtr resolver, int iface, Protocol proto,
11                                                      ResolverEvent revent, IntPtr hostname, IntPtr address,
12                                                      IntPtr userdata);
13
14     public class HostNameResolver : IDisposable
15     {
16         private IntPtr handle;
17         private Client client;
18         private int iface;
19         private Protocol proto;
20         private string hostname;
21         private Protocol aproto;
22
23         private IPAddress currentAddress;
24         private string currentHost;
25
26         private ArrayList foundListeners = new ArrayList ();
27         private ArrayList timeoutListeners = new ArrayList ();
28         
29         [DllImport ("avahi-client")]
30         private static extern IntPtr avahi_host_name_resolver_new (IntPtr client, int iface, Protocol proto,
31                                                                    IntPtr hostname, Protocol aproto,
32                                                                    HostNameResolverCallback cb, IntPtr userdata);
33
34         [DllImport ("avahi-client")]
35         private static extern void avahi_host_name_resolver_free (IntPtr handle);
36
37         public event HostAddressHandler Found
38         {
39             add {
40                 foundListeners.Add (value);
41                 Start ();
42             }
43             remove {
44                 foundListeners.Remove (value);
45                 Stop (false);
46             }
47         }
48         
49         public event EventHandler Timeout
50         {
51             add {
52                 timeoutListeners.Add (value);
53                 Start ();
54             }
55             remove {
56                 timeoutListeners.Remove (value);
57                 Stop (false);
58             }
59         }
60
61         public IPAddress Address
62         {
63             get { return currentAddress; }
64         }
65
66         public string HostName
67         {
68             get { return currentHost; }
69         }
70
71         public HostNameResolver (Client client, string hostname) : this (client, -1, Protocol.Unspecified,
72                                                                          hostname, Protocol.Unspecified)
73         {
74         }
75
76         public HostNameResolver (Client client, int iface, Protocol proto, string hostname,
77                                  Protocol aproto)
78         {
79             this.client = client;
80             this.iface = iface;
81             this.proto = proto;
82             this.hostname = hostname;
83             this.aproto = aproto;
84         }
85
86         ~HostNameResolver ()
87         {
88             Dispose ();
89         }
90
91         public void Dispose ()
92         {
93             Stop (true);
94         }
95
96         private void Start ()
97         {
98             if (handle != IntPtr.Zero || (foundListeners.Count == 0 && timeoutListeners.Count == 0))
99                 return;
100
101             IntPtr hostPtr = Utility.StringToPtr (hostname);
102             handle = avahi_host_name_resolver_new (client.Handle, iface, proto, hostPtr, aproto,
103                                                    OnHostNameResolverCallback, IntPtr.Zero);
104             Utility.Free (hostPtr);
105         }
106
107         private void Stop (bool force)
108         {
109             if (handle != IntPtr.Zero && (force || (foundListeners.Count == 0 && timeoutListeners.Count == 0))) {
110                 avahi_host_name_resolver_free (handle);
111                 handle = IntPtr.Zero;
112             }
113         }
114
115         private void OnHostNameResolverCallback (IntPtr resolver, int iface, Protocol proto,
116                                                  ResolverEvent revent, IntPtr hostname, IntPtr address,
117                                                  IntPtr userdata)
118         {
119             if (revent == ResolverEvent.Found) {
120                 currentAddress = Utility.PtrToAddress (address);
121                 currentHost = Utility.PtrToString (hostname);
122
123                 foreach (HostAddressHandler handler in foundListeners)
124                     handler (this, currentHost, currentAddress);
125             } else {
126                 currentAddress = null;
127                 currentHost = null;
128                 
129                 foreach (EventHandler handler in timeoutListeners)
130                     handler (this, new EventArgs ());
131             }
132         }
133     }
134 }