internal DataSetCompressedStream(DataSet ds)
        {
            this.dataSet = ds;
            FileStream      fs        = new FileStream(@"c:\DataFile.dat", FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();

            try
            {
                DataSet tmpDs = new DataSet();
                foreach (DataTable dt in ds.Tables)
                {
                    DataTable newTable = tmpDs.Tables.Add(dt.TableName);
                    foreach (DataColumn dc in dt.Columns)
                    {
                        newTable.Columns.Add(dc.ColumnName, dc.DataType);
                    }

                    foreach (DataRow r in dt.Rows)
                    {
                        newTable.ImportRow(r);
                    }
                }
                tmpDs.RemotingFormat = SerializationFormat.Binary;
                formatter.Serialize(fs, tmpDs);
            }
            catch (SerializationException ex)
            {
                Console.WriteLine("Failed to serialize. Reason: " + ex.Message);
                throw;
            }
            finally
            {
                fs.Close();
            }


            this.tableList = new List <DataTable>();
            foreach (DataTable table in ds.Tables)
            {
                tableList.Add(table);
            }

            this.innerMemoryStream = new MemoryStream();
            DBConverter.ToMemoryStreamNoHeader(this.innerMemoryStream, VERSION);
            DBConverter.ToMemoryStream(this.innerMemoryStream, this.dataSet.DataSetName);
            DBConverter.ToMemoryStreamNoHeader(this.innerMemoryStream, this.tableList.Count);
            this.innerMemoryStreamLength    = this.innerMemoryStream.Position;
            this.innerMemoryStream.Position = 0;

            this.tableMemoryStream = new MemoryStream();
        }
        //// The unsafe keyword allows pointers to be used within the following method:
        //static unsafe void ClearBytes(byte[] src, int srcIndex, long count)
        //{

        //    int srcLen = src.Length;

        //    // The following fixed statement pins the location of the src and dst objects
        //    // in memory so that they will not be moved by garbage collection.
        //    fixed(byte* pSrc = src)
        //    {
        //        byte* ps = pSrc;

        //        long countMod4 = count % 4;
        //        long countDiv4 = count / 4;
        //        // Loop over the count in blocks of 4 bytes, copying an integer (4 bytes) at a time:
        //        for(long i = 0; i < countDiv4; i++)
        //        {
        //            *((int*)ps) = 0;
        //            ps += 4;
        //        }

        //        // Complete the copy by moving any bytes that weren't moved in blocks of 4:
        //        for(long i = 0; i < countMod4; i++)
        //        {
        //            *ps = (byte)0;
        //            ps++;
        //        }
        //    }
        //}


        public long WriteTableToStream(long countHint)
        {
            long startPos = this.outputStream.Position;

            while (this.outputStream.Position - startPos < countHint)
            {
                this.rowIndex++;
                if (this.rowIndex >= this.rowList.Count)
                {
                    this.isComplete = true;
                    return(0);
                }
                DBConverter.BytesFromRow(rowList[rowIndex], this.table.Columns, this.colDbTypeAr, this.outputStream);
            }

            return(this.outputStream.Position - startPos);
        }
        public DataTableBinarySerializer(DataTable table, MemoryStream outputStream)
        {
            this.table       = table;
            this.colDbTypeAr = DBConverter.GetDataColumnTypeCodes(table);

            this.rowList = new List <DataRow>();
            foreach (DataRow r in table.Rows)
            {
                if (r.RowState == DataRowState.Deleted)
                {
                    continue;
                }

                rowList.Add(r);
            }
            this.outputStream = outputStream;
            DBConverter.ToMemoryStreamNoHeader(this.outputStream, VERSION);
            DBConverter.ToMemoryStream(this.outputStream, table.TableName);
            DBConverter.ToMemoryStreamNoHeader(this.outputStream, this.rowList.Count);
            this.innerMemoryStreamLength = this.outputStream.Position;
        }
        public static void BytesFromRow(DataRow row, DataColumnCollection columns, TypeCodeEx[] colDbTypeAr, MemoryStream memStream)
        {
            for (int i = 0; i < columns.Count; i++)
            {
                DataColumn dc      = columns[i];
                object     cellVal = row[dc];

                TypeCodeEx typeCodeEx = colDbTypeAr[i];

                if (cellVal == dc.DefaultValue)
                {
                    typeCodeEx = TypeCodeEx.Empty;
                }
                else if (cellVal == null ||
                         DBNull.Value.Equals(cellVal))
                {
                    typeCodeEx = TypeCodeEx.DBNull;
                }

                Byte[] cellBytes = null;

                switch (typeCodeEx)
                {
                case TypeCodeEx.Empty:
                case TypeCodeEx.Object:
                    memStream.WriteByte((byte)DataHeader.DefaultValue);
                    break;

                case TypeCodeEx.DBNull:
                    memStream.WriteByte((byte)DataHeader.DbNull);
                    break;

                case TypeCodeEx.Boolean:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((bool)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.Char:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((char)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.SByte:
                case TypeCodeEx.Byte:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    memStream.WriteByte((byte)cellVal);
                    break;

                case TypeCodeEx.Int16:
                case TypeCodeEx.UInt16:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((Int16)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.Int32:
                case TypeCodeEx.UInt32:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((Int32)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.Int64:
                case TypeCodeEx.UInt64:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((Int64)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.Single:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((float)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.Double:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes((double)cellVal);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.Decimal:
                {
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    int[] intAr = Decimal.GetBits((Decimal)cellVal);
                    foreach (int decPart in intAr)
                    {
                        cellBytes = BitConverter.GetBytes(decPart);
                        memStream.Write(cellBytes, 0, cellBytes.Length);
                    }
                }
                break;

                case TypeCodeEx.DateTime:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = BitConverter.GetBytes(((DateTime)cellVal).Ticks);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.String:
                {
                    DBConverter.ToMemoryStream(memStream, (string)cellVal);
                }
                break;

                case TypeCodeEx.Guid:
                    memStream.WriteByte((byte)DataHeader.FixedLenValue);
                    cellBytes = ((Guid)cellVal).ToByteArray();
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                    break;

                case TypeCodeEx.ByteAr:
                {
                    memStream.WriteByte((byte)DataHeader.VariableLenValue);
                    cellBytes = (byte[])cellVal;
                    Byte[] lengthBytes = BitConverter.GetBytes(cellBytes.Length);
                    memStream.Write(lengthBytes, 0, lengthBytes.Length);
                    memStream.Write(cellBytes, 0, cellBytes.Length);
                }
                break;
                }
            }            //foreach column
        }