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 / SQLTypes / SQLChars.cs / 1 / SQLChars.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //junfang //[....] //[....] //----------------------------------------------------------------------------- //************************************************************************* // @File: SqlChars.cs // @Owner: junfang // // Created by: JunFang // // Description: Class SqlChars is used to represent a char/varchar/nchar/nvarchar // data from SQL Server. It contains a char array buffer, which can // be refilled. For example, in data access, user could use one instance // of SqlChars to bind to a binary column, and we will just keep copying // the data into the same instance, and avoid allocation per row. // // Notes: // // History: // // @Version: Yukon // 120214 JXF 09/23/02 SqlBytes/SqlChars class indexer // 112296 AZA 07/06/02 Seal SqlAccess classes. // 107151 AZA 04/18/02 Track byte array buffer as well as SqlBytes in // sqlaccess. // 107216 JXF 04/17/02 Bug 514927 // 106854 JXF 04/15/02 Fix http suites due to SqlChars // 106448 JXF 04/12/02 Bugs on sqlchars // 105715 JXF 04/05/02 Handle NULL properly in SqlBytes.SetLength // 91128 JXF 10/17/01 Make SqlBytes not unsafe // // 04/20/01 JunFang Created. // // @EndHeader@ //************************************************************************* namespace System.Data.SqlTypes { using System; using System.IO; using System.Runtime.InteropServices; using System.Diagnostics; using System.Data.Common; using System.Data.Sql; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using System.Runtime.Serialization; using System.Security.Permissions; [Serializable,XmlSchemaProvider("GetXsdType")] public sealed class SqlChars : System.Data.SqlTypes.INullable, IXmlSerializable, ISerializable { // -------------------------------------------------------------- // Data members // ------------------------------------------------------------- // SqlChars has five possible states // 1) SqlChars is Null // - m_pchData and m_stream must be null, m_lCuLen must be x_lNull // 2) SqlChars contains a valid buffer, // - m_rgchBuf must not be null, and m_pchData and m_stream must be null // 3) SqlChars contains a valid pointer // - m_pchData must not be null, m_rgchBuf could be null or not, // if not null, content is garbage, should never look into it. // - m_stream must be null. // 4) SqlChars contains a SqlStreamChars // - m_stream must not be null // - m_rgchBuf could be null or not. if not null, content is garbage, should never look into it. // - m_pchData must be null. // - m_lCurLen must be x_lNull. // 5) SqlChars contains a Lazy Materialized Blob (ie, StorageState.Delayed) // internal char[] m_rgchBuf; // Data buffer private long m_lCurLen; // Current data length #pragma warning disable 169 // this field is no longer used, hence the warning was disabled // however, it can not be removed or it will break serialization with pre-release builds of V2.0 private IntPtr m_pchData; // Pointer to data in unmanaged memory, We don't own this memory, should never free #pragma warning restore 169 internal SqlStreamChars m_stream; private SqlBytesCharsState m_state; private char[] m_rgchWorkBuf; // A 1-char work buffer. #if WINFSFunctionality private byte[] m_cookie; #endif // The max data length that we support at this time. private const long x_lMaxLen = (long)System.Int32.MaxValue; private const long x_lNull = -1L; // -------------------------------------------------------------- // Constructor(s) // -------------------------------------------------------------- // Public default constructor used for XML serialization public SqlChars() { SetNull(); } // Create a SqlChars with an in-memory buffer public SqlChars(char[] buffer) { m_rgchBuf = buffer; m_stream = null; if (m_rgchBuf == null) { m_state = SqlBytesCharsState.Null; m_lCurLen = x_lNull; } else { m_state = SqlBytesCharsState.Buffer; m_lCurLen = (long)m_rgchBuf.Length; } m_rgchWorkBuf = null; AssertValid(); } // Create a SqlChars from a SqlString public SqlChars(SqlString value) : this (value.IsNull ? (char[])null : value.Value.ToCharArray()) { } // Create a SqlChars from a SqlStreamChars #if WINFSInternalOnly public #else internal #endif SqlChars(SqlStreamChars s) { m_rgchBuf = null; m_lCurLen = x_lNull; m_stream = s; m_state = (s == null) ? SqlBytesCharsState.Null : SqlBytesCharsState.Stream; m_rgchWorkBuf = null; AssertValid(); } #if WINFSFunctionality internal SqlChars(byte[] cookie): this((char[]) null) { m_state = SqlBytesCharsState.Delayed; m_cookie = cookie; } #endif // Constructor required for serialization. Deserializes as a Buffer. If the bits have been tampered with // then this will throw a SerializationException or a InvalidCastException. private SqlChars(SerializationInfo info, StreamingContext context) { m_stream = null; m_rgchWorkBuf = null; if (info.GetBoolean("IsNull")) { m_state = SqlBytesCharsState.Null; m_rgchBuf = null; } else { m_state = SqlBytesCharsState.Buffer; m_rgchBuf = (char[]) info.GetValue("data", typeof(char[])); m_lCurLen = m_rgchBuf.Length; } AssertValid(); } // ------------------------------------------------------------- // Public properties // -------------------------------------------------------------- #if WINFSFunctionality #if WINFSInternalOnly internal #else public #endif // Internal for WinFS until UDTExtensions rebuilt against DWPriv.dll bool IsFilled { get { return (m_state != SqlBytesCharsState.Delayed); } } #endif // INullable public bool IsNull { get { #if WINFSFunctionality AssertFilled(); #endif return m_state == SqlBytesCharsState.Null; } } // Property: the in-memory buffer of SqlChars // Return Buffer even if SqlChars is Null. public char[] Buffer { get { #if WINFSFunctionality AssertFilled(); #endif if (FStream()) { CopyStreamToBuffer(); } return m_rgchBuf; } } // Property: the actual length of the data public long Length { get { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Null: throw new SqlNullValueException(); case SqlBytesCharsState.Stream: return m_stream.Length; default: return m_lCurLen; } } } // Property: the max length of the data // Return MaxLength even if SqlChars is Null. // When the buffer is also null, return -1. // If containing a Stream, return -1. public long MaxLength { get { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Stream: return -1L; default: return (m_rgchBuf == null) ? -1L : (long)m_rgchBuf.Length; } } } // Property: get a copy of the data in a new char[] array. public char[] Value { get { #if WINFSFunctionality AssertFilled(); #endif char[] buffer; switch (m_state) { case SqlBytesCharsState.Null: throw new SqlNullValueException(); case SqlBytesCharsState.Stream: if (m_stream.Length > x_lMaxLen) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); buffer = new char[m_stream.Length]; if (m_stream.Position != 0) m_stream.Seek(0, SeekOrigin.Begin); m_stream.Read(buffer, 0, checked((int)m_stream.Length)); break; default: buffer = new char[m_lCurLen]; Array.Copy(m_rgchBuf, buffer, (int)m_lCurLen); break; } return buffer; } } // class indexer public char this[long offset] { get { #if WINFSFunctionality AssertFilled(); #endif if (offset < 0 || offset >= this.Length) throw new ArgumentOutOfRangeException("offset"); if (m_rgchWorkBuf == null) m_rgchWorkBuf = new char[1]; Read(offset, m_rgchWorkBuf, 0, 1); return m_rgchWorkBuf[0]; } set { #if WINFSFunctionality AssertFilled(); #endif if (m_rgchWorkBuf == null) m_rgchWorkBuf = new char[1]; m_rgchWorkBuf[0] = value; Write(offset, m_rgchWorkBuf, 0, 1); } } #if WINFSInternalOnly public #else internal #endif SqlStreamChars Stream { get { #if WINFSFunctionality AssertFilled(); #endif return FStream() ? m_stream : new StreamOnSqlChars(this); } set { m_lCurLen = x_lNull; m_stream = value; m_state = (value == null) ? SqlBytesCharsState.Null : SqlBytesCharsState.Stream; AssertValid(); } } public StorageState Storage { get { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Null: throw new SqlNullValueException(); case SqlBytesCharsState.Stream: return StorageState.Stream; case SqlBytesCharsState.Buffer: return StorageState.Buffer; #if WINFSFunctionality case SqlBytesCharsState.Delayed: return StorageState.Delayed; #endif default: return StorageState.UnmanagedBuffer; } } } // ------------------------------------------------------------- // Public methods // ------------------------------------------------------------- #if WINFSFunctionality #if WINFSInternalOnly internal #else public #endif // Internal for WinFS until UDTExtensions rebuilt against DWPriv.dll void Fill(SqlConnection connection) { Fill(connection, null); } internal void Fill(SqlConnection connection, SqlTransaction transaction) { AssertNotFilled(); Object result = SQLUtility.GetLOBFromCookie(m_cookie, connection, transaction); m_cookie = null; if ((result == null) || (result is DBNull)) SetNull(); else SetBuffer(((string)result).ToCharArray()); } #endif public void SetNull() { #if WINFSFunctionality // Clear the buffer only if it was a cookie if (!IsFilled) m_rgchBuf = null; #endif m_lCurLen = x_lNull; m_stream = null; m_state = SqlBytesCharsState.Null; AssertValid(); } // Set the current length of the data // If the SqlChars is Null, setLength will make it non-Null. public void SetLength(long value) { #if WINFSFunctionality AssertFilled(); #endif if (value < 0) throw new ArgumentOutOfRangeException("value"); if (FStream()) { m_stream.SetLength(value); } else { // If there is a buffer, even the value of SqlChars is Null, // still allow setting length to zero, which will make it not Null. // If the buffer is null, raise exception // if (null == m_rgchBuf) throw new SqlTypeException(Res.GetString(Res.SqlMisc_NoBufferMessage)); if (value > (long)m_rgchBuf.Length) throw new ArgumentOutOfRangeException("value"); else if (IsNull) // At this point we know that value is small enough // Go back in buffer mode m_state = SqlBytesCharsState.Buffer; m_lCurLen = value; } AssertValid(); } // Read data of specified length from specified offset into a buffer public long Read(long offset, char[] buffer, int offsetInBuffer, int count) { #if WINFSFunctionality AssertFilled(); #endif if (IsNull) throw new SqlNullValueException(); // Validate the arguments if (buffer == null) throw new ArgumentNullException("buffer"); if (offset > this.Length || offset < 0) throw new ArgumentOutOfRangeException("offset"); if (offsetInBuffer > buffer.Length || offsetInBuffer < 0) throw new ArgumentOutOfRangeException("offsetInBuffer"); if (count < 0 || count > buffer.Length - offsetInBuffer) throw new ArgumentOutOfRangeException("count"); // Adjust count based on data length if (count > this.Length - offset) count = (int)(this.Length - offset); if (count != 0) { switch (m_state) { case SqlBytesCharsState.Stream: if (m_stream.Position != offset) m_stream.Seek(offset, SeekOrigin.Begin); m_stream.Read(buffer, offsetInBuffer, count); break; default: Array.Copy(m_rgchBuf, offset, buffer, offsetInBuffer, count); break; } } return count; } // Write data of specified length into the SqlChars from specified offset public void Write(long offset, char[] buffer, int offsetInBuffer, int count) { #if WINFSFunctionality AssertFilled(); #endif if (FStream()) { if (m_stream.Position != offset) m_stream.Seek(offset, SeekOrigin.Begin); m_stream.Write(buffer, offsetInBuffer, count); } else { // Validate the arguments if (buffer == null) throw new ArgumentNullException("buffer"); if (m_rgchBuf == null) throw new SqlTypeException(Res.GetString(Res.SqlMisc_NoBufferMessage)); if (offset < 0) throw new ArgumentOutOfRangeException("offset"); if (offset > m_rgchBuf.Length) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length) throw new ArgumentOutOfRangeException("offsetInBuffer"); if (count < 0 || count > buffer.Length - offsetInBuffer) throw new ArgumentOutOfRangeException("count"); if (count > m_rgchBuf.Length - offset) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); if (IsNull) { // If NULL and there is buffer inside, we only allow writing from // offset zero. // if (offset != 0) throw new SqlTypeException(Res.GetString(Res.SqlMisc_WriteNonZeroOffsetOnNullMessage)); // treat as if our current length is zero. // Note this has to be done after all inputs are validated, so that // we won't throw exception after this point. // m_lCurLen = 0; m_state = SqlBytesCharsState.Buffer; } else if (offset > m_lCurLen) { // Don't allow writing from an offset that this larger than current length. // It would leave uninitialized data in the buffer. // throw new SqlTypeException(Res.GetString(Res.SqlMisc_WriteOffsetLargerThanLenMessage)); } if (count != 0) { Array.Copy(buffer, offsetInBuffer, m_rgchBuf, offset, count); // If the last position that has been written is after // the current data length, reset the length if (m_lCurLen < offset + count) m_lCurLen = offset + count; } } AssertValid(); } public SqlString ToSqlString() { #if WINFSFunctionality AssertFilled(); #endif return IsNull ? SqlString.Null : new String(Value); } // ------------------------------------------------------------- // Conversion operators // -------------------------------------------------------------- // Alternative method: ToSqlString() public static explicit operator SqlString(SqlChars value) { return value.ToSqlString(); } // Alternative method: constructor SqlChars(SqlString) public static explicit operator SqlChars(SqlString value) { return new SqlChars(value); } // ------------------------------------------------------------- // Private utility functions // -------------------------------------------------------------- [System.Diagnostics.Conditional("DEBUG")] private void AssertValid() { Debug.Assert(m_state >= SqlBytesCharsState.Null && m_state <= SqlBytesCharsState.Stream); if (IsNull) { } else { Debug.Assert((m_lCurLen >= 0 && m_lCurLen <= x_lMaxLen) || FStream()); Debug.Assert(FStream() || (m_rgchBuf != null && m_lCurLen <= m_rgchBuf.Length)); Debug.Assert(!FStream() || (m_lCurLen == x_lNull)); } Debug.Assert(m_rgchWorkBuf == null || m_rgchWorkBuf.Length == 1); } #if WINFSFunctionality // User is not allowed to use any methods until this SqlChars has been filled // except Fill() private void AssertFilled() { if (!IsFilled) throw new SqlNotFilledException(); } private void AssertNotFilled() { if (IsFilled) throw new SqlAlreadyFilledException(); } internal byte[] Cookie { get { Debug.Assert(!IsFilled, "Unexpected state on Cookie getter!"); return m_cookie; } } #endif // whether the SqlChars contains a Stream internal bool FStream() { return m_state == SqlBytesCharsState.Stream; } // Copy the data from the Stream to the array buffer. // If the SqlChars doesn't hold a buffer or the buffer // is not big enough, allocate new char array. private void CopyStreamToBuffer() { Debug.Assert(FStream()); long lStreamLen = m_stream.Length; if (lStreamLen >= x_lMaxLen) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); if (m_rgchBuf == null || m_rgchBuf.Length < lStreamLen) m_rgchBuf = new char[lStreamLen]; if (m_stream.Position != 0) m_stream.Seek(0, SeekOrigin.Begin); m_stream.Read(m_rgchBuf, 0, (int)lStreamLen); m_stream = null; m_lCurLen = lStreamLen; m_state = SqlBytesCharsState.Buffer; AssertValid(); } private void SetBuffer(char[] buffer) { m_rgchBuf = buffer; m_lCurLen = (m_rgchBuf == null) ? x_lNull : (long)m_rgchBuf.Length; m_stream = null; m_state = (m_rgchBuf == null) ? SqlBytesCharsState.Null : SqlBytesCharsState.Buffer; AssertValid(); } // -------------------------------------------------------------- // XML Serialization // ------------------------------------------------------------- XmlSchema IXmlSerializable.GetSchema() { return null; } void IXmlSerializable.ReadXml(XmlReader r) { #if WINFSFunctionality AssertFilled(); #endif char[] value = null; string isNull = r.GetAttribute("nil", XmlSchema.InstanceNamespace); if (isNull != null && XmlConvert.ToBoolean(isNull)) { SetNull(); } else { value = r.ReadElementString().ToCharArray(); SetBuffer(value); } } void IXmlSerializable.WriteXml(XmlWriter writer) { #if WINFSFunctionality AssertFilled(); #endif if (IsNull) { writer.WriteAttributeString("xsi", "nil", XmlSchema.InstanceNamespace, "true"); } else { char[] value = this.Buffer; writer.WriteString(new String(value, 0, (int)(this.Length))); } } public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet) { return new XmlQualifiedName("string", XmlSchema.Namespace); } // -------------------------------------------------------------- // Serialization using ISerializable // ------------------------------------------------------------- // State information is not saved. The current state is converted to Buffer and only the underlying // array is serialized, except for Null, in which case this state is kept. [SecurityPermissionAttribute(SecurityAction.LinkDemand,SerializationFormatter=true)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Null: info.AddValue("IsNull", true); break; case SqlBytesCharsState.Buffer: info.AddValue("IsNull", false); info.AddValue("data", m_rgchBuf); break; case SqlBytesCharsState.Stream: CopyStreamToBuffer(); goto case SqlBytesCharsState.Buffer; default: Debug.Assert(false); goto case SqlBytesCharsState.Null; } } // ------------------------------------------------------------- // Static fields, properties // ------------------------------------------------------------- // Get a Null instance. // Since SqlChars is mutable, have to be property and create a new one each time. public static SqlChars Null { get { return new SqlChars((char[])null); } } } // class SqlChars // StreamOnSqlChars is a stream build on top of SqlChars, and // provides the Stream interface. The purpose is to help users // to read/write SqlChars object. internal sealed class StreamOnSqlChars : SqlStreamChars { // -------------------------------------------------------------- // Data members // ------------------------------------------------------------- private SqlChars m_sqlchars; // the SqlChars object private long m_lPosition; // -------------------------------------------------------------- // Constructor(s) // -------------------------------------------------------------- internal StreamOnSqlChars(SqlChars s) { m_sqlchars = s; m_lPosition = 0; } // ------------------------------------------------------------- // Public properties // -------------------------------------------------------------- public override bool IsNull { get { return m_sqlchars == null || m_sqlchars.IsNull; } } // Always can read/write/seek, unless sb is null, // which means the stream has been closed. public override bool CanRead { get { return m_sqlchars != null && !m_sqlchars.IsNull; } } public override bool CanSeek { get { return m_sqlchars != null; } } public override bool CanWrite { get { return m_sqlchars != null && (!m_sqlchars.IsNull || m_sqlchars.m_rgchBuf != null); } } public override long Length { get { CheckIfStreamClosed("get_Length"); return m_sqlchars.Length; } } public override long Position { get { CheckIfStreamClosed("get_Position"); return m_lPosition; } set { CheckIfStreamClosed("set_Position"); if (value < 0 || value > m_sqlchars.Length) throw new ArgumentOutOfRangeException("value"); else m_lPosition = value; } } // ------------------------------------------------------------- // Public methods // ------------------------------------------------------------- public override long Seek(long offset, SeekOrigin origin) { CheckIfStreamClosed("Seek"); long lPosition = 0; switch(origin) { case SeekOrigin.Begin: if (offset < 0 || offset > m_sqlchars.Length) throw ADP.ArgumentOutOfRange("offset"); m_lPosition = offset; break; case SeekOrigin.Current: lPosition = m_lPosition + offset; if (lPosition < 0 || lPosition > m_sqlchars.Length) throw ADP.ArgumentOutOfRange("offset"); m_lPosition = lPosition; break; case SeekOrigin.End: lPosition = m_sqlchars.Length + offset; if (lPosition < 0 || lPosition > m_sqlchars.Length) throw ADP.ArgumentOutOfRange("offset"); m_lPosition = lPosition; break; default: throw ADP.ArgumentOutOfRange("offset");; } return m_lPosition; } // The Read/Write/Readchar/Writechar simply delegates to SqlChars public override int Read(char[] buffer, int offset, int count) { CheckIfStreamClosed("Read"); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset < 0 || offset > buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count < 0 || count > buffer.Length - offset) throw new ArgumentOutOfRangeException("count"); int icharsRead = (int)m_sqlchars.Read(m_lPosition, buffer, offset, count); m_lPosition += icharsRead; return icharsRead; } public override void Write(char[] buffer, int offset, int count) { CheckIfStreamClosed("Write"); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset < 0 || offset > buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count < 0 || count > buffer.Length - offset) throw new ArgumentOutOfRangeException("count"); m_sqlchars.Write(m_lPosition, buffer, offset, count); m_lPosition += count; } public override int ReadChar() { CheckIfStreamClosed("ReadChar"); // If at the end of stream, return -1, rather than call SqlChars.Readchar, // which will throw exception. This is the behavior for Stream. // if (m_lPosition >= m_sqlchars.Length) return -1; int ret = m_sqlchars[m_lPosition]; m_lPosition ++; return ret; } public override void WriteChar(char value) { CheckIfStreamClosed("WriteChar"); m_sqlchars[m_lPosition] = value; m_lPosition ++; } public override void SetLength(long value) { CheckIfStreamClosed("SetLength"); m_sqlchars.SetLength(value); if (m_lPosition > value) m_lPosition = value; } // Flush is a no-op if underlying SqlChars is not a stream on SqlChars public override void Flush() { if (m_sqlchars.FStream()) m_sqlchars.m_stream.Flush(); } protected override void Dispose(bool disposing) { // When m_sqlchars is null, it means the stream has been closed, and // any opearation in the future should fail. // This is the only case that m_sqlchars is null. m_sqlchars = null; } // ------------------------------------------------------------- // Private utility functions // -------------------------------------------------------------- private bool FClosed() { return m_sqlchars == null; } private void CheckIfStreamClosed(string methodname) { if (FClosed()) throw ADP.StreamClosed(methodname); } } // class StreamOnSqlChars } // namespace System.Data.SqlTypes // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //junfang //[....] //[....] //----------------------------------------------------------------------------- //************************************************************************* // @File: SqlChars.cs // @Owner: junfang // // Created by: JunFang // // Description: Class SqlChars is used to represent a char/varchar/nchar/nvarchar // data from SQL Server. It contains a char array buffer, which can // be refilled. For example, in data access, user could use one instance // of SqlChars to bind to a binary column, and we will just keep copying // the data into the same instance, and avoid allocation per row. // // Notes: // // History: // // @Version: Yukon // 120214 JXF 09/23/02 SqlBytes/SqlChars class indexer // 112296 AZA 07/06/02 Seal SqlAccess classes. // 107151 AZA 04/18/02 Track byte array buffer as well as SqlBytes in // sqlaccess. // 107216 JXF 04/17/02 Bug 514927 // 106854 JXF 04/15/02 Fix http suites due to SqlChars // 106448 JXF 04/12/02 Bugs on sqlchars // 105715 JXF 04/05/02 Handle NULL properly in SqlBytes.SetLength // 91128 JXF 10/17/01 Make SqlBytes not unsafe // // 04/20/01 JunFang Created. // // @EndHeader@ //************************************************************************* namespace System.Data.SqlTypes { using System; using System.IO; using System.Runtime.InteropServices; using System.Diagnostics; using System.Data.Common; using System.Data.Sql; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using System.Runtime.Serialization; using System.Security.Permissions; [Serializable,XmlSchemaProvider("GetXsdType")] public sealed class SqlChars : System.Data.SqlTypes.INullable, IXmlSerializable, ISerializable { // -------------------------------------------------------------- // Data members // ------------------------------------------------------------- // SqlChars has five possible states // 1) SqlChars is Null // - m_pchData and m_stream must be null, m_lCuLen must be x_lNull // 2) SqlChars contains a valid buffer, // - m_rgchBuf must not be null, and m_pchData and m_stream must be null // 3) SqlChars contains a valid pointer // - m_pchData must not be null, m_rgchBuf could be null or not, // if not null, content is garbage, should never look into it. // - m_stream must be null. // 4) SqlChars contains a SqlStreamChars // - m_stream must not be null // - m_rgchBuf could be null or not. if not null, content is garbage, should never look into it. // - m_pchData must be null. // - m_lCurLen must be x_lNull. // 5) SqlChars contains a Lazy Materialized Blob (ie, StorageState.Delayed) // internal char[] m_rgchBuf; // Data buffer private long m_lCurLen; // Current data length #pragma warning disable 169 // this field is no longer used, hence the warning was disabled // however, it can not be removed or it will break serialization with pre-release builds of V2.0 private IntPtr m_pchData; // Pointer to data in unmanaged memory, We don't own this memory, should never free #pragma warning restore 169 internal SqlStreamChars m_stream; private SqlBytesCharsState m_state; private char[] m_rgchWorkBuf; // A 1-char work buffer. #if WINFSFunctionality private byte[] m_cookie; #endif // The max data length that we support at this time. private const long x_lMaxLen = (long)System.Int32.MaxValue; private const long x_lNull = -1L; // -------------------------------------------------------------- // Constructor(s) // -------------------------------------------------------------- // Public default constructor used for XML serialization public SqlChars() { SetNull(); } // Create a SqlChars with an in-memory buffer public SqlChars(char[] buffer) { m_rgchBuf = buffer; m_stream = null; if (m_rgchBuf == null) { m_state = SqlBytesCharsState.Null; m_lCurLen = x_lNull; } else { m_state = SqlBytesCharsState.Buffer; m_lCurLen = (long)m_rgchBuf.Length; } m_rgchWorkBuf = null; AssertValid(); } // Create a SqlChars from a SqlString public SqlChars(SqlString value) : this (value.IsNull ? (char[])null : value.Value.ToCharArray()) { } // Create a SqlChars from a SqlStreamChars #if WINFSInternalOnly public #else internal #endif SqlChars(SqlStreamChars s) { m_rgchBuf = null; m_lCurLen = x_lNull; m_stream = s; m_state = (s == null) ? SqlBytesCharsState.Null : SqlBytesCharsState.Stream; m_rgchWorkBuf = null; AssertValid(); } #if WINFSFunctionality internal SqlChars(byte[] cookie): this((char[]) null) { m_state = SqlBytesCharsState.Delayed; m_cookie = cookie; } #endif // Constructor required for serialization. Deserializes as a Buffer. If the bits have been tampered with // then this will throw a SerializationException or a InvalidCastException. private SqlChars(SerializationInfo info, StreamingContext context) { m_stream = null; m_rgchWorkBuf = null; if (info.GetBoolean("IsNull")) { m_state = SqlBytesCharsState.Null; m_rgchBuf = null; } else { m_state = SqlBytesCharsState.Buffer; m_rgchBuf = (char[]) info.GetValue("data", typeof(char[])); m_lCurLen = m_rgchBuf.Length; } AssertValid(); } // ------------------------------------------------------------- // Public properties // -------------------------------------------------------------- #if WINFSFunctionality #if WINFSInternalOnly internal #else public #endif // Internal for WinFS until UDTExtensions rebuilt against DWPriv.dll bool IsFilled { get { return (m_state != SqlBytesCharsState.Delayed); } } #endif // INullable public bool IsNull { get { #if WINFSFunctionality AssertFilled(); #endif return m_state == SqlBytesCharsState.Null; } } // Property: the in-memory buffer of SqlChars // Return Buffer even if SqlChars is Null. public char[] Buffer { get { #if WINFSFunctionality AssertFilled(); #endif if (FStream()) { CopyStreamToBuffer(); } return m_rgchBuf; } } // Property: the actual length of the data public long Length { get { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Null: throw new SqlNullValueException(); case SqlBytesCharsState.Stream: return m_stream.Length; default: return m_lCurLen; } } } // Property: the max length of the data // Return MaxLength even if SqlChars is Null. // When the buffer is also null, return -1. // If containing a Stream, return -1. public long MaxLength { get { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Stream: return -1L; default: return (m_rgchBuf == null) ? -1L : (long)m_rgchBuf.Length; } } } // Property: get a copy of the data in a new char[] array. public char[] Value { get { #if WINFSFunctionality AssertFilled(); #endif char[] buffer; switch (m_state) { case SqlBytesCharsState.Null: throw new SqlNullValueException(); case SqlBytesCharsState.Stream: if (m_stream.Length > x_lMaxLen) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); buffer = new char[m_stream.Length]; if (m_stream.Position != 0) m_stream.Seek(0, SeekOrigin.Begin); m_stream.Read(buffer, 0, checked((int)m_stream.Length)); break; default: buffer = new char[m_lCurLen]; Array.Copy(m_rgchBuf, buffer, (int)m_lCurLen); break; } return buffer; } } // class indexer public char this[long offset] { get { #if WINFSFunctionality AssertFilled(); #endif if (offset < 0 || offset >= this.Length) throw new ArgumentOutOfRangeException("offset"); if (m_rgchWorkBuf == null) m_rgchWorkBuf = new char[1]; Read(offset, m_rgchWorkBuf, 0, 1); return m_rgchWorkBuf[0]; } set { #if WINFSFunctionality AssertFilled(); #endif if (m_rgchWorkBuf == null) m_rgchWorkBuf = new char[1]; m_rgchWorkBuf[0] = value; Write(offset, m_rgchWorkBuf, 0, 1); } } #if WINFSInternalOnly public #else internal #endif SqlStreamChars Stream { get { #if WINFSFunctionality AssertFilled(); #endif return FStream() ? m_stream : new StreamOnSqlChars(this); } set { m_lCurLen = x_lNull; m_stream = value; m_state = (value == null) ? SqlBytesCharsState.Null : SqlBytesCharsState.Stream; AssertValid(); } } public StorageState Storage { get { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Null: throw new SqlNullValueException(); case SqlBytesCharsState.Stream: return StorageState.Stream; case SqlBytesCharsState.Buffer: return StorageState.Buffer; #if WINFSFunctionality case SqlBytesCharsState.Delayed: return StorageState.Delayed; #endif default: return StorageState.UnmanagedBuffer; } } } // ------------------------------------------------------------- // Public methods // ------------------------------------------------------------- #if WINFSFunctionality #if WINFSInternalOnly internal #else public #endif // Internal for WinFS until UDTExtensions rebuilt against DWPriv.dll void Fill(SqlConnection connection) { Fill(connection, null); } internal void Fill(SqlConnection connection, SqlTransaction transaction) { AssertNotFilled(); Object result = SQLUtility.GetLOBFromCookie(m_cookie, connection, transaction); m_cookie = null; if ((result == null) || (result is DBNull)) SetNull(); else SetBuffer(((string)result).ToCharArray()); } #endif public void SetNull() { #if WINFSFunctionality // Clear the buffer only if it was a cookie if (!IsFilled) m_rgchBuf = null; #endif m_lCurLen = x_lNull; m_stream = null; m_state = SqlBytesCharsState.Null; AssertValid(); } // Set the current length of the data // If the SqlChars is Null, setLength will make it non-Null. public void SetLength(long value) { #if WINFSFunctionality AssertFilled(); #endif if (value < 0) throw new ArgumentOutOfRangeException("value"); if (FStream()) { m_stream.SetLength(value); } else { // If there is a buffer, even the value of SqlChars is Null, // still allow setting length to zero, which will make it not Null. // If the buffer is null, raise exception // if (null == m_rgchBuf) throw new SqlTypeException(Res.GetString(Res.SqlMisc_NoBufferMessage)); if (value > (long)m_rgchBuf.Length) throw new ArgumentOutOfRangeException("value"); else if (IsNull) // At this point we know that value is small enough // Go back in buffer mode m_state = SqlBytesCharsState.Buffer; m_lCurLen = value; } AssertValid(); } // Read data of specified length from specified offset into a buffer public long Read(long offset, char[] buffer, int offsetInBuffer, int count) { #if WINFSFunctionality AssertFilled(); #endif if (IsNull) throw new SqlNullValueException(); // Validate the arguments if (buffer == null) throw new ArgumentNullException("buffer"); if (offset > this.Length || offset < 0) throw new ArgumentOutOfRangeException("offset"); if (offsetInBuffer > buffer.Length || offsetInBuffer < 0) throw new ArgumentOutOfRangeException("offsetInBuffer"); if (count < 0 || count > buffer.Length - offsetInBuffer) throw new ArgumentOutOfRangeException("count"); // Adjust count based on data length if (count > this.Length - offset) count = (int)(this.Length - offset); if (count != 0) { switch (m_state) { case SqlBytesCharsState.Stream: if (m_stream.Position != offset) m_stream.Seek(offset, SeekOrigin.Begin); m_stream.Read(buffer, offsetInBuffer, count); break; default: Array.Copy(m_rgchBuf, offset, buffer, offsetInBuffer, count); break; } } return count; } // Write data of specified length into the SqlChars from specified offset public void Write(long offset, char[] buffer, int offsetInBuffer, int count) { #if WINFSFunctionality AssertFilled(); #endif if (FStream()) { if (m_stream.Position != offset) m_stream.Seek(offset, SeekOrigin.Begin); m_stream.Write(buffer, offsetInBuffer, count); } else { // Validate the arguments if (buffer == null) throw new ArgumentNullException("buffer"); if (m_rgchBuf == null) throw new SqlTypeException(Res.GetString(Res.SqlMisc_NoBufferMessage)); if (offset < 0) throw new ArgumentOutOfRangeException("offset"); if (offset > m_rgchBuf.Length) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length) throw new ArgumentOutOfRangeException("offsetInBuffer"); if (count < 0 || count > buffer.Length - offsetInBuffer) throw new ArgumentOutOfRangeException("count"); if (count > m_rgchBuf.Length - offset) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); if (IsNull) { // If NULL and there is buffer inside, we only allow writing from // offset zero. // if (offset != 0) throw new SqlTypeException(Res.GetString(Res.SqlMisc_WriteNonZeroOffsetOnNullMessage)); // treat as if our current length is zero. // Note this has to be done after all inputs are validated, so that // we won't throw exception after this point. // m_lCurLen = 0; m_state = SqlBytesCharsState.Buffer; } else if (offset > m_lCurLen) { // Don't allow writing from an offset that this larger than current length. // It would leave uninitialized data in the buffer. // throw new SqlTypeException(Res.GetString(Res.SqlMisc_WriteOffsetLargerThanLenMessage)); } if (count != 0) { Array.Copy(buffer, offsetInBuffer, m_rgchBuf, offset, count); // If the last position that has been written is after // the current data length, reset the length if (m_lCurLen < offset + count) m_lCurLen = offset + count; } } AssertValid(); } public SqlString ToSqlString() { #if WINFSFunctionality AssertFilled(); #endif return IsNull ? SqlString.Null : new String(Value); } // ------------------------------------------------------------- // Conversion operators // -------------------------------------------------------------- // Alternative method: ToSqlString() public static explicit operator SqlString(SqlChars value) { return value.ToSqlString(); } // Alternative method: constructor SqlChars(SqlString) public static explicit operator SqlChars(SqlString value) { return new SqlChars(value); } // ------------------------------------------------------------- // Private utility functions // -------------------------------------------------------------- [System.Diagnostics.Conditional("DEBUG")] private void AssertValid() { Debug.Assert(m_state >= SqlBytesCharsState.Null && m_state <= SqlBytesCharsState.Stream); if (IsNull) { } else { Debug.Assert((m_lCurLen >= 0 && m_lCurLen <= x_lMaxLen) || FStream()); Debug.Assert(FStream() || (m_rgchBuf != null && m_lCurLen <= m_rgchBuf.Length)); Debug.Assert(!FStream() || (m_lCurLen == x_lNull)); } Debug.Assert(m_rgchWorkBuf == null || m_rgchWorkBuf.Length == 1); } #if WINFSFunctionality // User is not allowed to use any methods until this SqlChars has been filled // except Fill() private void AssertFilled() { if (!IsFilled) throw new SqlNotFilledException(); } private void AssertNotFilled() { if (IsFilled) throw new SqlAlreadyFilledException(); } internal byte[] Cookie { get { Debug.Assert(!IsFilled, "Unexpected state on Cookie getter!"); return m_cookie; } } #endif // whether the SqlChars contains a Stream internal bool FStream() { return m_state == SqlBytesCharsState.Stream; } // Copy the data from the Stream to the array buffer. // If the SqlChars doesn't hold a buffer or the buffer // is not big enough, allocate new char array. private void CopyStreamToBuffer() { Debug.Assert(FStream()); long lStreamLen = m_stream.Length; if (lStreamLen >= x_lMaxLen) throw new SqlTypeException(Res.GetString(Res.SqlMisc_BufferInsufficientMessage)); if (m_rgchBuf == null || m_rgchBuf.Length < lStreamLen) m_rgchBuf = new char[lStreamLen]; if (m_stream.Position != 0) m_stream.Seek(0, SeekOrigin.Begin); m_stream.Read(m_rgchBuf, 0, (int)lStreamLen); m_stream = null; m_lCurLen = lStreamLen; m_state = SqlBytesCharsState.Buffer; AssertValid(); } private void SetBuffer(char[] buffer) { m_rgchBuf = buffer; m_lCurLen = (m_rgchBuf == null) ? x_lNull : (long)m_rgchBuf.Length; m_stream = null; m_state = (m_rgchBuf == null) ? SqlBytesCharsState.Null : SqlBytesCharsState.Buffer; AssertValid(); } // -------------------------------------------------------------- // XML Serialization // ------------------------------------------------------------- XmlSchema IXmlSerializable.GetSchema() { return null; } void IXmlSerializable.ReadXml(XmlReader r) { #if WINFSFunctionality AssertFilled(); #endif char[] value = null; string isNull = r.GetAttribute("nil", XmlSchema.InstanceNamespace); if (isNull != null && XmlConvert.ToBoolean(isNull)) { SetNull(); } else { value = r.ReadElementString().ToCharArray(); SetBuffer(value); } } void IXmlSerializable.WriteXml(XmlWriter writer) { #if WINFSFunctionality AssertFilled(); #endif if (IsNull) { writer.WriteAttributeString("xsi", "nil", XmlSchema.InstanceNamespace, "true"); } else { char[] value = this.Buffer; writer.WriteString(new String(value, 0, (int)(this.Length))); } } public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet) { return new XmlQualifiedName("string", XmlSchema.Namespace); } // -------------------------------------------------------------- // Serialization using ISerializable // ------------------------------------------------------------- // State information is not saved. The current state is converted to Buffer and only the underlying // array is serialized, except for Null, in which case this state is kept. [SecurityPermissionAttribute(SecurityAction.LinkDemand,SerializationFormatter=true)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { #if WINFSFunctionality AssertFilled(); #endif switch (m_state) { case SqlBytesCharsState.Null: info.AddValue("IsNull", true); break; case SqlBytesCharsState.Buffer: info.AddValue("IsNull", false); info.AddValue("data", m_rgchBuf); break; case SqlBytesCharsState.Stream: CopyStreamToBuffer(); goto case SqlBytesCharsState.Buffer; default: Debug.Assert(false); goto case SqlBytesCharsState.Null; } } // ------------------------------------------------------------- // Static fields, properties // ------------------------------------------------------------- // Get a Null instance. // Since SqlChars is mutable, have to be property and create a new one each time. public static SqlChars Null { get { return new SqlChars((char[])null); } } } // class SqlChars // StreamOnSqlChars is a stream build on top of SqlChars, and // provides the Stream interface. The purpose is to help users // to read/write SqlChars object. internal sealed class StreamOnSqlChars : SqlStreamChars { // -------------------------------------------------------------- // Data members // ------------------------------------------------------------- private SqlChars m_sqlchars; // the SqlChars object private long m_lPosition; // -------------------------------------------------------------- // Constructor(s) // -------------------------------------------------------------- internal StreamOnSqlChars(SqlChars s) { m_sqlchars = s; m_lPosition = 0; } // ------------------------------------------------------------- // Public properties // -------------------------------------------------------------- public override bool IsNull { get { return m_sqlchars == null || m_sqlchars.IsNull; } } // Always can read/write/seek, unless sb is null, // which means the stream has been closed. public override bool CanRead { get { return m_sqlchars != null && !m_sqlchars.IsNull; } } public override bool CanSeek { get { return m_sqlchars != null; } } public override bool CanWrite { get { return m_sqlchars != null && (!m_sqlchars.IsNull || m_sqlchars.m_rgchBuf != null); } } public override long Length { get { CheckIfStreamClosed("get_Length"); return m_sqlchars.Length; } } public override long Position { get { CheckIfStreamClosed("get_Position"); return m_lPosition; } set { CheckIfStreamClosed("set_Position"); if (value < 0 || value > m_sqlchars.Length) throw new ArgumentOutOfRangeException("value"); else m_lPosition = value; } } // ------------------------------------------------------------- // Public methods // ------------------------------------------------------------- public override long Seek(long offset, SeekOrigin origin) { CheckIfStreamClosed("Seek"); long lPosition = 0; switch(origin) { case SeekOrigin.Begin: if (offset < 0 || offset > m_sqlchars.Length) throw ADP.ArgumentOutOfRange("offset"); m_lPosition = offset; break; case SeekOrigin.Current: lPosition = m_lPosition + offset; if (lPosition < 0 || lPosition > m_sqlchars.Length) throw ADP.ArgumentOutOfRange("offset"); m_lPosition = lPosition; break; case SeekOrigin.End: lPosition = m_sqlchars.Length + offset; if (lPosition < 0 || lPosition > m_sqlchars.Length) throw ADP.ArgumentOutOfRange("offset"); m_lPosition = lPosition; break; default: throw ADP.ArgumentOutOfRange("offset");; } return m_lPosition; } // The Read/Write/Readchar/Writechar simply delegates to SqlChars public override int Read(char[] buffer, int offset, int count) { CheckIfStreamClosed("Read"); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset < 0 || offset > buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count < 0 || count > buffer.Length - offset) throw new ArgumentOutOfRangeException("count"); int icharsRead = (int)m_sqlchars.Read(m_lPosition, buffer, offset, count); m_lPosition += icharsRead; return icharsRead; } public override void Write(char[] buffer, int offset, int count) { CheckIfStreamClosed("Write"); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset < 0 || offset > buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count < 0 || count > buffer.Length - offset) throw new ArgumentOutOfRangeException("count"); m_sqlchars.Write(m_lPosition, buffer, offset, count); m_lPosition += count; } public override int ReadChar() { CheckIfStreamClosed("ReadChar"); // If at the end of stream, return -1, rather than call SqlChars.Readchar, // which will throw exception. This is the behavior for Stream. // if (m_lPosition >= m_sqlchars.Length) return -1; int ret = m_sqlchars[m_lPosition]; m_lPosition ++; return ret; } public override void WriteChar(char value) { CheckIfStreamClosed("WriteChar"); m_sqlchars[m_lPosition] = value; m_lPosition ++; } public override void SetLength(long value) { CheckIfStreamClosed("SetLength"); m_sqlchars.SetLength(value); if (m_lPosition > value) m_lPosition = value; } // Flush is a no-op if underlying SqlChars is not a stream on SqlChars public override void Flush() { if (m_sqlchars.FStream()) m_sqlchars.m_stream.Flush(); } protected override void Dispose(bool disposing) { // When m_sqlchars is null, it means the stream has been closed, and // any opearation in the future should fail. // This is the only case that m_sqlchars is null. m_sqlchars = null; } // ------------------------------------------------------------- // Private utility functions // -------------------------------------------------------------- private bool FClosed() { return m_sqlchars == null; } private void CheckIfStreamClosed(string methodname) { if (FClosed()) throw ADP.StreamClosed(methodname); } } // class StreamOnSqlChars } // namespace System.Data.SqlTypes // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpServerUtilityBase.cs
- SimpleExpression.cs
- FunctionNode.cs
- ValueHandle.cs
- PersonalizationAdministration.cs
- XmlUtilWriter.cs
- _LocalDataStore.cs
- SiteMembershipCondition.cs
- NativeRecognizer.cs
- ReadOnlyHierarchicalDataSourceView.cs
- HttpHandlersSection.cs
- QueryContext.cs
- EncryptedKey.cs
- VSWCFServiceContractGenerator.cs
- DataListItem.cs
- XmlValueConverter.cs
- BrowserCapabilitiesFactoryBase.cs
- MemberListBinding.cs
- util.cs
- CompilerTypeWithParams.cs
- CompoundFileIOPermission.cs
- ContextMenuStripGroupCollection.cs
- XPathNodeIterator.cs
- BaseTemplateBuildProvider.cs
- ITextView.cs
- BitmapVisualManager.cs
- DbDataSourceEnumerator.cs
- HtmlTitle.cs
- FormsAuthenticationCredentials.cs
- ApplicationDirectory.cs
- BypassElement.cs
- Vector3DAnimationUsingKeyFrames.cs
- OleDbErrorCollection.cs
- ConfigurationCollectionAttribute.cs
- ClientFormsAuthenticationCredentials.cs
- ServiceOperationHelpers.cs
- LinkArea.cs
- OperatingSystem.cs
- ValidationErrorCollection.cs
- ListBox.cs
- SslStream.cs
- WorkflowOperationContext.cs
- GeneralTransform2DTo3DTo2D.cs
- storepermission.cs
- PrivateFontCollection.cs
- MultipartContentParser.cs
- InternalSafeNativeMethods.cs
- BindingWorker.cs
- PiiTraceSource.cs
- InvokeBinder.cs
- ButtonFlatAdapter.cs
- WorkerRequest.cs
- SmiEventSink_Default.cs
- GridViewRowEventArgs.cs
- Dispatcher.cs
- ListViewHitTestInfo.cs
- DataGridColumnHeader.cs
- PublisherIdentityPermission.cs
- TransactionTraceIdentifier.cs
- Command.cs
- DataFormats.cs
- ProcessHostConfigUtils.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- DesignerSerializationVisibilityAttribute.cs
- ActivityWithResultWrapper.cs
- Converter.cs
- ObsoleteAttribute.cs
- TriggerActionCollection.cs
- SafeNativeMethods.cs
- HtmlUtf8RawTextWriter.cs
- Base64Stream.cs
- GrammarBuilderBase.cs
- PrePrepareMethodAttribute.cs
- HwndMouseInputProvider.cs
- ListViewInsertedEventArgs.cs
- XsdCachingReader.cs
- ZipFileInfoCollection.cs
- TemplatePropertyEntry.cs
- ConfigurationElementProperty.cs
- DesignerObjectListAdapter.cs
- Pipe.cs
- _BufferOffsetSize.cs
- MenuItemBinding.cs
- RTLAwareMessageBox.cs
- Certificate.cs
- EmptyControlCollection.cs
- GroupDescription.cs
- ISAPIWorkerRequest.cs
- DatatypeImplementation.cs
- MergeLocalizationDirectives.cs
- PropertyEntry.cs
- TextEditorMouse.cs
- ObjectDisposedException.cs
- ObjectConverter.cs
- ProfileModule.cs
- XmlDocumentFragment.cs
- MemberPathMap.cs
- DataGridBoolColumn.cs
- RenderData.cs
- XmlSchemaComplexContentExtension.cs