Allow schema files that are missing checksums on the !!SCHEMAMATIC line.
[versaplex.git] / wvdotnet / wvsockstream.cs
blob9a64f9f6dbeee35ccd476bd42c8763640681c6ad
1 /*
2 * Versaplex:
3 * Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
4 * See the included file named LICENSE for license information.
5 */
6 using System;
7 using System.Collections.Generic;
8 using System.Net;
9 using System.Net.Sockets;
10 using Mono.Unix;
11 using Wv;
13 namespace Wv
15 public class WvSockStream : WvStream
17 Socket _sock = null;
18 protected Socket sock {
19 get {
20 return _sock;
22 set {
23 _sock = value;
24 if (_sock != null)
25 _sock.Blocking = false;
29 public override bool ok {
30 get { return (sock != null) && base.ok; }
33 public WvSockStream(Socket sock)
35 this.sock = sock;
38 public override EndPoint localaddr {
39 get {
40 if (!ok)
41 return null;
42 return sock.LocalEndPoint;
46 public override EndPoint remoteaddr {
47 get {
48 if (!ok)
49 return null;
50 return sock.RemoteEndPoint;
54 public override int read(WvBytes b)
56 if (!ok)
57 return 0;
59 try
61 int ret = sock.Receive(b.bytes, b.start, b.len, 0);
62 if (ret <= 0) // EOF
64 nowrite();
65 noread();
66 return 0;
68 else
69 return ret;
71 catch (SocketException e)
73 if (e.ErrorCode == 10004) // EINTR is normal when non-blocking
74 return 0;
75 else if (e.ErrorCode == 10035) // EWOULDBLOCK too
76 return 0;
77 else
79 err = e;
80 // err = new Exception(wv.fmt("Error code {0}\n", e.ErrorCode));
82 return 0;
86 public override int write(WvBytes b)
88 if (!ok)
89 return 0;
91 try
93 int ret = sock.Send(b.bytes, b.start, b.len, 0);
94 if (ret < 0) // Unexpected error
96 err = new Exception(wv.fmt("Write error #{0}", ret));
97 return 0;
99 else
100 return ret;
102 catch (SocketException e)
104 if (e.ErrorCode == 10004) // EINTR is normal when non-blocking
105 return 0;
106 else if (e.ErrorCode == 10035) // EWOULDBLOCK too
107 return 0;
108 else
110 err = e;
111 // err = new Exception(wv.fmt("Error code {0}\n", e.ErrorCode));
113 return 0;
117 public override event Action onreadable {
118 add { base.onreadable += value;
119 if (ok) ev.onreadable(sock, do_readable); }
120 remove { base.onreadable -= value;
121 if (!can_onreadable) ev.onreadable(sock, null); }
124 public override event Action onwritable {
125 add { base.onwritable += value;
126 if (ok) ev.onwritable(sock, do_writable); }
127 remove { base.onwritable -= value;
128 if (!can_onwritable) ev.onwritable(sock, null); }
131 void tryshutdown(SocketShutdown sd)
135 sock.Shutdown(sd);
137 catch (SocketException)
139 // ignore
143 public override bool wait(int msec_timeout,
144 bool readable, bool writable)
146 foreach (int remain in wv.until(msec_timeout))
148 if (!ok)
149 return false;
150 if (!readable && !writable)
151 wv.sleep(remain);
152 else
154 var rlist = new List<Socket>();
155 var wlist = new List<Socket>();
156 if (readable)
157 rlist.Add(sock);
158 if (writable)
159 wlist.Add(sock);
160 Socket.Select(rlist, wlist, null, remain * 1000);
162 if (rlist.Count > 0 || wlist.Count > 0)
163 return true;
167 return false;
170 public override void noread()
172 base.noread();
173 if (sock != null)
174 tryshutdown(SocketShutdown.Receive);
175 ev.onreadable(sock, null);
178 public override void nowrite()
180 base.nowrite();
181 if (sock != null)
182 tryshutdown(SocketShutdown.Send);
183 ev.onwritable(sock, null);
186 public override void close()
188 base.close();
189 if (sock != null)
191 try {
192 ev.onreadable(sock, null);
193 ev.onwritable(sock, null);
194 tryshutdown(SocketShutdown.Both);
195 sock.Close();
196 ((IDisposable)sock).Dispose();
198 finally {
199 sock = null;
205 public class WvTcp : WvSockStream
207 public WvTcp(string remote, ushort port) : base(null)
209 // FIXME: do DNS lookups asynchronously?
212 IPHostEntry ipe = Dns.GetHostEntry(remote);
213 IPEndPoint ipep = new IPEndPoint(ipe.AddressList[0], port);
214 Socket sock = new Socket(AddressFamily.InterNetwork,
215 SocketType.Stream,
216 ProtocolType.Tcp);
217 sock.Connect(ipep);
218 this.sock = sock;
220 catch (Exception e)
222 err = e;
227 public class WvUnix : WvSockStream
229 public WvUnix(string path) : base(null)
231 EndPoint ep;
233 if (path.StartsWith("@"))
234 ep = new AbstractUnixEndPoint(path.Substring(1));
235 else
236 ep = new UnixEndPoint(path);
238 Socket sock = new Socket(AddressFamily.Unix,
239 SocketType.Stream, 0);
240 sock.Connect(ep);
241 this.sock = sock;