2 * Firebird ADO.NET Data provider for .NET and Mono
4 * The contents of this file are subject to the Initial
5 * Developer's Public License Version 1.0 (the "License");
6 * you may not use this file except in compliance with the
7 * License. You may obtain a copy of the License at
8 * http://www.firebirdsql.org/index.php?op=doc&id=idpl
10 * Software distributed under the License is distributed on
11 * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
12 * express or implied. See the License for the specific
13 * language governing rights and limitations under the License.
15 * Copyright (c) 2002, 2005 Carlos Guzman Alvarez
16 * All Rights Reserved.
22 using System.Net.Sockets;
24 using FirebirdSql.Data.Common;
26 namespace FirebirdSql.Data.Gds
28 internal sealed class GdsConnection
32 private Socket socket;
33 private NetworkStream networkStream;
34 private XdrStream send;
35 private XdrStream receive;
36 private int operation;
40 #region Internal Properties
42 internal XdrStream Receive
44 get { return this.receive; }
47 internal XdrStream Send
49 get { return this.send; }
56 public GdsConnection()
60 GC.SuppressFinalize(this);
67 public void Connect(string dataSource, int port)
69 this.Connect(dataSource, port, 8192, Charset.DefaultCharset);
72 public void Connect(string dataSource, int port, int packetSize, Charset charset)
76 IPAddress hostadd = Dns.Resolve(dataSource).AddressList[0];
77 IPEndPoint EPhost = new IPEndPoint(hostadd, port);
79 this.socket = new Socket(
80 AddressFamily.InterNetwork,
86 // Set Receive Buffer size.
87 this.socket.SetSocketOption(
88 SocketOptionLevel.Socket,
89 SocketOptionName.ReceiveBuffer,
92 // Set Send Buffer size.
93 this.socket.SetSocketOption(
94 SocketOptionLevel.Socket,
95 SocketOptionName.SendBuffer,
99 // Disables the Nagle algorithm for send coalescing.
100 this.socket.SetSocketOption(
101 SocketOptionLevel.Tcp,
102 SocketOptionName.NoDelay,
105 // Make the socket to connect to the Server
106 this.socket.Connect(EPhost);
107 this.networkStream = new NetworkStream(this.socket, true);
110 this.send = new XdrStream(this.networkStream, charset);
111 this.receive = new XdrStream(this.networkStream, charset);
113 this.send = new XdrStream(new BufferedStream(this.networkStream), charset);
114 this.receive = new XdrStream(new BufferedStream(this.networkStream), charset);
117 GC.SuppressFinalize(this.socket);
118 GC.SuppressFinalize(this.networkStream);
119 GC.SuppressFinalize(this.send);
120 GC.SuppressFinalize(this.receive);
122 catch (SocketException)
124 throw new IscException(IscCodes.isc_arg_gds, IscCodes.isc_network_error, dataSource);
128 public void Disconnect()
132 if (this.receive != null)
134 this.receive.Close();
136 if (this.send != null)
140 if (this.networkStream != null)
142 this.networkStream.Close();
144 if (this.socket != null)
152 this.networkStream = null;
162 #region Internal Methods
164 internal int ReadOperation()
166 int op = (this.operation >= 0) ? this.operation : this.NextOperation();
172 internal int NextOperation()
176 /* loop as long as we are receiving dummy packets, just
177 * throwing them away--note that if we are a server we won't
178 * be receiving them, but it is better to check for them at
179 * this level rather than try to catch them in all places where
180 * this routine is called
182 this.operation = this.receive.ReadInt32();
183 } while (this.operation == IscCodes.op_dummy);
185 return this.operation;
188 internal GdsResponse ReadGenericResponse()
192 if (this.ReadOperation() == IscCodes.op_response)
194 GdsResponse r = new GdsResponse(
195 this.receive.ReadInt32(),
196 this.receive.ReadInt64(),
197 this.receive.ReadBuffer());
199 r.Warning = this.ReadStatusVector();
210 throw new IscException(IscCodes.isc_net_read_err);
214 internal IscException ReadStatusVector()
216 IscException exception = null;
223 int arg = this.receive.ReadInt32();
227 case IscCodes.isc_arg_gds:
228 int er = this.receive.ReadInt32();
231 if (exception == null)
233 exception = new IscException();
235 exception.Errors.Add(arg, er);
239 case IscCodes.isc_arg_end:
240 if (exception != null && exception.Errors.Count != 0)
242 exception.BuildExceptionMessage();
247 case IscCodes.isc_arg_interpreted:
248 case IscCodes.isc_arg_string:
249 exception.Errors.Add(arg, this.receive.ReadString());
252 case IscCodes.isc_arg_number:
253 exception.Errors.Add(arg, this.receive.ReadInt32());
258 int e = this.receive.ReadInt32();
261 if (exception == null)
263 exception = new IscException();
265 exception.Errors.Add(arg, e);
274 throw new IscException(IscCodes.isc_arg_gds, IscCodes.isc_net_read_err);
277 if (exception != null && !exception.IsWarning)
285 internal void SetOperation(int operation)
287 this.operation = operation;