-/*\r
- * Firebird ADO.NET Data provider for .NET and Mono \r
- * \r
- * The contents of this file are subject to the Initial \r
- * Developer's Public License Version 1.0 (the "License"); \r
- * you may not use this file except in compliance with the \r
- * License. You may obtain a copy of the License at \r
- * http://www.firebirdsql.org/index.php?op=doc&id=idpl\r
- *\r
- * Software distributed under the License is distributed on \r
- * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either \r
- * express or implied. See the License for the specific \r
- * language governing rights and limitations under the License.\r
- * \r
- * Copyright (c) 2002, 2005 Carlos Guzman Alvarez\r
- * All Rights Reserved.\r
- */\r
-\r
-using System;\r
-using System.Collections;\r
-using System.IO;\r
-using System.Net;\r
-using System.Text;\r
-using System.Globalization;\r
-\r
-using FirebirdSql.Data.Common;\r
-\r
-namespace FirebirdSql.Data.Gds\r
-{\r
- internal class XdrStream : Stream\r
- {\r
- #region Static Fields\r
-\r
- private static byte[] fill;\r
- private static byte[] pad;\r
-\r
- #endregion\r
-\r
- #region Static Properties\r
-\r
- internal static byte[] Fill\r
- {\r
- get\r
- {\r
- if (fill == null)\r
- {\r
- fill = new byte[32767];\r
- for (int i = 0; i < fill.Length; i++)\r
- {\r
- fill[i] = 32;\r
- }\r
- }\r
-\r
- return fill;\r
- }\r
- }\r
-\r
- private static byte[] Pad\r
- {\r
- get\r
- {\r
- if (pad == null)\r
- {\r
- pad = new byte[] { 0, 0, 0, 0 };\r
- }\r
-\r
- return pad;\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Fields\r
-\r
- private byte[] buffer;\r
- private Charset charset;\r
- private Stream innerStream;\r
-\r
- #endregion\r
-\r
- #region Stream Properties\r
-\r
- public override bool CanWrite\r
- {\r
- get { return this.innerStream.CanWrite; }\r
- }\r
-\r
- public override bool CanRead\r
- {\r
- get { return this.innerStream.CanRead; }\r
- }\r
-\r
- public override bool CanSeek\r
- {\r
- get { return this.innerStream.CanSeek; }\r
- }\r
-\r
- public override long Position\r
- {\r
- get { return this.innerStream.Position; }\r
- set { this.innerStream.Position = value; }\r
- }\r
-\r
- public override long Length\r
- {\r
- get { return this.innerStream.Length; }\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
-\r
- public XdrStream() : this(Charset.DefaultCharset)\r
- {\r
- }\r
-\r
- public XdrStream(Charset charset) : this(new MemoryStream(), charset)\r
- {\r
- }\r
-\r
- public XdrStream(byte[] buffer, Charset charset) : this(new MemoryStream(buffer), charset)\r
- {\r
- }\r
-\r
- public XdrStream(Stream innerStream, Charset charset) : base()\r
- {\r
- this.buffer = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };\r
- this.innerStream = innerStream;\r
- this.charset = charset;\r
- }\r
-\r
- #endregion\r
-\r
- #region Stream methods\r
-\r
- public override void Close()\r
- {\r
- if (this.innerStream != null)\r
- {\r
- this.innerStream.Close();\r
- }\r
-\r
- this.buffer = null;\r
- this.charset = null;\r
- this.innerStream = null;\r
- }\r
-\r
- public override void Flush()\r
- {\r
- this.CheckDisposed();\r
-\r
- this.innerStream.Flush();\r
- }\r
-\r
- public override void SetLength(long length)\r
- {\r
- this.CheckDisposed();\r
-\r
- this.innerStream.SetLength(length);\r
- }\r
-\r
- public override long Seek(long offset, System.IO.SeekOrigin loc)\r
- {\r
- this.CheckDisposed();\r
-\r
- return this.innerStream.Seek(offset, loc);\r
- }\r
-\r
- public override int Read(byte[] buffer, int offset, int count)\r
- {\r
- this.CheckDisposed();\r
-\r
- if (this.CanRead)\r
- {\r
- return this.innerStream.Read(buffer, offset, count);\r
- }\r
-\r
- throw new InvalidOperationException("Read operations are not allowed by this stream");\r
- }\r
-\r
- public override void WriteByte(byte value)\r
- {\r
- this.CheckDisposed();\r
-\r
- this.innerStream.WriteByte(value);\r
- }\r
-\r
- public override void Write(byte[] buffer, int offset, int count)\r
- {\r
- this.CheckDisposed();\r
-\r
- if (this.CanWrite)\r
- {\r
- this.innerStream.Write(buffer, offset, count);\r
- }\r
- else\r
- {\r
- throw new InvalidOperationException("Write operations are not allowed by this stream");\r
- }\r
- }\r
-\r
- public byte[] ToArray()\r
- {\r
- this.CheckDisposed();\r
-\r
- if (this.innerStream is MemoryStream)\r
- {\r
- return ((MemoryStream)this.innerStream).ToArray();\r
- }\r
-\r
- throw new InvalidOperationException();\r
- }\r
-\r
- #endregion\r
-\r
- #region Xdr Read Methods\r
-\r
- public byte[] ReadBytes(int count)\r
- {\r
- byte[] buffer = new byte[count];\r
- this.Read(buffer, 0, buffer.Length);\r
-\r
- return buffer;\r
- }\r
-\r
- public byte[] ReadOpaque(int length)\r
- {\r
- byte[] buffer = new byte[length];\r
- int readed = 0;\r
-\r
- if (length > 0)\r
- {\r
- while (readed < length)\r
- {\r
- readed += this.Read(buffer, readed, length - readed);\r
- }\r
-\r
- int padLength = ((4 - length) & 3);\r
- if (padLength > 0)\r
- {\r
- this.Read(Pad, 0, padLength);\r
- }\r
- }\r
-\r
- return buffer;\r
- }\r
-\r
- public byte[] ReadBuffer()\r
- {\r
- return this.ReadOpaque(this.ReadInt32());\r
- }\r
-\r
- public string ReadString()\r
- {\r
- return this.ReadString(this.charset);\r
- }\r
-\r
- public string ReadString(int length)\r
- {\r
- return this.ReadString(this.charset, length);\r
- }\r
-\r
- public string ReadString(Charset charset)\r
- {\r
- return this.ReadString(charset, this.ReadInt32());\r
- }\r
-\r
- public string ReadString(Charset charset, int length)\r
- {\r
- byte[] buffer = this.ReadOpaque(length);\r
-\r
- return charset.GetString(buffer, 0, buffer.Length);\r
- }\r
-\r
- public short ReadInt16()\r
- {\r
- return Convert.ToInt16(this.ReadInt32());\r
- }\r
-\r
- public int ReadInt32()\r
- {\r
- this.Read(buffer, 0, 4);\r
-\r
- return IPAddress.HostToNetworkOrder(BitConverter.ToInt32(buffer, 0));\r
- }\r
-\r
- public long ReadInt64()\r
- {\r
- this.Read(buffer, 0, 8);\r
-\r
- return IPAddress.HostToNetworkOrder(BitConverter.ToInt64(buffer, 0));\r
- }\r
-\r
- public Guid ReadGuid(int length)\r
- {\r
- return new Guid(this.ReadOpaque(length));\r
- }\r
-\r
- public float ReadSingle()\r
- {\r
- return BitConverter.ToSingle(BitConverter.GetBytes(this.ReadInt32()), 0);\r
- }\r
-\r
- public double ReadDouble()\r
- {\r
- return BitConverter.ToDouble(BitConverter.GetBytes(this.ReadInt64()), 0);\r
- }\r
-\r
- public DateTime ReadDateTime()\r
- {\r
- DateTime date = this.ReadDate();\r
- DateTime time = this.ReadTime();\r
-\r
- return new System.DateTime(\r
- date.Year, date.Month, date.Day,\r
- time.Hour, time.Minute, time.Second, time.Millisecond);\r
- }\r
-\r
- public DateTime ReadDate()\r
- {\r
- return TypeDecoder.DecodeDate(this.ReadInt32());\r
- }\r
-\r
- public DateTime ReadTime()\r
- {\r
- return TypeDecoder.DecodeTime(this.ReadInt32());\r
- }\r
-\r
- public decimal ReadDecimal(int type, int scale)\r
- {\r
- decimal value = 0;\r
-\r
- switch (type & ~1)\r
- {\r
- case IscCodes.SQL_SHORT:\r
- value = TypeDecoder.DecodeDecimal(this.ReadInt16(), scale, type);\r
- break;\r
-\r
- case IscCodes.SQL_LONG:\r
- value = TypeDecoder.DecodeDecimal(this.ReadInt32(), scale, type);\r
- break;\r
-\r
- case IscCodes.SQL_QUAD:\r
- case IscCodes.SQL_INT64:\r
- value = TypeDecoder.DecodeDecimal(this.ReadInt64(), scale, type);\r
- break;\r
-\r
- case IscCodes.SQL_DOUBLE:\r
- case IscCodes.SQL_D_FLOAT:\r
- value = Convert.ToDecimal(this.ReadDouble());\r
- break;\r
- }\r
-\r
- return value;\r
- }\r
-\r
- public object ReadValue(DbField field)\r
- {\r
- object fieldValue = null;\r
- Charset innerCharset = (this.charset.Name != "NONE") ? this.charset : field.Charset;\r
-\r
- switch (field.DbDataType)\r
- {\r
- case DbDataType.Char:\r
- {\r
- string s = this.ReadString(innerCharset, field.Length);\r
-\r
- if ((field.Length % field.Charset.BytesPerCharacter) == 0 &&\r
- s.Length > field.CharCount)\r
- {\r
- fieldValue = s.Substring(0, field.CharCount);\r
- }\r
- else\r
- {\r
- fieldValue = s;\r
- }\r
- }\r
- break;\r
-\r
- case DbDataType.VarChar:\r
- fieldValue = this.ReadString(innerCharset).TrimEnd();\r
- break;\r
-\r
- case DbDataType.SmallInt:\r
- fieldValue = this.ReadInt16();\r
- break;\r
-\r
- case DbDataType.Integer:\r
- fieldValue = this.ReadInt32();\r
- break;\r
-\r
- case DbDataType.Array:\r
- case DbDataType.Binary:\r
- case DbDataType.Text:\r
- case DbDataType.BigInt:\r
- fieldValue = this.ReadInt64();\r
- break;\r
-\r
- case DbDataType.Decimal:\r
- case DbDataType.Numeric:\r
- fieldValue = this.ReadDecimal(\r
- field.DataType,\r
- field.NumericScale);\r
- break;\r
-\r
- case DbDataType.Float:\r
- fieldValue = this.ReadSingle();\r
- break;\r
-\r
- case DbDataType.Guid:\r
- fieldValue = this.ReadGuid(field.Length);\r
- break;\r
-\r
- case DbDataType.Double:\r
- fieldValue = this.ReadDouble();\r
- break;\r
-\r
- case DbDataType.Date:\r
- fieldValue = this.ReadDate();\r
- break;\r
-\r
- case DbDataType.Time:\r
- fieldValue = this.ReadTime();\r
- break;\r
-\r
- case DbDataType.TimeStamp:\r
- fieldValue = this.ReadDateTime();\r
- break;\r
- }\r
-\r
- int sqlInd = this.ReadInt32();\r
-\r
- if (sqlInd == 0)\r
- {\r
- return fieldValue;\r
- }\r
- else if (sqlInd == -1)\r
- {\r
- return null;\r
- }\r
- else\r
- {\r
- throw new IscException("invalid sqlind value: " + sqlInd);\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Xdr Write Methods\r
-\r
- public void WriteOpaque(byte[] buffer)\r
- {\r
- this.WriteOpaque(buffer, buffer.Length);\r
- }\r
-\r
- public void WriteOpaque(byte[] buffer, int length)\r
- {\r
- if (buffer != null && length > 0)\r
- {\r
- this.Write(buffer, 0, buffer.Length);\r
- this.Write(Fill, 0, length - buffer.Length);\r
- this.Write(Pad, 0, ((4 - length) & 3));\r
- }\r
- }\r
-\r
- public void WriteBuffer(byte[] buffer)\r
- {\r
- this.WriteBuffer(buffer, buffer == null ? 0 : buffer.Length);\r
- }\r
-\r
- public void WriteBuffer(byte[] buffer, int length)\r
- {\r
- this.Write(length);\r
- if (buffer != null && length > 0)\r
- {\r
- this.Write(buffer, 0, length);\r
- this.Write(Pad, 0, ((4 - length) & 3));\r
- }\r
- }\r
-\r
- public void WriteBlobBuffer(byte[] buffer)\r
- {\r
- int length = buffer.Length; // 2 for short for buffer length\r
-\r
- if (length > short.MaxValue)\r
- {\r
- throw (new IOException()); //Need a value???\r
- }\r
-\r
- this.Write(length + 2);\r
- this.Write(length + 2); //bizarre but true! three copies of the length\r
- this.WriteByte((byte)((length >> 0) & 0xff));\r
- this.WriteByte((byte)((length >> 8) & 0xff));\r
- this.Write(buffer, 0, length);\r
-\r
- this.Write(Pad, 0, ((4 - length + 2) & 3));\r
- }\r
-\r
- public void WriteTyped(int type, byte[] buffer)\r
- {\r
- int length;\r
-\r
- if (buffer == null)\r
- {\r
- this.Write(1);\r
- this.WriteByte((byte)type);\r
- length = 1;\r
- }\r
- else\r
- {\r
- length = buffer.Length + 1;\r
- this.Write(length);\r
- this.WriteByte((byte)type);\r
- this.Write(buffer, 0, buffer.Length);\r
- }\r
- this.Write(Pad, 0, ((4 - length) & 3));\r
- }\r
-\r
- public void Write(string value)\r
- {\r
- byte[] buffer = this.charset.GetBytes(value);\r
-\r
- this.WriteBuffer(buffer, buffer.Length);\r
- }\r
-\r
- public void Write(short value)\r
- {\r
- this.Write((int)value);\r
- }\r
-\r
- public void Write(int value)\r
- {\r
- this.Write(BitConverter.GetBytes(IPAddress.NetworkToHostOrder(value)), 0, 4);\r
- }\r
-\r
- public void Write(long value)\r
- {\r
- this.Write(BitConverter.GetBytes(IPAddress.NetworkToHostOrder(value)), 0, 8);\r
- }\r
-\r
- public void Write(float value)\r
- {\r
- byte[] buffer = BitConverter.GetBytes(value);\r
-\r
- this.Write(BitConverter.ToInt32(buffer, 0));\r
- }\r
-\r
- public void Write(double value)\r
- {\r
- byte[] buffer = BitConverter.GetBytes(value);\r
-\r
- this.Write(BitConverter.ToInt64(buffer, 0));\r
- }\r
-\r
- public void Write(decimal value, int type, int scale)\r
- {\r
- object numeric = TypeEncoder.EncodeDecimal(value, scale, type);\r
-\r
- switch (type & ~1)\r
- {\r
- case IscCodes.SQL_SHORT:\r
- this.Write((short)numeric);\r
- break;\r
-\r
- case IscCodes.SQL_LONG:\r
- this.Write((int)numeric);\r
- break;\r
-\r
- case IscCodes.SQL_QUAD:\r
- case IscCodes.SQL_INT64:\r
- this.Write((long)numeric);\r
- break;\r
-\r
- case IscCodes.SQL_DOUBLE:\r
- case IscCodes.SQL_D_FLOAT:\r
- this.Write((double)value);\r
- break;\r
- }\r
- }\r
-\r
- public void Write(DateTime value)\r
- {\r
- this.WriteDate(value);\r
- this.WriteTime(value);\r
- }\r
-\r
- public void WriteDate(DateTime value)\r
- {\r
- this.Write(TypeEncoder.EncodeDate(Convert.ToDateTime(value)));\r
- }\r
-\r
- public void WriteTime(DateTime value)\r
- {\r
- this.Write(TypeEncoder.EncodeTime(Convert.ToDateTime(value)));\r
- }\r
-\r
- public void Write(Descriptor descriptor)\r
- {\r
- for (int i = 0; i < descriptor.Count; i++)\r
- {\r
- this.Write(descriptor[i]);\r
- }\r
- }\r
-\r
- public void Write(DbField param)\r
- {\r
- Charset innerCharset = (this.charset.Name != "NONE") ? this.charset : param.Charset;\r
-\r
- param.FixNull();\r
-\r
- try\r
- {\r
- switch (param.DbDataType)\r
- {\r
- case DbDataType.Char:\r
- {\r
- string svalue = param.DbValue.GetString();\r
-\r
- if ((param.Length % param.Charset.BytesPerCharacter) == 0 &&\r
- svalue.Length > param.CharCount)\r
- {\r
- throw new IscException(335544321);\r
- }\r
-\r
- this.WriteOpaque(innerCharset.GetBytes(svalue), param.Length);\r
- }\r
- break;\r
-\r
- case DbDataType.VarChar:\r
- {\r
- string svalue = param.DbValue.GetString().TrimEnd();\r
-\r
- if ((param.Length % param.Charset.BytesPerCharacter) == 0 &&\r
- svalue.Length > param.CharCount)\r
- {\r
- throw new IscException(335544321);\r
- }\r
-\r
- byte[] data = innerCharset.GetBytes(svalue);\r
-\r
- this.WriteBuffer(data, data.Length);\r
- }\r
- break;\r
-\r
- case DbDataType.SmallInt:\r
- this.Write(param.DbValue.GetInt16());\r
- break;\r
-\r
- case DbDataType.Integer:\r
- this.Write(param.DbValue.GetInt32());\r
- break;\r
-\r
- case DbDataType.BigInt:\r
- case DbDataType.Array:\r
- case DbDataType.Binary:\r
- case DbDataType.Text:\r
- this.Write(param.DbValue.GetInt64());\r
- break;\r
-\r
- case DbDataType.Decimal:\r
- case DbDataType.Numeric:\r
- this.Write(\r
- param.DbValue.GetDecimal(),\r
- param.DataType,\r
- param.NumericScale);\r
- break;\r
-\r
- case DbDataType.Float:\r
- this.Write(param.DbValue.GetFloat());\r
- break;\r
-\r
- case DbDataType.Guid:\r
- this.WriteOpaque(param.DbValue.GetGuid().ToByteArray());\r
- break;\r
-\r
- case DbDataType.Double:\r
- this.Write(param.DbValue.GetDouble());\r
- break;\r
-\r
- case DbDataType.Date:\r
- this.Write(param.DbValue.EncodeDate());\r
- break;\r
-\r
- case DbDataType.Time:\r
- this.Write(param.DbValue.EncodeTime());\r
- break;\r
-\r
- case DbDataType.TimeStamp:\r
- this.Write(param.DbValue.EncodeDate());\r
- this.Write(param.DbValue.EncodeTime());\r
- break;\r
-\r
- default:\r
- throw new IscException("Unknown sql data type: " + param.DataType);\r
- }\r
-\r
- this.Write(param.NullFlag);\r
- }\r
- catch (IOException)\r
- {\r
- throw new IscException(IscCodes.isc_net_write_err);\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Private Methods\r
-\r
- private void CheckDisposed()\r
- {\r
- if (this.innerStream == null)\r
- {\r
- throw new ObjectDisposedException("The XdrStream is closed.");\r
- }\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+/*
+ * Firebird ADO.NET Data provider for .NET and Mono
+ *
+ * The contents of this file are subject to the Initial
+ * Developer's Public License Version 1.0 (the "License");
+ * you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ * http://www.firebirdsql.org/index.php?op=doc&id=idpl
+ *
+ * Software distributed under the License is distributed on
+ * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * Copyright (c) 2002, 2005 Carlos Guzman Alvarez
+ * All Rights Reserved.
+ */
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Globalization;
+
+using FirebirdSql.Data.Common;
+
+namespace FirebirdSql.Data.Gds
+{
+ internal class XdrStream : Stream
+ {
+ #region Static Fields
+
+ private static byte[] fill;
+ private static byte[] pad;
+
+ #endregion
+
+ #region Static Properties
+
+ internal static byte[] Fill
+ {
+ get
+ {
+ if (fill == null)
+ {
+ fill = new byte[32767];
+ for (int i = 0; i < fill.Length; i++)
+ {
+ fill[i] = 32;
+ }
+ }
+
+ return fill;
+ }
+ }
+
+ private static byte[] Pad
+ {
+ get
+ {
+ if (pad == null)
+ {
+ pad = new byte[] { 0, 0, 0, 0 };
+ }
+
+ return pad;
+ }
+ }
+
+ #endregion
+
+ #region Fields
+
+ private byte[] buffer;
+ private Charset charset;
+ private Stream innerStream;
+
+ #endregion
+
+ #region Stream Properties
+
+ public override bool CanWrite
+ {
+ get { return this.innerStream.CanWrite; }
+ }
+
+ public override bool CanRead
+ {
+ get { return this.innerStream.CanRead; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return this.innerStream.CanSeek; }
+ }
+
+ public override long Position
+ {
+ get { return this.innerStream.Position; }
+ set { this.innerStream.Position = value; }
+ }
+
+ public override long Length
+ {
+ get { return this.innerStream.Length; }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ public XdrStream() : this(Charset.DefaultCharset)
+ {
+ }
+
+ public XdrStream(Charset charset) : this(new MemoryStream(), charset)
+ {
+ }
+
+ public XdrStream(byte[] buffer, Charset charset) : this(new MemoryStream(buffer), charset)
+ {
+ }
+
+ public XdrStream(Stream innerStream, Charset charset) : base()
+ {
+ this.buffer = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
+ this.innerStream = innerStream;
+ this.charset = charset;
+ }
+
+ #endregion
+
+ #region Stream methods
+
+ public override void Close()
+ {
+ if (this.innerStream != null)
+ {
+ this.innerStream.Close();
+ }
+
+ this.buffer = null;
+ this.charset = null;
+ this.innerStream = null;
+ }
+
+ public override void Flush()
+ {
+ this.CheckDisposed();
+
+ this.innerStream.Flush();
+ }
+
+ public override void SetLength(long length)
+ {
+ this.CheckDisposed();
+
+ this.innerStream.SetLength(length);
+ }
+
+ public override long Seek(long offset, System.IO.SeekOrigin loc)
+ {
+ this.CheckDisposed();
+
+ return this.innerStream.Seek(offset, loc);
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ this.CheckDisposed();
+
+ if (this.CanRead)
+ {
+ return this.innerStream.Read(buffer, offset, count);
+ }
+
+ throw new InvalidOperationException("Read operations are not allowed by this stream");
+ }
+
+ public override void WriteByte(byte value)
+ {
+ this.CheckDisposed();
+
+ this.innerStream.WriteByte(value);
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ this.CheckDisposed();
+
+ if (this.CanWrite)
+ {
+ this.innerStream.Write(buffer, offset, count);
+ }
+ else
+ {
+ throw new InvalidOperationException("Write operations are not allowed by this stream");
+ }
+ }
+
+ public byte[] ToArray()
+ {
+ this.CheckDisposed();
+
+ if (this.innerStream is MemoryStream)
+ {
+ return ((MemoryStream)this.innerStream).ToArray();
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ #endregion
+
+ #region Xdr Read Methods
+
+ public byte[] ReadBytes(int count)
+ {
+ byte[] buffer = new byte[count];
+ this.Read(buffer, 0, buffer.Length);
+
+ return buffer;
+ }
+
+ public byte[] ReadOpaque(int length)
+ {
+ byte[] buffer = new byte[length];
+ int readed = 0;
+
+ if (length > 0)
+ {
+ while (readed < length)
+ {
+ readed += this.Read(buffer, readed, length - readed);
+ }
+
+ int padLength = ((4 - length) & 3);
+ if (padLength > 0)
+ {
+ this.Read(Pad, 0, padLength);
+ }
+ }
+
+ return buffer;
+ }
+
+ public byte[] ReadBuffer()
+ {
+ return this.ReadOpaque(this.ReadInt32());
+ }
+
+ public string ReadString()
+ {
+ return this.ReadString(this.charset);
+ }
+
+ public string ReadString(int length)
+ {
+ return this.ReadString(this.charset, length);
+ }
+
+ public string ReadString(Charset charset)
+ {
+ return this.ReadString(charset, this.ReadInt32());
+ }
+
+ public string ReadString(Charset charset, int length)
+ {
+ byte[] buffer = this.ReadOpaque(length);
+
+ return charset.GetString(buffer, 0, buffer.Length);
+ }
+
+ public short ReadInt16()
+ {
+ return Convert.ToInt16(this.ReadInt32());
+ }
+
+ public int ReadInt32()
+ {
+ this.Read(buffer, 0, 4);
+
+ return IPAddress.HostToNetworkOrder(BitConverter.ToInt32(buffer, 0));
+ }
+
+ public long ReadInt64()
+ {
+ this.Read(buffer, 0, 8);
+
+ return IPAddress.HostToNetworkOrder(BitConverter.ToInt64(buffer, 0));
+ }
+
+ public Guid ReadGuid(int length)
+ {
+ return new Guid(this.ReadOpaque(length));
+ }
+
+ public float ReadSingle()
+ {
+ return BitConverter.ToSingle(BitConverter.GetBytes(this.ReadInt32()), 0);
+ }
+
+ public double ReadDouble()
+ {
+ return BitConverter.ToDouble(BitConverter.GetBytes(this.ReadInt64()), 0);
+ }
+
+ public DateTime ReadDateTime()
+ {
+ DateTime date = this.ReadDate();
+ DateTime time = this.ReadTime();
+
+ return new System.DateTime(
+ date.Year, date.Month, date.Day,
+ time.Hour, time.Minute, time.Second, time.Millisecond);
+ }
+
+ public DateTime ReadDate()
+ {
+ return TypeDecoder.DecodeDate(this.ReadInt32());
+ }
+
+ public DateTime ReadTime()
+ {
+ return TypeDecoder.DecodeTime(this.ReadInt32());
+ }
+
+ public decimal ReadDecimal(int type, int scale)
+ {
+ decimal value = 0;
+
+ switch (type & ~1)
+ {
+ case IscCodes.SQL_SHORT:
+ value = TypeDecoder.DecodeDecimal(this.ReadInt16(), scale, type);
+ break;
+
+ case IscCodes.SQL_LONG:
+ value = TypeDecoder.DecodeDecimal(this.ReadInt32(), scale, type);
+ break;
+
+ case IscCodes.SQL_QUAD:
+ case IscCodes.SQL_INT64:
+ value = TypeDecoder.DecodeDecimal(this.ReadInt64(), scale, type);
+ break;
+
+ case IscCodes.SQL_DOUBLE:
+ case IscCodes.SQL_D_FLOAT:
+ value = Convert.ToDecimal(this.ReadDouble());
+ break;
+ }
+
+ return value;
+ }
+
+ public object ReadValue(DbField field)
+ {
+ object fieldValue = null;
+ Charset innerCharset = (this.charset.Name != "NONE") ? this.charset : field.Charset;
+
+ switch (field.DbDataType)
+ {
+ case DbDataType.Char:
+ {
+ string s = this.ReadString(innerCharset, field.Length);
+
+ if ((field.Length % field.Charset.BytesPerCharacter) == 0 &&
+ s.Length > field.CharCount)
+ {
+ fieldValue = s.Substring(0, field.CharCount);
+ }
+ else
+ {
+ fieldValue = s;
+ }
+ }
+ break;
+
+ case DbDataType.VarChar:
+ fieldValue = this.ReadString(innerCharset).TrimEnd();
+ break;
+
+ case DbDataType.SmallInt:
+ fieldValue = this.ReadInt16();
+ break;
+
+ case DbDataType.Integer:
+ fieldValue = this.ReadInt32();
+ break;
+
+ case DbDataType.Array:
+ case DbDataType.Binary:
+ case DbDataType.Text:
+ case DbDataType.BigInt:
+ fieldValue = this.ReadInt64();
+ break;
+
+ case DbDataType.Decimal:
+ case DbDataType.Numeric:
+ fieldValue = this.ReadDecimal(
+ field.DataType,
+ field.NumericScale);
+ break;
+
+ case DbDataType.Float:
+ fieldValue = this.ReadSingle();
+ break;
+
+ case DbDataType.Guid:
+ fieldValue = this.ReadGuid(field.Length);
+ break;
+
+ case DbDataType.Double:
+ fieldValue = this.ReadDouble();
+ break;
+
+ case DbDataType.Date:
+ fieldValue = this.ReadDate();
+ break;
+
+ case DbDataType.Time:
+ fieldValue = this.ReadTime();
+ break;
+
+ case DbDataType.TimeStamp:
+ fieldValue = this.ReadDateTime();
+ break;
+ }
+
+ int sqlInd = this.ReadInt32();
+
+ if (sqlInd == 0)
+ {
+ return fieldValue;
+ }
+ else if (sqlInd == -1)
+ {
+ return null;
+ }
+ else
+ {
+ throw new IscException("invalid sqlind value: " + sqlInd);
+ }
+ }
+
+ #endregion
+
+ #region Xdr Write Methods
+
+ public void WriteOpaque(byte[] buffer)
+ {
+ this.WriteOpaque(buffer, buffer.Length);
+ }
+
+ public void WriteOpaque(byte[] buffer, int length)
+ {
+ if (buffer != null && length > 0)
+ {
+ this.Write(buffer, 0, buffer.Length);
+ this.Write(Fill, 0, length - buffer.Length);
+ this.Write(Pad, 0, ((4 - length) & 3));
+ }
+ }
+
+ public void WriteBuffer(byte[] buffer)
+ {
+ this.WriteBuffer(buffer, buffer == null ? 0 : buffer.Length);
+ }
+
+ public void WriteBuffer(byte[] buffer, int length)
+ {
+ this.Write(length);
+ if (buffer != null && length > 0)
+ {
+ this.Write(buffer, 0, length);
+ this.Write(Pad, 0, ((4 - length) & 3));
+ }
+ }
+
+ public void WriteBlobBuffer(byte[] buffer)
+ {
+ int length = buffer.Length; // 2 for short for buffer length
+
+ if (length > short.MaxValue)
+ {
+ throw (new IOException()); //Need a value???
+ }
+
+ this.Write(length + 2);
+ this.Write(length + 2); //bizarre but true! three copies of the length
+ this.WriteByte((byte)((length >> 0) & 0xff));
+ this.WriteByte((byte)((length >> 8) & 0xff));
+ this.Write(buffer, 0, length);
+
+ this.Write(Pad, 0, ((4 - length + 2) & 3));
+ }
+
+ public void WriteTyped(int type, byte[] buffer)
+ {
+ int length;
+
+ if (buffer == null)
+ {
+ this.Write(1);
+ this.WriteByte((byte)type);
+ length = 1;
+ }
+ else
+ {
+ length = buffer.Length + 1;
+ this.Write(length);
+ this.WriteByte((byte)type);
+ this.Write(buffer, 0, buffer.Length);
+ }
+ this.Write(Pad, 0, ((4 - length) & 3));
+ }
+
+ public void Write(string value)
+ {
+ byte[] buffer = this.charset.GetBytes(value);
+
+ this.WriteBuffer(buffer, buffer.Length);
+ }
+
+ public void Write(short value)
+ {
+ this.Write((int)value);
+ }
+
+ public void Write(int value)
+ {
+ this.Write(BitConverter.GetBytes(IPAddress.NetworkToHostOrder(value)), 0, 4);
+ }
+
+ public void Write(long value)
+ {
+ this.Write(BitConverter.GetBytes(IPAddress.NetworkToHostOrder(value)), 0, 8);
+ }
+
+ public void Write(float value)
+ {
+ byte[] buffer = BitConverter.GetBytes(value);
+
+ this.Write(BitConverter.ToInt32(buffer, 0));
+ }
+
+ public void Write(double value)
+ {
+ byte[] buffer = BitConverter.GetBytes(value);
+
+ this.Write(BitConverter.ToInt64(buffer, 0));
+ }
+
+ public void Write(decimal value, int type, int scale)
+ {
+ object numeric = TypeEncoder.EncodeDecimal(value, scale, type);
+
+ switch (type & ~1)
+ {
+ case IscCodes.SQL_SHORT:
+ this.Write((short)numeric);
+ break;
+
+ case IscCodes.SQL_LONG:
+ this.Write((int)numeric);
+ break;
+
+ case IscCodes.SQL_QUAD:
+ case IscCodes.SQL_INT64:
+ this.Write((long)numeric);
+ break;
+
+ case IscCodes.SQL_DOUBLE:
+ case IscCodes.SQL_D_FLOAT:
+ this.Write((double)value);
+ break;
+ }
+ }
+
+ public void Write(DateTime value)
+ {
+ this.WriteDate(value);
+ this.WriteTime(value);
+ }
+
+ public void WriteDate(DateTime value)
+ {
+ this.Write(TypeEncoder.EncodeDate(Convert.ToDateTime(value)));
+ }
+
+ public void WriteTime(DateTime value)
+ {
+ this.Write(TypeEncoder.EncodeTime(Convert.ToDateTime(value)));
+ }
+
+ public void Write(Descriptor descriptor)
+ {
+ for (int i = 0; i < descriptor.Count; i++)
+ {
+ this.Write(descriptor[i]);
+ }
+ }
+
+ public void Write(DbField param)
+ {
+ Charset innerCharset = (this.charset.Name != "NONE") ? this.charset : param.Charset;
+
+ param.FixNull();
+
+ try
+ {
+ switch (param.DbDataType)
+ {
+ case DbDataType.Char:
+ {
+ string svalue = param.DbValue.GetString();
+
+ if ((param.Length % param.Charset.BytesPerCharacter) == 0 &&
+ svalue.Length > param.CharCount)
+ {
+ throw new IscException(335544321);
+ }
+
+ this.WriteOpaque(innerCharset.GetBytes(svalue), param.Length);
+ }
+ break;
+
+ case DbDataType.VarChar:
+ {
+ string svalue = param.DbValue.GetString().TrimEnd();
+
+ if ((param.Length % param.Charset.BytesPerCharacter) == 0 &&
+ svalue.Length > param.CharCount)
+ {
+ throw new IscException(335544321);
+ }
+
+ byte[] data = innerCharset.GetBytes(svalue);
+
+ this.WriteBuffer(data, data.Length);
+ }
+ break;
+
+ case DbDataType.SmallInt:
+ this.Write(param.DbValue.GetInt16());
+ break;
+
+ case DbDataType.Integer:
+ this.Write(param.DbValue.GetInt32());
+ break;
+
+ case DbDataType.BigInt:
+ case DbDataType.Array:
+ case DbDataType.Binary:
+ case DbDataType.Text:
+ this.Write(param.DbValue.GetInt64());
+ break;
+
+ case DbDataType.Decimal:
+ case DbDataType.Numeric:
+ this.Write(
+ param.DbValue.GetDecimal(),
+ param.DataType,
+ param.NumericScale);
+ break;
+
+ case DbDataType.Float:
+ this.Write(param.DbValue.GetFloat());
+ break;
+
+ case DbDataType.Guid:
+ this.WriteOpaque(param.DbValue.GetGuid().ToByteArray());
+ break;
+
+ case DbDataType.Double:
+ this.Write(param.DbValue.GetDouble());
+ break;
+
+ case DbDataType.Date:
+ this.Write(param.DbValue.EncodeDate());
+ break;
+
+ case DbDataType.Time:
+ this.Write(param.DbValue.EncodeTime());
+ break;
+
+ case DbDataType.TimeStamp:
+ this.Write(param.DbValue.EncodeDate());
+ this.Write(param.DbValue.EncodeTime());
+ break;
+
+ default:
+ throw new IscException("Unknown sql data type: " + param.DataType);
+ }
+
+ this.Write(param.NullFlag);
+ }
+ catch (IOException)
+ {
+ throw new IscException(IscCodes.isc_net_write_err);
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private void CheckDisposed()
+ {
+ if (this.innerStream == null)
+ {
+ throw new ObjectDisposedException("The XdrStream is closed.");
+ }
+ }
+
+ #endregion
+ }
+}