New test.
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Gds / XdrStream.cs
index 06a76a089be99f9770984ca1c046b8969c6092f1..fed6b42ae5ed965064d3f522e6813d980aedfd41 100644 (file)
-/*\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
+       }
+}