SqlCachedBuffer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / Data / System / Data / SqlClient / SqlCachedBuffer.cs / 1 / SqlCachedBuffer.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.SqlClient {
 
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data; 
    using System.Data.Common;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.Text;
    using System.Xml; 
    using System.Data.SqlTypes;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Reflection; 

    // Caches the bytes returned from partial length prefixed datatypes, like XML 
    sealed internal class SqlCachedBuffer : System.Data.SqlTypes.INullable{ 

       ArrayList    _cachedBytes; 
 	const int _maxChunkSize = 2048;	// Arbitrary value for chunk size. Revisit this later for better perf

        // Reads off from the network buffer and caches bytes. Only reads one column value in the current row.
        internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj ) { 
            int cb = 0;
            ulong  plplength; 
            byte[] byteArr; 

            Debug.Assert(_cachedBytes == null, "Cache is already filled!"); 
            _cachedBytes = new ArrayList();

            // the very first length is already read.
            plplength = parser.PlpBytesLeft(stateObj);; 
            // For now we  only handle Plp data from the parser directly.
            Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data"); 
            do { 
                if (plplength == 0)
                    break; 
                do {
                    cb = (plplength > (ulong) _maxChunkSize) ?  _maxChunkSize : (int)plplength ;
                    byteArr = new byte[cb];
                    cb = stateObj.ReadPlpBytes(ref byteArr, 0, cb); 
                    Debug.Assert(cb == byteArr.Length);
                    if (_cachedBytes.Count == 0) { 
                        // Add the Byte order mark if needed if we read the first array 
                        AddByteOrderMark(byteArr);
                    } 
                    _cachedBytes.Add(byteArr);
                    plplength -= (ulong)cb;
                } while (plplength > 0);
                plplength = parser.PlpBytesLeft(stateObj); 
            } while (plplength > 0);
            Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0); 
        } 

 
        // Reads off from a reader and caches bytes. Only reads the first column of each row.
        internal SqlCachedBuffer(SqlDataReader dataRdr,  int columnOrdinal, long startPosition) {
            byte[] byteArr;
            long bytesRead; 
            int cbread;
 
            Debug.Assert(_cachedBytes == null, "Cache is already filled!"); 
            _cachedBytes = new ArrayList();
 
            bytesRead = startPosition;
            do {
                // Allocate buffer and read a new chunk
                byteArr = new byte[_maxChunkSize]; 
                cbread = (int)dataRdr.GetBytesInternal(columnOrdinal, bytesRead, byteArr, 0, _maxChunkSize);
                bytesRead += cbread; 
 
                if (_cachedBytes.Count == 0) {
                    // Add the Byte order mark if needed if we read the first array 
                    AddByteOrderMark(byteArr, cbread);
                }

                if (0 < cbread) { 
                    // Handle reading less than we requested
                    if (cbread < byteArr.Length) { 
                        byte[] newByteArr = new byte[cbread]; 
                        Buffer.BlockCopy(byteArr, 0, newByteArr, 0, cbread);
                        byteArr = newByteArr; 
                    }

                    // Add new buffer to the list
                    _cachedBytes.Add(byteArr); 
                }
            } 
            while (0 < cbread); 
        }
 
        private void AddByteOrderMark(byte[] byteArr ) {
            AddByteOrderMark(byteArr, byteArr.Length);
        }
 
        private void AddByteOrderMark(byte[] byteArr, int length ) {
            Debug.Assert(byteArr.Length >= length); 
 
            int bom = 0xfeff;
            // Need to find out if we should add byte order mark or not. 
            // We need to add this if we are getting ntext xml, not if we are getting binary xml
            // Binary Xml always begins with the bytes 0xDF and 0xFF
            // If we aren't getting these, then we are getting unicode xml
            if ((length >= 2 ) && (byteArr[0] == 0xDF) && (byteArr[1] == 0xFF)){ 
                bom = 0;
            } 
            if (bom != 0) { 
                byte[]  b = new byte[2];
                b[0] = (byte)bom; 
                bom >>= 8;
                b[1] = (byte)bom;
                Debug.Assert(_cachedBytes.Count == 0);
                _cachedBytes.Add(b); 
            }
            return; 
        } 

 
        private SqlCachedBuffer() {
            // For constructing Null
        }
 
        public  static readonly SqlCachedBuffer Null = new SqlCachedBuffer();
 
        internal ArrayList  CachedBytes { 
            get {
                return _cachedBytes; 
            }
        }

        override public string ToString() { 
            if (IsNull)
                throw new SqlNullValueException(); 
 
            if (_cachedBytes.Count == 0) {
                return String.Empty; 
            }
            SqlCachedStream fragment = new SqlCachedStream(this);
            SqlXml   sxml = new SqlXml((Stream)fragment);
            return sxml.Value; 
        }
 
        internal SqlString ToSqlString() { 
            if (IsNull)
                return SqlString.Null; 
            string str = ToString();
            return new SqlString(str);
        }
 
        internal SqlXml ToSqlXml() {
            SqlCachedStream fragment = new SqlCachedStream(this); 
            SqlXml  sx = new SqlXml((Stream)fragment); 
            return sx;
        } 

        internal XmlReader ToXmlReader() {
            SqlCachedStream fragment = new SqlCachedStream(this);
            //XmlTextReader xr = new XmlTextReader(fragment, XmlNodeType.Element, null); 
            XmlReaderSettings readerSettings = new XmlReaderSettings();
            readerSettings.ConformanceLevel = ConformanceLevel.Fragment; 
 
            // Call internal XmlReader.CreateSqlReader from System.Xml.
            // Signature: internal static XmlReader CreateSqlReader(Stream input, XmlReaderSettings settings, XmlParserContext inputContext); 
            MethodInfo createSqlReaderMethodInfo = typeof(System.Xml.XmlReader).GetMethod("CreateSqlReader", BindingFlags.Static | BindingFlags.NonPublic);
            object[] args = new object[3] { (Stream)fragment, readerSettings, null };
            XmlReader xr;
 
            new System.Security.Permissions.ReflectionPermission(System.Security.Permissions.ReflectionPermissionFlag.MemberAccess).Assert();
            try { 
                xr = (XmlReader)createSqlReaderMethodInfo.Invoke(null, args); 
            }
            finally { 
                System.Security.Permissions.ReflectionPermission.RevertAssert();
            }
            return xr;
        } 

        public bool IsNull { 
            get { 
                return (_cachedBytes == null) ? true : false ;
            } 
        }

    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.SqlClient {
 
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data; 
    using System.Data.Common;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.Text;
    using System.Xml; 
    using System.Data.SqlTypes;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Reflection; 

    // Caches the bytes returned from partial length prefixed datatypes, like XML 
    sealed internal class SqlCachedBuffer : System.Data.SqlTypes.INullable{ 

       ArrayList    _cachedBytes; 
 	const int _maxChunkSize = 2048;	// Arbitrary value for chunk size. Revisit this later for better perf

        // Reads off from the network buffer and caches bytes. Only reads one column value in the current row.
        internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj ) { 
            int cb = 0;
            ulong  plplength; 
            byte[] byteArr; 

            Debug.Assert(_cachedBytes == null, "Cache is already filled!"); 
            _cachedBytes = new ArrayList();

            // the very first length is already read.
            plplength = parser.PlpBytesLeft(stateObj);; 
            // For now we  only handle Plp data from the parser directly.
            Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data"); 
            do { 
                if (plplength == 0)
                    break; 
                do {
                    cb = (plplength > (ulong) _maxChunkSize) ?  _maxChunkSize : (int)plplength ;
                    byteArr = new byte[cb];
                    cb = stateObj.ReadPlpBytes(ref byteArr, 0, cb); 
                    Debug.Assert(cb == byteArr.Length);
                    if (_cachedBytes.Count == 0) { 
                        // Add the Byte order mark if needed if we read the first array 
                        AddByteOrderMark(byteArr);
                    } 
                    _cachedBytes.Add(byteArr);
                    plplength -= (ulong)cb;
                } while (plplength > 0);
                plplength = parser.PlpBytesLeft(stateObj); 
            } while (plplength > 0);
            Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0); 
        } 

 
        // Reads off from a reader and caches bytes. Only reads the first column of each row.
        internal SqlCachedBuffer(SqlDataReader dataRdr,  int columnOrdinal, long startPosition) {
            byte[] byteArr;
            long bytesRead; 
            int cbread;
 
            Debug.Assert(_cachedBytes == null, "Cache is already filled!"); 
            _cachedBytes = new ArrayList();
 
            bytesRead = startPosition;
            do {
                // Allocate buffer and read a new chunk
                byteArr = new byte[_maxChunkSize]; 
                cbread = (int)dataRdr.GetBytesInternal(columnOrdinal, bytesRead, byteArr, 0, _maxChunkSize);
                bytesRead += cbread; 
 
                if (_cachedBytes.Count == 0) {
                    // Add the Byte order mark if needed if we read the first array 
                    AddByteOrderMark(byteArr, cbread);
                }

                if (0 < cbread) { 
                    // Handle reading less than we requested
                    if (cbread < byteArr.Length) { 
                        byte[] newByteArr = new byte[cbread]; 
                        Buffer.BlockCopy(byteArr, 0, newByteArr, 0, cbread);
                        byteArr = newByteArr; 
                    }

                    // Add new buffer to the list
                    _cachedBytes.Add(byteArr); 
                }
            } 
            while (0 < cbread); 
        }
 
        private void AddByteOrderMark(byte[] byteArr ) {
            AddByteOrderMark(byteArr, byteArr.Length);
        }
 
        private void AddByteOrderMark(byte[] byteArr, int length ) {
            Debug.Assert(byteArr.Length >= length); 
 
            int bom = 0xfeff;
            // Need to find out if we should add byte order mark or not. 
            // We need to add this if we are getting ntext xml, not if we are getting binary xml
            // Binary Xml always begins with the bytes 0xDF and 0xFF
            // If we aren't getting these, then we are getting unicode xml
            if ((length >= 2 ) && (byteArr[0] == 0xDF) && (byteArr[1] == 0xFF)){ 
                bom = 0;
            } 
            if (bom != 0) { 
                byte[]  b = new byte[2];
                b[0] = (byte)bom; 
                bom >>= 8;
                b[1] = (byte)bom;
                Debug.Assert(_cachedBytes.Count == 0);
                _cachedBytes.Add(b); 
            }
            return; 
        } 

 
        private SqlCachedBuffer() {
            // For constructing Null
        }
 
        public  static readonly SqlCachedBuffer Null = new SqlCachedBuffer();
 
        internal ArrayList  CachedBytes { 
            get {
                return _cachedBytes; 
            }
        }

        override public string ToString() { 
            if (IsNull)
                throw new SqlNullValueException(); 
 
            if (_cachedBytes.Count == 0) {
                return String.Empty; 
            }
            SqlCachedStream fragment = new SqlCachedStream(this);
            SqlXml   sxml = new SqlXml((Stream)fragment);
            return sxml.Value; 
        }
 
        internal SqlString ToSqlString() { 
            if (IsNull)
                return SqlString.Null; 
            string str = ToString();
            return new SqlString(str);
        }
 
        internal SqlXml ToSqlXml() {
            SqlCachedStream fragment = new SqlCachedStream(this); 
            SqlXml  sx = new SqlXml((Stream)fragment); 
            return sx;
        } 

        internal XmlReader ToXmlReader() {
            SqlCachedStream fragment = new SqlCachedStream(this);
            //XmlTextReader xr = new XmlTextReader(fragment, XmlNodeType.Element, null); 
            XmlReaderSettings readerSettings = new XmlReaderSettings();
            readerSettings.ConformanceLevel = ConformanceLevel.Fragment; 
 
            // Call internal XmlReader.CreateSqlReader from System.Xml.
            // Signature: internal static XmlReader CreateSqlReader(Stream input, XmlReaderSettings settings, XmlParserContext inputContext); 
            MethodInfo createSqlReaderMethodInfo = typeof(System.Xml.XmlReader).GetMethod("CreateSqlReader", BindingFlags.Static | BindingFlags.NonPublic);
            object[] args = new object[3] { (Stream)fragment, readerSettings, null };
            XmlReader xr;
 
            new System.Security.Permissions.ReflectionPermission(System.Security.Permissions.ReflectionPermissionFlag.MemberAccess).Assert();
            try { 
                xr = (XmlReader)createSqlReaderMethodInfo.Invoke(null, args); 
            }
            finally { 
                System.Security.Permissions.ReflectionPermission.RevertAssert();
            }
            return xr;
        } 

        public bool IsNull { 
            get { 
                return (_cachedBytes == null) ? true : false ;
            } 
        }

    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK