Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / DataOracleClient / System / Data / OracleClient / OracleColumn.cs / 1 / OracleColumn.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.OracleClient { using System; using System.Data; using System.Data.Common; using System.Diagnostics; using System.IO; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Text; //--------------------------------------------------------------------- // OracleColumn // // Contains all the information about a single column in a result set, // and implements the methods necessary to describe column to Oracle // and to extract the column data from the native buffer used to fetch // it. // sealed internal class OracleColumn { private OciParameterDescriptor _describeHandle; // the Describe handle private int _ordinal; // the ordinal position in the rowset (0..n-1) private string _columnName; // the name of the column private MetaType _metaType; private byte _precision; // precision of the column (OracleNumber only) private byte _scale; // scale of the column (OracleNumber only) private int _byteSize; // how many bytes we need in the row buffer private bool _isNullable; // whether the value is nullable or not. private int _indicatorOffset; // offset from the start of the row buffer to the indicator binding (see OCI.INDICATOR) private int _lengthOffset; // offset from the start of the row buffer to the length binding private int _valueOffset; // offset from the start of the row buffer to the value binding private NativeBuffer_RowBuffer _rowBuffer; // the row buffer we're bound to (reused for all rows fetched) private NativeBuffer_LongColumnData _longBuffer;// the out-of-line buffer used for piecewise binding; must be reset for each new fetch. private int _longLength; // the length of the data we actually fetched into _longBuffer private OCI.Callback.OCICallbackDefine _callback;// the piecewise binding callback for this column private OciLobLocator _lobLocator; // the descriptor allocated for LOB columns private OracleConnection _connection; // the connection the column is on (LOB columns only) private int _connectionCloseCount; // The close count of the connection; used to decide if we're zombied private bool _bindAsUTF16; // true whenever we're binding character data as Unicode... // Construct by getting the specified describe handle from the specified statement handle internal OracleColumn(OciStatementHandle statementHandle, int ordinal, OciErrorHandle errorHandle, OracleConnection connection) { _ordinal = ordinal; _describeHandle = statementHandle.GetDescriptor(_ordinal, errorHandle);; _connection = connection; _connectionCloseCount = connection.CloseCount; } internal string ColumnName { get { return _columnName; } } internal bool IsNullable { get { return _isNullable; } } internal bool IsLob { get { return _metaType.IsLob; } } internal bool IsLong { get { return _metaType.IsLong; } } internal OracleType OracleType { get { return _metaType.OracleType; } } internal int Ordinal { get { return _ordinal; } } internal byte Precision { get { return _precision; } } internal byte Scale { get { return _scale; } } // This is the value used for the SchemaTable, which must be Chars... internal int SchemaTableSize { get { return (_bindAsUTF16 && !_metaType.IsLong)?_byteSize/2:_byteSize; } } private int _callback_GetColumnPiecewise( IntPtr octxp, IntPtr defnp, uint iter, IntPtr bufpp, // dvoid** IntPtr alenp, // ub4** IntPtr piecep, // ub1* IntPtr indpp, // dvoid** IntPtr rcodep // ub2** ) { // Callback routine for Dynamic Binding column values from Oracle: tell // Oracle where to stuff the data. if (Bid.AdvancedOn) Bid.Trace("" +" octxp=0x%-07Ix" +" defnp=0x%-07Ix" +" iter=%-2d" +" bufpp=0x%-07Ix" +" alenp=0x%-07Ix" +" piecep=0x%-07Ix" +" indpp=0x%-07Ix" +" rcodep=0x%-07Ix\n", octxp, defnp, unchecked((int)iter), // tracing -- I don't care about overflow. bufpp, alenp, piecep, indpp, rcodep ); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: THIS IS A CALLBACK FUNCTION FROM AN OCI PINVOKE! // Namely, OCIStmtFetch. We expect that you will have called // DangerousAddRef on the _rowBuffer and the _longBuffer // SafeHandles, to prevent any Handle Recycling from occurring. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // RFC50002189 - chunk length is saved as part of chunk's buffer // later, when the LONG field value is requested, TotalLength is used // to sum the lengths and the result is writtent into buffer[_lengthOffset], as before the change IntPtr lengthPtr; IntPtr indicatorPtr = (-1 != _indicatorOffset) ? _rowBuffer.DangerousGetDataPtr(_indicatorOffset) : IntPtr.Zero; IntPtr valuePtr = _longBuffer.GetChunk(out lengthPtr); Marshal.WriteIntPtr(bufpp, valuePtr); // *bufpp Marshal.WriteIntPtr(indpp, indicatorPtr); // *indpp Marshal.WriteIntPtr(alenp, lengthPtr); // *alenp // provide the size of allocated buffer, in bytes, to Oracle driver // on output, we will receive from Oracle driver the length of filled buffer, in bytes Marshal.WriteInt32(lengthPtr, NativeBuffer_LongColumnData.MaxChunkSize); // **alenp GC.KeepAlive(this); return (int)OCI.RETURNCODE.OCI_CONTINUE; } internal void Bind(OciStatementHandle statementHandle, NativeBuffer_RowBuffer buffer, OciErrorHandle errorHandle, int rowBufferLength) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: You must have called DangerousAddRef on the buffer before // calling this method, or you run the risk of allowing Handle // Recycling to occur! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Binds the buffer for the column to the statement handle specified. OciDefineHandle defineHandle = null; IntPtr h; OCI.MODE mode = OCI.MODE.OCI_DEFAULT; int bindByteSize; OCI.DATATYPE ociType = _metaType.OciType; _rowBuffer = buffer; if (_metaType.IsLong) { mode = OCI.MODE.OCI_DYNAMIC_FETCH; bindByteSize = Int32.MaxValue; } else { bindByteSize = _byteSize; } IntPtr indicatorLocation = IntPtr.Zero; IntPtr lengthLocation = IntPtr.Zero; IntPtr valueLocation = _rowBuffer.DangerousGetDataPtr(_valueOffset); if (-1 != _indicatorOffset) { indicatorLocation = _rowBuffer.DangerousGetDataPtr(_indicatorOffset); } if (-1 != _lengthOffset && !_metaType.IsLong) { lengthLocation = _rowBuffer.DangerousGetDataPtr(_lengthOffset); } try { int rc = TracedNativeMethods.OCIDefineByPos( statementHandle, // hndlp out h, // defnpp errorHandle, // errhp checked((uint)_ordinal+1), // position valueLocation, // valuep bindByteSize, // value_sz ociType, // htype indicatorLocation, // indp, lengthLocation, // rlenp, IntPtr.Zero, // rcodep, mode // mode ); if (rc != 0) { _connection.CheckError(errorHandle, rc); } defineHandle = new OciDefineHandle(statementHandle, h); if (0 != rowBufferLength) { uint valOffset = checked((uint)rowBufferLength); uint indOffset = (-1 != _indicatorOffset) ? valOffset : 0; uint lenOffset = (-1 != _lengthOffset && !_metaType.IsLong) ? valOffset : 0; rc = TracedNativeMethods.OCIDefineArrayOfStruct( defineHandle, errorHandle, valOffset, indOffset, lenOffset, 0 // never use rcodep above... ); if (rc != 0) { _connection.CheckError(errorHandle, rc); } } if (_metaType.UsesNationalCharacterSet) { Debug.Assert(!_metaType.IsLong, "LONG data may never be bound as NCHAR"); // NOTE: the order is important here; setting charsetForm will // reset charsetId (I found this out the hard way...) defineHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, (int)OCI.CHARSETFORM.SQLCS_NCHAR, errorHandle); } if (!_connection.UnicodeEnabled) { if (_bindAsUTF16) { // NOTE: the order is important here; setting charsetForm will // reset charsetId (I found this out the hard way...) defineHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_ID, (short)OCI.CHARSETID.OCI_UTF16ID, errorHandle); } } if (_metaType.IsLong) { // Initialize the longBuffer in the rowBuffer to null _rowBuffer.WriteIntPtr(_valueOffset, IntPtr.Zero); _callback = new OCI.Callback.OCICallbackDefine(_callback_GetColumnPiecewise); rc = TracedNativeMethods.OCIDefineDynamic( defineHandle, // defnp errorHandle, // errhp IntPtr.Zero, // dvoid *octxp, _callback // OCICallbackDefine ocbfp ); if (rc != 0) { _connection.CheckError(errorHandle, rc); } } } finally { // We don't need these any longer, get rid of it. NativeBuffer.SafeDispose(ref _longBuffer); OciHandle.SafeDispose(ref defineHandle); } } internal bool Describe(ref int offset, OracleConnection connection, OciErrorHandle errorHandle) { // Gets all of the column description information from the describe // handle. In addition, we'll determine the position of the column // in the rowbuffer, based upon the offset parameter, which is passed // by ref so we can adjust the end position accordingly. short tempub2; byte tempub1; OCI.DATATYPE ociType; bool needSize = false; bool cannotPrefetch = false; _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_NAME, out _columnName,errorHandle, _connection); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_DATA_TYPE, out tempub2, errorHandle); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_IS_NULL, out tempub1, errorHandle); _isNullable = (0 != tempub1); ociType = (OCI.DATATYPE)tempub2; switch (ociType) { case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_DATA_SIZE, out _byteSize, errorHandle); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM,out tempub1, errorHandle); OCI.CHARSETFORM charsetForm = (OCI.CHARSETFORM)tempub1; _bindAsUTF16 = connection.ServerVersionAtLeastOracle8; // SQLBUVSTS 217686: the _byteSize we have is size, in bytes, of the string in its server representation. This size can be // less than the buffer size we need to fetch the UTF16 chars for the same string which can result in // either silent data truncation or ORA-01406 exception of Oracle. // To calculate the byte size for UTF16 characters, we query for the size in UTF16 characters using // OCI_ATTR_CHAR_SIZE and double it (1 UTF16 char == 2 bytes). int charSize; // according to Oracle's documentation, OCI_ATTR_CHAR_SIZE is supported only if both client and server >= 9 if (connection.ServerVersionAtLeastOracle9i && OCI.ClientVersionAtLeastOracle9i) { // we can query for the char size since both client and server versions are >= 9 _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHAR_SIZE, out tempub2, errorHandle); charSize = tempub2; } else { // if either client or server is 8 or less, we cannot use OCI_ATTR_CHAR_SIZE attribute // in that case, we assume the worse scenario: max number of characters is same or less as number of bytes used to encode it // (which is true in all NLS languages and UTF* encodings). // we could query for OCI_ATTR_CHARSET_ID and calculate the max size with better efficiency, but this would // complicate the calcs thus making the fix risky and prone for regressions. charSize = _byteSize; } if (charsetForm == OCI.CHARSETFORM.SQLCS_NCHAR) { // National Character Set _metaType = MetaType.GetMetaTypeForType((OCI.DATATYPE.CHAR == ociType) ? OracleType.NChar : OracleType.NVarChar); } else { // Database Character Set _metaType = MetaType.GetMetaTypeForType((OCI.DATATYPE.CHAR == ociType) ? OracleType.Char : OracleType.VarChar); if (_bindAsUTF16) { // we deal only with UTF16 so get the size required to store same number of UTF16 chars _byteSize *= ADP.CharSize; } } // To fetch the data, we have to specify size in bytes. // To be on the safe side and avoid regressions, select the max between the size as it // is encoded on the server and the size we've calculated above. _byteSize = Math.Max(_byteSize, charSize * ADP.CharSize); needSize = true; break; case OCI.DATATYPE.DATE: _metaType = MetaType.GetMetaTypeForType(OracleType.DateTime); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.TIMESTAMP: _metaType = MetaType.GetMetaTypeForType(OracleType.Timestamp); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.TIMESTAMP_LTZ: _metaType = MetaType.GetMetaTypeForType(OracleType.TimestampLocal); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.TIMESTAMP_TZ: _metaType = MetaType.GetMetaTypeForType(OracleType.TimestampWithTZ); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.INTERVAL_YM: _metaType = MetaType.GetMetaTypeForType(OracleType.IntervalYearToMonth); _byteSize = _metaType.BindSize; break; case OCI.DATATYPE.INTERVAL_DS: _metaType = MetaType.GetMetaTypeForType(OracleType.IntervalDayToSecond); _byteSize = _metaType.BindSize; break; case OCI.DATATYPE.NUMBER: _metaType = MetaType.GetMetaTypeForType(OracleType.Number); _byteSize = _metaType.BindSize; _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_PRECISION, out _precision, errorHandle); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_SCALE, out _scale, errorHandle); break; case OCI.DATATYPE.RAW: _metaType = MetaType.GetMetaTypeForType(OracleType.Raw); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_DATA_SIZE, out _byteSize, errorHandle); needSize = true; break; case OCI.DATATYPE.ROWID: case OCI.DATATYPE.ROWID_DESC: case OCI.DATATYPE.UROWID: _metaType = MetaType.GetMetaTypeForType(OracleType.RowId); _byteSize = _metaType.BindSize; if (connection.UnicodeEnabled) { _bindAsUTF16 = true; _byteSize *= ADP.CharSize; // Since Oracle reported the number of characters and UTF16 characters are two bytes each, have to adjust the buffer size } needSize = true; break; case OCI.DATATYPE.BFILE: _metaType = MetaType.GetMetaTypeForType(OracleType.BFile); _byteSize = _metaType.BindSize; cannotPrefetch = true; break; case OCI.DATATYPE.BLOB: _metaType = MetaType.GetMetaTypeForType(OracleType.Blob); _byteSize = _metaType.BindSize; cannotPrefetch = true; break; case OCI.DATATYPE.CLOB: _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, out tempub1, errorHandle); _metaType = MetaType.GetMetaTypeForType((OCI.CHARSETFORM.SQLCS_NCHAR == (OCI.CHARSETFORM)tempub1) ? OracleType.NClob : OracleType.Clob); _byteSize = _metaType.BindSize; cannotPrefetch = true; break; case OCI.DATATYPE.LONG: _metaType = MetaType.GetMetaTypeForType(OracleType.LongVarChar); _byteSize = _metaType.BindSize; needSize = true; cannotPrefetch = true; _bindAsUTF16 = connection.ServerVersionAtLeastOracle8; // MDAC #79471 - Oracle7 servers don't do Unicode break; case OCI.DATATYPE.LONGRAW: _metaType = MetaType.GetMetaTypeForType(OracleType.LongRaw); _byteSize = _metaType.BindSize; needSize = true; cannotPrefetch = true; break; default: throw ADP.TypeNotSupported(ociType); } if (_isNullable) { _indicatorOffset= offset; offset += IntPtr.Size; } else { _indicatorOffset = -1; } if (needSize) { _lengthOffset = offset; offset += IntPtr.Size; } else { _lengthOffset = -1; } _valueOffset = offset; if (OCI.DATATYPE.LONG == ociType || OCI.DATATYPE.LONGRAW == ociType) { offset += IntPtr.Size; } else { offset += _byteSize; } offset = (offset + (IntPtr.Size-1)) & ~(IntPtr.Size-1); // align buffer; // We don't need this any longer, get rid of it. OciHandle.SafeDispose(ref _describeHandle); return cannotPrefetch; } internal void Dispose() { NativeBuffer.SafeDispose(ref _longBuffer); OciLobLocator.SafeDispose(ref _lobLocator); OciHandle.SafeDispose(ref _describeHandle); _columnName = null; _metaType = null; _callback = null; _connection = null; } internal void FixupLongValueLength(NativeBuffer buffer) { if (null != _longBuffer) { Debug.Assert(_metaType.IsLong, "dangling long buffer?"); // Determine the actual length of the LONG/LONG RAW data read, if we // haven't done so already. if (-1 == _longLength) { // Our "piecewise" fetching of LONG/LONG RAW data will extend the // buffer by a chunk, and ask Oracle to fill it. // Oracle calls ours _callback_GetColumnPiecewise for each new buffer. // We create different chunk for each callback call, each chunk has its own // length. // Before the fix of RFC50002189, we assumed that native Oracle driver will fill each // non-last chunk fully (with size = request one == ChunkSize),so we calculated the total // length as fixed chunk size * (num of chunks - 1) + last chunk size! // This assumption was wrong (RFC50002189) - Oracle driver can fill less data than the chunk size. // The fix for RFC50002189 includes: // * remember each chunk size separately, as part of the chunk // * calculate and fixup the total length here (as before) and update the buffer[_lengthOffset] _longLength = _longBuffer.TotalLengthInBytes; // Of course, we have to convert for character data to number of // Unicode Characters read, not number of bytes if (_bindAsUTF16) { Debug.Assert(0 == (_longLength & 0x1), "odd length unicode data?"); _longLength /= 2; } Debug.Assert(_longLength >= 0, "invalid size for LONG data?"); // Finally, we write the length back to the row buffer so we don't // have to have two code paths to construct the managed object. buffer.WriteInt32(_lengthOffset, _longLength); } } } internal string GetDataTypeName() { // Returns the name of the back-end data type. return _metaType.DataTypeName; } internal Type GetFieldType() { // Returns the actual clr type that the column is. return _metaType.BaseType; } internal Type GetFieldOracleType() { // Returns the actual oracletype that the column is. return _metaType.NoConvertType; } internal object GetValue(NativeBuffer_RowBuffer buffer) { // Returns an object that contains the value of the column in the // specified row buffer. This method returns CLS-typed objects. if (IsDBNull(buffer)) { return DBNull.Value; } //Debug.WriteLine(String.Format("{0}: {1}", _columnName, buffer.ReadInt16(_indicatorOffset+2))); switch (_metaType.OciType) { case OCI.DATATYPE.BFILE: { object value; using (OracleBFile bfile = GetOracleBFile(buffer)) { value = bfile.Value; // reading the LOB is MUCH more expensive than constructing an object we'll throw away } return value; } case OCI.DATATYPE.RAW: case OCI.DATATYPE.LONGRAW: { long length = GetBytes(buffer, 0, null, 0, 0); byte[] value = new byte[length]; GetBytes( buffer, 0, value, 0, (int)length ); return value; } case OCI.DATATYPE.DATE: case OCI.DATATYPE.INT_TIMESTAMP: case OCI.DATATYPE.INT_TIMESTAMP_TZ: case OCI.DATATYPE.INT_TIMESTAMP_LTZ: return GetDateTime( buffer ); case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: { object value; using (OracleLob lob = GetOracleLob(buffer)) { value = lob.Value; // reading the LOB is MUCH more expensive than constructing an object we'll throw away } return value; } case OCI.DATATYPE.INT_INTERVAL_YM: return GetInt32( buffer ); case OCI.DATATYPE.VARNUM: return GetDecimal( buffer ); case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: case OCI.DATATYPE.LONG: return GetString( buffer ); case OCI.DATATYPE.INT_INTERVAL_DS: return GetTimeSpan( buffer ); } throw ADP.TypeNotSupported(_metaType.OciType); } internal object GetOracleValue(NativeBuffer_RowBuffer buffer) { // Returns an object that contains the value of the column in the // specified row buffer. This method returns Oracle-typed objects. //Debug.WriteLine(String.Format("{0}: {1}", _columnName, buffer.ReadInt16(_indicatorOffset+2))); switch (_metaType.OciType) { case OCI.DATATYPE.BFILE: return GetOracleBFile( buffer ); case OCI.DATATYPE.RAW: case OCI.DATATYPE.LONGRAW: return GetOracleBinary( buffer ); case OCI.DATATYPE.DATE: case OCI.DATATYPE.INT_TIMESTAMP: case OCI.DATATYPE.INT_TIMESTAMP_TZ: case OCI.DATATYPE.INT_TIMESTAMP_LTZ: return GetOracleDateTime( buffer ); case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: return GetOracleLob( buffer ); case OCI.DATATYPE.INT_INTERVAL_YM: return GetOracleMonthSpan( buffer ); case OCI.DATATYPE.VARNUM: return GetOracleNumber( buffer ); case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: case OCI.DATATYPE.LONG: return GetOracleString( buffer ); case OCI.DATATYPE.INT_INTERVAL_DS: return GetOracleTimeSpan( buffer ); } throw ADP.TypeNotSupported(_metaType.OciType); } //--------------------------------------------------------------------- // Get // // Returns an the value of the column in the specified row buffer as // the appropriate type // internal long GetBytes( NativeBuffer_RowBuffer buffer, long fieldOffset, byte[] destinationBuffer, int destinationOffset, int length ) { if (length < 0) { // MDAC 71007 throw ADP.InvalidDataLength(length); } if ((destinationOffset < 0) || (null != destinationBuffer && destinationOffset >= destinationBuffer.Length)) { // MDAC 71013 throw ADP.InvalidDestinationBufferIndex(destinationBuffer.Length, destinationOffset, "bufferoffset"); // NOTE: Name matches public object model OracleDataReader.GetBytes() } if (0 > fieldOffset || UInt32.MaxValue < fieldOffset) { throw ADP.InvalidSourceOffset("fieldOffset", 0, UInt32.MaxValue); } int byteCount; if (IsLob) { OracleType lobType = _metaType.OracleType; if (OracleType.Blob != lobType && OracleType.BFile != lobType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } using (OracleLob lob = new OracleLob(_lobLocator)) { uint valueLength = (uint)lob.Length; uint sourceOffset = (uint) fieldOffset; if (sourceOffset > valueLength) { // MDAC 72830 throw ADP.InvalidSourceBufferIndex((int)valueLength, (int)sourceOffset, "fieldOffset"); // NOTE: Name matches public object model OracleDataReader.GetBytes() } byteCount = (int)(valueLength - sourceOffset); if (null != destinationBuffer) { byteCount = Math.Min(byteCount, length); if (0 < byteCount) { lob.Seek(sourceOffset,SeekOrigin.Begin); lob.Read(destinationBuffer, destinationOffset, byteCount); } } } } else { if (OracleType.Raw != OracleType && OracleType.LongRaw != OracleType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } FixupLongValueLength(buffer); int valueLength = OracleBinary.GetLength(buffer, _lengthOffset, _metaType); int sourceOffset = (int) fieldOffset; byteCount = valueLength - sourceOffset; if (null != destinationBuffer) { byteCount = Math.Min(byteCount, length); if (0 < byteCount) { OracleBinary.GetBytes(buffer, _valueOffset, _metaType, sourceOffset, destinationBuffer, destinationOffset, byteCount); } } } return Math.Max(0,byteCount); } internal long GetChars(NativeBuffer_RowBuffer buffer, long fieldOffset, char[] destinationBuffer, int destinationOffset, int length) { if (length < 0) { // MDAC 71007 throw ADP.InvalidDataLength(length); } if ((destinationOffset < 0) || (null != destinationBuffer && destinationOffset >= destinationBuffer.Length)) { // MDAC 71013 throw ADP.InvalidDestinationBufferIndex(destinationBuffer.Length, destinationOffset, "bufferoffset"); // NOTE: Name matches public object model OracleDataReader.GetChars() } if (0 > fieldOffset || UInt32.MaxValue < fieldOffset) { throw ADP.InvalidSourceOffset("fieldOffset", 0, UInt32.MaxValue); } int charCount; if (IsLob) { OracleType lobType = _metaType.OracleType; if (OracleType.Clob != lobType && OracleType.NClob != lobType && OracleType.BFile != lobType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } using (OracleLob lob = new OracleLob(_lobLocator)) { string s = (string)lob.Value; int valueLength = s.Length; int sourceOffset = (int) fieldOffset; if (sourceOffset < 0) { // MDAC 72830 throw ADP.InvalidSourceBufferIndex(valueLength, sourceOffset, "fieldOffset"); // NOTE: Name matches public object model OracleDataReader.GetChars() } charCount = (int)(valueLength - sourceOffset); if (null != destinationBuffer) { charCount = Math.Min(charCount, length); if (0 < charCount) { char[] result = s.ToCharArray(sourceOffset, charCount); Buffer.BlockCopy(result, 0, destinationBuffer, destinationOffset, charCount); } } } } else { if (OracleType.Char != OracleType && OracleType.VarChar != OracleType && OracleType.LongVarChar != OracleType && OracleType.NChar != OracleType && OracleType.NVarChar != OracleType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } FixupLongValueLength(buffer); int valueLength = OracleString.GetLength(buffer, _lengthOffset, _metaType); int sourceOffset = (int) fieldOffset; charCount = valueLength - sourceOffset; if (null != destinationBuffer) { charCount = Math.Min(charCount, length); if (0 < charCount) { OracleString.GetChars(buffer, _valueOffset, _lengthOffset, _metaType, _connection, _bindAsUTF16, sourceOffset, destinationBuffer, destinationOffset, charCount); } } } return Math.Max(0,charCount); } internal DateTime GetDateTime(NativeBuffer_RowBuffer buffer) { if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } if (typeof(DateTime) != _metaType.BaseType) { throw ADP.InvalidCast(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); DateTime result = OracleDateTime.MarshalToDateTime(buffer, _valueOffset, _lengthOffset, _metaType, _connection); return result; } internal decimal GetDecimal(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); decimal result = OracleNumber.MarshalToDecimal(buffer, _valueOffset, _connection); return result; } internal double GetDouble(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); decimal decimalValue = OracleNumber.MarshalToDecimal(buffer, _valueOffset, _connection); double result = (double)decimalValue; return result; } internal float GetFloat(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); decimal decimalValue = OracleNumber.MarshalToDecimal(buffer, _valueOffset, _connection); float result = (float)decimalValue; return result; } internal int GetInt32(NativeBuffer_RowBuffer buffer) { if (typeof(int) != _metaType.BaseType && typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); int result; if (typeof(int) == _metaType.BaseType) { result = OracleMonthSpan.MarshalToInt32(buffer, _valueOffset); } else { result = OracleNumber.MarshalToInt32(buffer, _valueOffset, _connection); } return result; } internal Int64 GetInt64(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); Int64 result = OracleNumber.MarshalToInt64(buffer, _valueOffset, _connection); return result; } internal string GetString(NativeBuffer_RowBuffer buffer) { if (IsLob) { OracleType lobType = _metaType.OracleType; if (OracleType.Clob != lobType && OracleType.NClob != lobType && OracleType.BFile != lobType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } string result; using (OracleLob lob = new OracleLob(_lobLocator)) { result = (string)lob.Value; } return result; } else { if (typeof(string) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } FixupLongValueLength(buffer); string result = OracleString.MarshalToString(buffer, _valueOffset, _lengthOffset, _metaType, _connection, _bindAsUTF16, false); return result; } } internal TimeSpan GetTimeSpan(NativeBuffer_RowBuffer buffer) { if (typeof(TimeSpan) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); TimeSpan result = OracleTimeSpan.MarshalToTimeSpan(buffer, _valueOffset); return result; } internal OracleBFile GetOracleBFile(NativeBuffer_RowBuffer buffer) { Debug.Assert(null == _longBuffer, "dangling long buffer?"); if (typeof(OracleBFile) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleBFile.Null; } OracleBFile result = new OracleBFile(_lobLocator); return result; } internal OracleBinary GetOracleBinary(NativeBuffer_RowBuffer buffer) { if (typeof(OracleBinary) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } FixupLongValueLength(buffer); if (IsDBNull(buffer)) { return OracleBinary.Null; } OracleBinary result = new OracleBinary(buffer, _valueOffset, _lengthOffset, _metaType); return result; } internal OracleDateTime GetOracleDateTime(NativeBuffer_RowBuffer buffer) { if (typeof(OracleDateTime) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleDateTime.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleDateTime result = new OracleDateTime(buffer, _valueOffset, _lengthOffset, _metaType, _connection); return result; } internal OracleLob GetOracleLob(NativeBuffer_RowBuffer buffer) { if (typeof(OracleLob) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleLob.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleLob result = new OracleLob(_lobLocator); return result; } internal OracleMonthSpan GetOracleMonthSpan(NativeBuffer_RowBuffer buffer) { if (typeof(OracleMonthSpan) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleMonthSpan.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleMonthSpan result = new OracleMonthSpan(buffer, _valueOffset); return result; } internal OracleNumber GetOracleNumber(NativeBuffer_RowBuffer buffer) { if (typeof(OracleNumber) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleNumber.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleNumber result = new OracleNumber(buffer, _valueOffset); return result; } internal OracleString GetOracleString(NativeBuffer_RowBuffer buffer) { if (typeof(OracleString) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleString.Null; } FixupLongValueLength(buffer); OracleString result = new OracleString(buffer, _valueOffset, _lengthOffset, _metaType, _connection, _bindAsUTF16, false); return result; } internal OracleTimeSpan GetOracleTimeSpan(NativeBuffer_RowBuffer buffer) { if (typeof(OracleTimeSpan) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleTimeSpan.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleTimeSpan result = new OracleTimeSpan(buffer, _valueOffset); return result; } internal bool IsDBNull(NativeBuffer_RowBuffer buffer) { // Returns true if the column value in the buffer is null. return (_isNullable && buffer.ReadInt16(_indicatorOffset) == (Int16)OCI.INDICATOR.ISNULL); } internal void Rebind(OracleConnection connection, ref bool mustRelease, ref SafeHandle handleToBind) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: You must have called DangerousAddRef on the buffer before // calling this method, or you run the risk of allowing Handle // Recycling to occur! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Here's the hook that gets called whenever we're about to fetch // a new row, allowing us to reset any information that we shouldn't // carry forward. handleToBind = null; switch (_metaType.OciType) { case OCI.DATATYPE.LONG: case OCI.DATATYPE.LONGRAW: _rowBuffer.WriteInt32(_lengthOffset, 0); _longLength = -1; // reset the length to unknown; if (null != _longBuffer) { _longBuffer.Reset(); // free all the memory we allocated, except the initial one } else { _longBuffer = new NativeBuffer_LongColumnData(); } handleToBind = _longBuffer; break; case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: case OCI.DATATYPE.BFILE: OciLobLocator.SafeDispose(ref _lobLocator); _lobLocator = new OciLobLocator(connection, _metaType.OracleType); handleToBind = _lobLocator.Descriptor; break; } // We need to add-ref the handle so it can't be released somehow // by another thread while we're fetching. Only after we do that // can we write it to the buffer for the Oracle to use during the // Fetch. The caller is required to provide storage for the // handleToBind and ensure that the DangerousRelease is called // in it's CER. if (null != handleToBind) { handleToBind.DangerousAddRef(ref mustRelease); _rowBuffer.WriteIntPtr(_valueOffset, handleToBind.DangerousGetHandle()); } } }; } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.OracleClient { using System; using System.Data; using System.Data.Common; using System.Diagnostics; using System.IO; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Text; //--------------------------------------------------------------------- // OracleColumn // // Contains all the information about a single column in a result set, // and implements the methods necessary to describe column to Oracle // and to extract the column data from the native buffer used to fetch // it. // sealed internal class OracleColumn { private OciParameterDescriptor _describeHandle; // the Describe handle private int _ordinal; // the ordinal position in the rowset (0..n-1) private string _columnName; // the name of the column private MetaType _metaType; private byte _precision; // precision of the column (OracleNumber only) private byte _scale; // scale of the column (OracleNumber only) private int _byteSize; // how many bytes we need in the row buffer private bool _isNullable; // whether the value is nullable or not. private int _indicatorOffset; // offset from the start of the row buffer to the indicator binding (see OCI.INDICATOR) private int _lengthOffset; // offset from the start of the row buffer to the length binding private int _valueOffset; // offset from the start of the row buffer to the value binding private NativeBuffer_RowBuffer _rowBuffer; // the row buffer we're bound to (reused for all rows fetched) private NativeBuffer_LongColumnData _longBuffer;// the out-of-line buffer used for piecewise binding; must be reset for each new fetch. private int _longLength; // the length of the data we actually fetched into _longBuffer private OCI.Callback.OCICallbackDefine _callback;// the piecewise binding callback for this column private OciLobLocator _lobLocator; // the descriptor allocated for LOB columns private OracleConnection _connection; // the connection the column is on (LOB columns only) private int _connectionCloseCount; // The close count of the connection; used to decide if we're zombied private bool _bindAsUTF16; // true whenever we're binding character data as Unicode... // Construct by getting the specified describe handle from the specified statement handle internal OracleColumn(OciStatementHandle statementHandle, int ordinal, OciErrorHandle errorHandle, OracleConnection connection) { _ordinal = ordinal; _describeHandle = statementHandle.GetDescriptor(_ordinal, errorHandle);; _connection = connection; _connectionCloseCount = connection.CloseCount; } internal string ColumnName { get { return _columnName; } } internal bool IsNullable { get { return _isNullable; } } internal bool IsLob { get { return _metaType.IsLob; } } internal bool IsLong { get { return _metaType.IsLong; } } internal OracleType OracleType { get { return _metaType.OracleType; } } internal int Ordinal { get { return _ordinal; } } internal byte Precision { get { return _precision; } } internal byte Scale { get { return _scale; } } // This is the value used for the SchemaTable, which must be Chars... internal int SchemaTableSize { get { return (_bindAsUTF16 && !_metaType.IsLong)?_byteSize/2:_byteSize; } } private int _callback_GetColumnPiecewise( IntPtr octxp, IntPtr defnp, uint iter, IntPtr bufpp, // dvoid** IntPtr alenp, // ub4** IntPtr piecep, // ub1* IntPtr indpp, // dvoid** IntPtr rcodep // ub2** ) { // Callback routine for Dynamic Binding column values from Oracle: tell // Oracle where to stuff the data. if (Bid.AdvancedOn) Bid.Trace("" +" octxp=0x%-07Ix" +" defnp=0x%-07Ix" +" iter=%-2d" +" bufpp=0x%-07Ix" +" alenp=0x%-07Ix" +" piecep=0x%-07Ix" +" indpp=0x%-07Ix" +" rcodep=0x%-07Ix\n", octxp, defnp, unchecked((int)iter), // tracing -- I don't care about overflow. bufpp, alenp, piecep, indpp, rcodep ); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: THIS IS A CALLBACK FUNCTION FROM AN OCI PINVOKE! // Namely, OCIStmtFetch. We expect that you will have called // DangerousAddRef on the _rowBuffer and the _longBuffer // SafeHandles, to prevent any Handle Recycling from occurring. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // RFC50002189 - chunk length is saved as part of chunk's buffer // later, when the LONG field value is requested, TotalLength is used // to sum the lengths and the result is writtent into buffer[_lengthOffset], as before the change IntPtr lengthPtr; IntPtr indicatorPtr = (-1 != _indicatorOffset) ? _rowBuffer.DangerousGetDataPtr(_indicatorOffset) : IntPtr.Zero; IntPtr valuePtr = _longBuffer.GetChunk(out lengthPtr); Marshal.WriteIntPtr(bufpp, valuePtr); // *bufpp Marshal.WriteIntPtr(indpp, indicatorPtr); // *indpp Marshal.WriteIntPtr(alenp, lengthPtr); // *alenp // provide the size of allocated buffer, in bytes, to Oracle driver // on output, we will receive from Oracle driver the length of filled buffer, in bytes Marshal.WriteInt32(lengthPtr, NativeBuffer_LongColumnData.MaxChunkSize); // **alenp GC.KeepAlive(this); return (int)OCI.RETURNCODE.OCI_CONTINUE; } internal void Bind(OciStatementHandle statementHandle, NativeBuffer_RowBuffer buffer, OciErrorHandle errorHandle, int rowBufferLength) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: You must have called DangerousAddRef on the buffer before // calling this method, or you run the risk of allowing Handle // Recycling to occur! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Binds the buffer for the column to the statement handle specified. OciDefineHandle defineHandle = null; IntPtr h; OCI.MODE mode = OCI.MODE.OCI_DEFAULT; int bindByteSize; OCI.DATATYPE ociType = _metaType.OciType; _rowBuffer = buffer; if (_metaType.IsLong) { mode = OCI.MODE.OCI_DYNAMIC_FETCH; bindByteSize = Int32.MaxValue; } else { bindByteSize = _byteSize; } IntPtr indicatorLocation = IntPtr.Zero; IntPtr lengthLocation = IntPtr.Zero; IntPtr valueLocation = _rowBuffer.DangerousGetDataPtr(_valueOffset); if (-1 != _indicatorOffset) { indicatorLocation = _rowBuffer.DangerousGetDataPtr(_indicatorOffset); } if (-1 != _lengthOffset && !_metaType.IsLong) { lengthLocation = _rowBuffer.DangerousGetDataPtr(_lengthOffset); } try { int rc = TracedNativeMethods.OCIDefineByPos( statementHandle, // hndlp out h, // defnpp errorHandle, // errhp checked((uint)_ordinal+1), // position valueLocation, // valuep bindByteSize, // value_sz ociType, // htype indicatorLocation, // indp, lengthLocation, // rlenp, IntPtr.Zero, // rcodep, mode // mode ); if (rc != 0) { _connection.CheckError(errorHandle, rc); } defineHandle = new OciDefineHandle(statementHandle, h); if (0 != rowBufferLength) { uint valOffset = checked((uint)rowBufferLength); uint indOffset = (-1 != _indicatorOffset) ? valOffset : 0; uint lenOffset = (-1 != _lengthOffset && !_metaType.IsLong) ? valOffset : 0; rc = TracedNativeMethods.OCIDefineArrayOfStruct( defineHandle, errorHandle, valOffset, indOffset, lenOffset, 0 // never use rcodep above... ); if (rc != 0) { _connection.CheckError(errorHandle, rc); } } if (_metaType.UsesNationalCharacterSet) { Debug.Assert(!_metaType.IsLong, "LONG data may never be bound as NCHAR"); // NOTE: the order is important here; setting charsetForm will // reset charsetId (I found this out the hard way...) defineHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, (int)OCI.CHARSETFORM.SQLCS_NCHAR, errorHandle); } if (!_connection.UnicodeEnabled) { if (_bindAsUTF16) { // NOTE: the order is important here; setting charsetForm will // reset charsetId (I found this out the hard way...) defineHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_ID, (short)OCI.CHARSETID.OCI_UTF16ID, errorHandle); } } if (_metaType.IsLong) { // Initialize the longBuffer in the rowBuffer to null _rowBuffer.WriteIntPtr(_valueOffset, IntPtr.Zero); _callback = new OCI.Callback.OCICallbackDefine(_callback_GetColumnPiecewise); rc = TracedNativeMethods.OCIDefineDynamic( defineHandle, // defnp errorHandle, // errhp IntPtr.Zero, // dvoid *octxp, _callback // OCICallbackDefine ocbfp ); if (rc != 0) { _connection.CheckError(errorHandle, rc); } } } finally { // We don't need these any longer, get rid of it. NativeBuffer.SafeDispose(ref _longBuffer); OciHandle.SafeDispose(ref defineHandle); } } internal bool Describe(ref int offset, OracleConnection connection, OciErrorHandle errorHandle) { // Gets all of the column description information from the describe // handle. In addition, we'll determine the position of the column // in the rowbuffer, based upon the offset parameter, which is passed // by ref so we can adjust the end position accordingly. short tempub2; byte tempub1; OCI.DATATYPE ociType; bool needSize = false; bool cannotPrefetch = false; _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_NAME, out _columnName,errorHandle, _connection); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_DATA_TYPE, out tempub2, errorHandle); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_IS_NULL, out tempub1, errorHandle); _isNullable = (0 != tempub1); ociType = (OCI.DATATYPE)tempub2; switch (ociType) { case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_DATA_SIZE, out _byteSize, errorHandle); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM,out tempub1, errorHandle); OCI.CHARSETFORM charsetForm = (OCI.CHARSETFORM)tempub1; _bindAsUTF16 = connection.ServerVersionAtLeastOracle8; // SQLBUVSTS 217686: the _byteSize we have is size, in bytes, of the string in its server representation. This size can be // less than the buffer size we need to fetch the UTF16 chars for the same string which can result in // either silent data truncation or ORA-01406 exception of Oracle. // To calculate the byte size for UTF16 characters, we query for the size in UTF16 characters using // OCI_ATTR_CHAR_SIZE and double it (1 UTF16 char == 2 bytes). int charSize; // according to Oracle's documentation, OCI_ATTR_CHAR_SIZE is supported only if both client and server >= 9 if (connection.ServerVersionAtLeastOracle9i && OCI.ClientVersionAtLeastOracle9i) { // we can query for the char size since both client and server versions are >= 9 _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHAR_SIZE, out tempub2, errorHandle); charSize = tempub2; } else { // if either client or server is 8 or less, we cannot use OCI_ATTR_CHAR_SIZE attribute // in that case, we assume the worse scenario: max number of characters is same or less as number of bytes used to encode it // (which is true in all NLS languages and UTF* encodings). // we could query for OCI_ATTR_CHARSET_ID and calculate the max size with better efficiency, but this would // complicate the calcs thus making the fix risky and prone for regressions. charSize = _byteSize; } if (charsetForm == OCI.CHARSETFORM.SQLCS_NCHAR) { // National Character Set _metaType = MetaType.GetMetaTypeForType((OCI.DATATYPE.CHAR == ociType) ? OracleType.NChar : OracleType.NVarChar); } else { // Database Character Set _metaType = MetaType.GetMetaTypeForType((OCI.DATATYPE.CHAR == ociType) ? OracleType.Char : OracleType.VarChar); if (_bindAsUTF16) { // we deal only with UTF16 so get the size required to store same number of UTF16 chars _byteSize *= ADP.CharSize; } } // To fetch the data, we have to specify size in bytes. // To be on the safe side and avoid regressions, select the max between the size as it // is encoded on the server and the size we've calculated above. _byteSize = Math.Max(_byteSize, charSize * ADP.CharSize); needSize = true; break; case OCI.DATATYPE.DATE: _metaType = MetaType.GetMetaTypeForType(OracleType.DateTime); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.TIMESTAMP: _metaType = MetaType.GetMetaTypeForType(OracleType.Timestamp); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.TIMESTAMP_LTZ: _metaType = MetaType.GetMetaTypeForType(OracleType.TimestampLocal); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.TIMESTAMP_TZ: _metaType = MetaType.GetMetaTypeForType(OracleType.TimestampWithTZ); _byteSize = _metaType.BindSize; needSize = true; break; case OCI.DATATYPE.INTERVAL_YM: _metaType = MetaType.GetMetaTypeForType(OracleType.IntervalYearToMonth); _byteSize = _metaType.BindSize; break; case OCI.DATATYPE.INTERVAL_DS: _metaType = MetaType.GetMetaTypeForType(OracleType.IntervalDayToSecond); _byteSize = _metaType.BindSize; break; case OCI.DATATYPE.NUMBER: _metaType = MetaType.GetMetaTypeForType(OracleType.Number); _byteSize = _metaType.BindSize; _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_PRECISION, out _precision, errorHandle); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_SCALE, out _scale, errorHandle); break; case OCI.DATATYPE.RAW: _metaType = MetaType.GetMetaTypeForType(OracleType.Raw); _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_DATA_SIZE, out _byteSize, errorHandle); needSize = true; break; case OCI.DATATYPE.ROWID: case OCI.DATATYPE.ROWID_DESC: case OCI.DATATYPE.UROWID: _metaType = MetaType.GetMetaTypeForType(OracleType.RowId); _byteSize = _metaType.BindSize; if (connection.UnicodeEnabled) { _bindAsUTF16 = true; _byteSize *= ADP.CharSize; // Since Oracle reported the number of characters and UTF16 characters are two bytes each, have to adjust the buffer size } needSize = true; break; case OCI.DATATYPE.BFILE: _metaType = MetaType.GetMetaTypeForType(OracleType.BFile); _byteSize = _metaType.BindSize; cannotPrefetch = true; break; case OCI.DATATYPE.BLOB: _metaType = MetaType.GetMetaTypeForType(OracleType.Blob); _byteSize = _metaType.BindSize; cannotPrefetch = true; break; case OCI.DATATYPE.CLOB: _describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, out tempub1, errorHandle); _metaType = MetaType.GetMetaTypeForType((OCI.CHARSETFORM.SQLCS_NCHAR == (OCI.CHARSETFORM)tempub1) ? OracleType.NClob : OracleType.Clob); _byteSize = _metaType.BindSize; cannotPrefetch = true; break; case OCI.DATATYPE.LONG: _metaType = MetaType.GetMetaTypeForType(OracleType.LongVarChar); _byteSize = _metaType.BindSize; needSize = true; cannotPrefetch = true; _bindAsUTF16 = connection.ServerVersionAtLeastOracle8; // MDAC #79471 - Oracle7 servers don't do Unicode break; case OCI.DATATYPE.LONGRAW: _metaType = MetaType.GetMetaTypeForType(OracleType.LongRaw); _byteSize = _metaType.BindSize; needSize = true; cannotPrefetch = true; break; default: throw ADP.TypeNotSupported(ociType); } if (_isNullable) { _indicatorOffset= offset; offset += IntPtr.Size; } else { _indicatorOffset = -1; } if (needSize) { _lengthOffset = offset; offset += IntPtr.Size; } else { _lengthOffset = -1; } _valueOffset = offset; if (OCI.DATATYPE.LONG == ociType || OCI.DATATYPE.LONGRAW == ociType) { offset += IntPtr.Size; } else { offset += _byteSize; } offset = (offset + (IntPtr.Size-1)) & ~(IntPtr.Size-1); // align buffer; // We don't need this any longer, get rid of it. OciHandle.SafeDispose(ref _describeHandle); return cannotPrefetch; } internal void Dispose() { NativeBuffer.SafeDispose(ref _longBuffer); OciLobLocator.SafeDispose(ref _lobLocator); OciHandle.SafeDispose(ref _describeHandle); _columnName = null; _metaType = null; _callback = null; _connection = null; } internal void FixupLongValueLength(NativeBuffer buffer) { if (null != _longBuffer) { Debug.Assert(_metaType.IsLong, "dangling long buffer?"); // Determine the actual length of the LONG/LONG RAW data read, if we // haven't done so already. if (-1 == _longLength) { // Our "piecewise" fetching of LONG/LONG RAW data will extend the // buffer by a chunk, and ask Oracle to fill it. // Oracle calls ours _callback_GetColumnPiecewise for each new buffer. // We create different chunk for each callback call, each chunk has its own // length. // Before the fix of RFC50002189, we assumed that native Oracle driver will fill each // non-last chunk fully (with size = request one == ChunkSize),so we calculated the total // length as fixed chunk size * (num of chunks - 1) + last chunk size! // This assumption was wrong (RFC50002189) - Oracle driver can fill less data than the chunk size. // The fix for RFC50002189 includes: // * remember each chunk size separately, as part of the chunk // * calculate and fixup the total length here (as before) and update the buffer[_lengthOffset] _longLength = _longBuffer.TotalLengthInBytes; // Of course, we have to convert for character data to number of // Unicode Characters read, not number of bytes if (_bindAsUTF16) { Debug.Assert(0 == (_longLength & 0x1), "odd length unicode data?"); _longLength /= 2; } Debug.Assert(_longLength >= 0, "invalid size for LONG data?"); // Finally, we write the length back to the row buffer so we don't // have to have two code paths to construct the managed object. buffer.WriteInt32(_lengthOffset, _longLength); } } } internal string GetDataTypeName() { // Returns the name of the back-end data type. return _metaType.DataTypeName; } internal Type GetFieldType() { // Returns the actual clr type that the column is. return _metaType.BaseType; } internal Type GetFieldOracleType() { // Returns the actual oracletype that the column is. return _metaType.NoConvertType; } internal object GetValue(NativeBuffer_RowBuffer buffer) { // Returns an object that contains the value of the column in the // specified row buffer. This method returns CLS-typed objects. if (IsDBNull(buffer)) { return DBNull.Value; } //Debug.WriteLine(String.Format("{0}: {1}", _columnName, buffer.ReadInt16(_indicatorOffset+2))); switch (_metaType.OciType) { case OCI.DATATYPE.BFILE: { object value; using (OracleBFile bfile = GetOracleBFile(buffer)) { value = bfile.Value; // reading the LOB is MUCH more expensive than constructing an object we'll throw away } return value; } case OCI.DATATYPE.RAW: case OCI.DATATYPE.LONGRAW: { long length = GetBytes(buffer, 0, null, 0, 0); byte[] value = new byte[length]; GetBytes( buffer, 0, value, 0, (int)length ); return value; } case OCI.DATATYPE.DATE: case OCI.DATATYPE.INT_TIMESTAMP: case OCI.DATATYPE.INT_TIMESTAMP_TZ: case OCI.DATATYPE.INT_TIMESTAMP_LTZ: return GetDateTime( buffer ); case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: { object value; using (OracleLob lob = GetOracleLob(buffer)) { value = lob.Value; // reading the LOB is MUCH more expensive than constructing an object we'll throw away } return value; } case OCI.DATATYPE.INT_INTERVAL_YM: return GetInt32( buffer ); case OCI.DATATYPE.VARNUM: return GetDecimal( buffer ); case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: case OCI.DATATYPE.LONG: return GetString( buffer ); case OCI.DATATYPE.INT_INTERVAL_DS: return GetTimeSpan( buffer ); } throw ADP.TypeNotSupported(_metaType.OciType); } internal object GetOracleValue(NativeBuffer_RowBuffer buffer) { // Returns an object that contains the value of the column in the // specified row buffer. This method returns Oracle-typed objects. //Debug.WriteLine(String.Format("{0}: {1}", _columnName, buffer.ReadInt16(_indicatorOffset+2))); switch (_metaType.OciType) { case OCI.DATATYPE.BFILE: return GetOracleBFile( buffer ); case OCI.DATATYPE.RAW: case OCI.DATATYPE.LONGRAW: return GetOracleBinary( buffer ); case OCI.DATATYPE.DATE: case OCI.DATATYPE.INT_TIMESTAMP: case OCI.DATATYPE.INT_TIMESTAMP_TZ: case OCI.DATATYPE.INT_TIMESTAMP_LTZ: return GetOracleDateTime( buffer ); case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: return GetOracleLob( buffer ); case OCI.DATATYPE.INT_INTERVAL_YM: return GetOracleMonthSpan( buffer ); case OCI.DATATYPE.VARNUM: return GetOracleNumber( buffer ); case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: case OCI.DATATYPE.LONG: return GetOracleString( buffer ); case OCI.DATATYPE.INT_INTERVAL_DS: return GetOracleTimeSpan( buffer ); } throw ADP.TypeNotSupported(_metaType.OciType); } //--------------------------------------------------------------------- // Get // // Returns an the value of the column in the specified row buffer as // the appropriate type // internal long GetBytes( NativeBuffer_RowBuffer buffer, long fieldOffset, byte[] destinationBuffer, int destinationOffset, int length ) { if (length < 0) { // MDAC 71007 throw ADP.InvalidDataLength(length); } if ((destinationOffset < 0) || (null != destinationBuffer && destinationOffset >= destinationBuffer.Length)) { // MDAC 71013 throw ADP.InvalidDestinationBufferIndex(destinationBuffer.Length, destinationOffset, "bufferoffset"); // NOTE: Name matches public object model OracleDataReader.GetBytes() } if (0 > fieldOffset || UInt32.MaxValue < fieldOffset) { throw ADP.InvalidSourceOffset("fieldOffset", 0, UInt32.MaxValue); } int byteCount; if (IsLob) { OracleType lobType = _metaType.OracleType; if (OracleType.Blob != lobType && OracleType.BFile != lobType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } using (OracleLob lob = new OracleLob(_lobLocator)) { uint valueLength = (uint)lob.Length; uint sourceOffset = (uint) fieldOffset; if (sourceOffset > valueLength) { // MDAC 72830 throw ADP.InvalidSourceBufferIndex((int)valueLength, (int)sourceOffset, "fieldOffset"); // NOTE: Name matches public object model OracleDataReader.GetBytes() } byteCount = (int)(valueLength - sourceOffset); if (null != destinationBuffer) { byteCount = Math.Min(byteCount, length); if (0 < byteCount) { lob.Seek(sourceOffset,SeekOrigin.Begin); lob.Read(destinationBuffer, destinationOffset, byteCount); } } } } else { if (OracleType.Raw != OracleType && OracleType.LongRaw != OracleType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } FixupLongValueLength(buffer); int valueLength = OracleBinary.GetLength(buffer, _lengthOffset, _metaType); int sourceOffset = (int) fieldOffset; byteCount = valueLength - sourceOffset; if (null != destinationBuffer) { byteCount = Math.Min(byteCount, length); if (0 < byteCount) { OracleBinary.GetBytes(buffer, _valueOffset, _metaType, sourceOffset, destinationBuffer, destinationOffset, byteCount); } } } return Math.Max(0,byteCount); } internal long GetChars(NativeBuffer_RowBuffer buffer, long fieldOffset, char[] destinationBuffer, int destinationOffset, int length) { if (length < 0) { // MDAC 71007 throw ADP.InvalidDataLength(length); } if ((destinationOffset < 0) || (null != destinationBuffer && destinationOffset >= destinationBuffer.Length)) { // MDAC 71013 throw ADP.InvalidDestinationBufferIndex(destinationBuffer.Length, destinationOffset, "bufferoffset"); // NOTE: Name matches public object model OracleDataReader.GetChars() } if (0 > fieldOffset || UInt32.MaxValue < fieldOffset) { throw ADP.InvalidSourceOffset("fieldOffset", 0, UInt32.MaxValue); } int charCount; if (IsLob) { OracleType lobType = _metaType.OracleType; if (OracleType.Clob != lobType && OracleType.NClob != lobType && OracleType.BFile != lobType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } using (OracleLob lob = new OracleLob(_lobLocator)) { string s = (string)lob.Value; int valueLength = s.Length; int sourceOffset = (int) fieldOffset; if (sourceOffset < 0) { // MDAC 72830 throw ADP.InvalidSourceBufferIndex(valueLength, sourceOffset, "fieldOffset"); // NOTE: Name matches public object model OracleDataReader.GetChars() } charCount = (int)(valueLength - sourceOffset); if (null != destinationBuffer) { charCount = Math.Min(charCount, length); if (0 < charCount) { char[] result = s.ToCharArray(sourceOffset, charCount); Buffer.BlockCopy(result, 0, destinationBuffer, destinationOffset, charCount); } } } } else { if (OracleType.Char != OracleType && OracleType.VarChar != OracleType && OracleType.LongVarChar != OracleType && OracleType.NChar != OracleType && OracleType.NVarChar != OracleType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } FixupLongValueLength(buffer); int valueLength = OracleString.GetLength(buffer, _lengthOffset, _metaType); int sourceOffset = (int) fieldOffset; charCount = valueLength - sourceOffset; if (null != destinationBuffer) { charCount = Math.Min(charCount, length); if (0 < charCount) { OracleString.GetChars(buffer, _valueOffset, _lengthOffset, _metaType, _connection, _bindAsUTF16, sourceOffset, destinationBuffer, destinationOffset, charCount); } } } return Math.Max(0,charCount); } internal DateTime GetDateTime(NativeBuffer_RowBuffer buffer) { if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } if (typeof(DateTime) != _metaType.BaseType) { throw ADP.InvalidCast(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); DateTime result = OracleDateTime.MarshalToDateTime(buffer, _valueOffset, _lengthOffset, _metaType, _connection); return result; } internal decimal GetDecimal(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); decimal result = OracleNumber.MarshalToDecimal(buffer, _valueOffset, _connection); return result; } internal double GetDouble(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); decimal decimalValue = OracleNumber.MarshalToDecimal(buffer, _valueOffset, _connection); double result = (double)decimalValue; return result; } internal float GetFloat(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); decimal decimalValue = OracleNumber.MarshalToDecimal(buffer, _valueOffset, _connection); float result = (float)decimalValue; return result; } internal int GetInt32(NativeBuffer_RowBuffer buffer) { if (typeof(int) != _metaType.BaseType && typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); int result; if (typeof(int) == _metaType.BaseType) { result = OracleMonthSpan.MarshalToInt32(buffer, _valueOffset); } else { result = OracleNumber.MarshalToInt32(buffer, _valueOffset, _connection); } return result; } internal Int64 GetInt64(NativeBuffer_RowBuffer buffer) { if (typeof(decimal) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); Int64 result = OracleNumber.MarshalToInt64(buffer, _valueOffset, _connection); return result; } internal string GetString(NativeBuffer_RowBuffer buffer) { if (IsLob) { OracleType lobType = _metaType.OracleType; if (OracleType.Clob != lobType && OracleType.NClob != lobType && OracleType.BFile != lobType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } string result; using (OracleLob lob = new OracleLob(_lobLocator)) { result = (string)lob.Value; } return result; } else { if (typeof(string) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } FixupLongValueLength(buffer); string result = OracleString.MarshalToString(buffer, _valueOffset, _lengthOffset, _metaType, _connection, _bindAsUTF16, false); return result; } } internal TimeSpan GetTimeSpan(NativeBuffer_RowBuffer buffer) { if (typeof(TimeSpan) != _metaType.BaseType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { throw ADP.DataReaderNoData(); } Debug.Assert(null == _longBuffer, "dangling long buffer?"); TimeSpan result = OracleTimeSpan.MarshalToTimeSpan(buffer, _valueOffset); return result; } internal OracleBFile GetOracleBFile(NativeBuffer_RowBuffer buffer) { Debug.Assert(null == _longBuffer, "dangling long buffer?"); if (typeof(OracleBFile) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleBFile.Null; } OracleBFile result = new OracleBFile(_lobLocator); return result; } internal OracleBinary GetOracleBinary(NativeBuffer_RowBuffer buffer) { if (typeof(OracleBinary) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } FixupLongValueLength(buffer); if (IsDBNull(buffer)) { return OracleBinary.Null; } OracleBinary result = new OracleBinary(buffer, _valueOffset, _lengthOffset, _metaType); return result; } internal OracleDateTime GetOracleDateTime(NativeBuffer_RowBuffer buffer) { if (typeof(OracleDateTime) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleDateTime.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleDateTime result = new OracleDateTime(buffer, _valueOffset, _lengthOffset, _metaType, _connection); return result; } internal OracleLob GetOracleLob(NativeBuffer_RowBuffer buffer) { if (typeof(OracleLob) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleLob.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleLob result = new OracleLob(_lobLocator); return result; } internal OracleMonthSpan GetOracleMonthSpan(NativeBuffer_RowBuffer buffer) { if (typeof(OracleMonthSpan) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleMonthSpan.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleMonthSpan result = new OracleMonthSpan(buffer, _valueOffset); return result; } internal OracleNumber GetOracleNumber(NativeBuffer_RowBuffer buffer) { if (typeof(OracleNumber) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleNumber.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleNumber result = new OracleNumber(buffer, _valueOffset); return result; } internal OracleString GetOracleString(NativeBuffer_RowBuffer buffer) { if (typeof(OracleString) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleString.Null; } FixupLongValueLength(buffer); OracleString result = new OracleString(buffer, _valueOffset, _lengthOffset, _metaType, _connection, _bindAsUTF16, false); return result; } internal OracleTimeSpan GetOracleTimeSpan(NativeBuffer_RowBuffer buffer) { if (typeof(OracleTimeSpan) != _metaType.NoConvertType) { throw ADP.InvalidCast(); } if (IsDBNull(buffer)) { return OracleTimeSpan.Null; } Debug.Assert(null == _longBuffer, "dangling long buffer?"); OracleTimeSpan result = new OracleTimeSpan(buffer, _valueOffset); return result; } internal bool IsDBNull(NativeBuffer_RowBuffer buffer) { // Returns true if the column value in the buffer is null. return (_isNullable && buffer.ReadInt16(_indicatorOffset) == (Int16)OCI.INDICATOR.ISNULL); } internal void Rebind(OracleConnection connection, ref bool mustRelease, ref SafeHandle handleToBind) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: You must have called DangerousAddRef on the buffer before // calling this method, or you run the risk of allowing Handle // Recycling to occur! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Here's the hook that gets called whenever we're about to fetch // a new row, allowing us to reset any information that we shouldn't // carry forward. handleToBind = null; switch (_metaType.OciType) { case OCI.DATATYPE.LONG: case OCI.DATATYPE.LONGRAW: _rowBuffer.WriteInt32(_lengthOffset, 0); _longLength = -1; // reset the length to unknown; if (null != _longBuffer) { _longBuffer.Reset(); // free all the memory we allocated, except the initial one } else { _longBuffer = new NativeBuffer_LongColumnData(); } handleToBind = _longBuffer; break; case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: case OCI.DATATYPE.BFILE: OciLobLocator.SafeDispose(ref _lobLocator); _lobLocator = new OciLobLocator(connection, _metaType.OracleType); handleToBind = _lobLocator.Descriptor; break; } // We need to add-ref the handle so it can't be released somehow // by another thread while we're fetching. Only after we do that // can we write it to the buffer for the Oracle to use during the // Fetch. The caller is required to provide storage for the // handleToBind and ensure that the DangerousRelease is called // in it's CER. if (null != handleToBind) { handleToBind.DangerousAddRef(ref mustRelease); _rowBuffer.WriteIntPtr(_valueOffset, handleToBind.DangerousGetHandle()); } } }; } // 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
- HttpListenerRequest.cs
- CommandValueSerializer.cs
- Predicate.cs
- PlatformNotSupportedException.cs
- DataServiceClientException.cs
- ArglessEventHandlerProxy.cs
- ACL.cs
- UserUseLicenseDictionaryLoader.cs
- LinkedList.cs
- InlineCollection.cs
- StylusButton.cs
- ResourceDictionaryCollection.cs
- MenuCommands.cs
- RSAOAEPKeyExchangeFormatter.cs
- DelegateTypeInfo.cs
- ScriptControlDescriptor.cs
- XmlSchemaAttribute.cs
- UrlPropertyAttribute.cs
- GiveFeedbackEventArgs.cs
- DelegatedStream.cs
- MediaContextNotificationWindow.cs
- SmtpLoginAuthenticationModule.cs
- WebPartConnectionsDisconnectVerb.cs
- PrivilegedConfigurationManager.cs
- ReadOnlyTernaryTree.cs
- DataGridViewCellMouseEventArgs.cs
- GridErrorDlg.cs
- HttpClientCertificate.cs
- PathSegment.cs
- BinaryFormatter.cs
- Encoder.cs
- RequestContext.cs
- VarRemapper.cs
- AdapterDictionary.cs
- SurrogateEncoder.cs
- WindowsGraphics2.cs
- NodeFunctions.cs
- MimeMapping.cs
- ReadOnlyNameValueCollection.cs
- DataServiceResponse.cs
- TraceEventCache.cs
- WebHeaderCollection.cs
- TrustManagerPromptUI.cs
- ValidationEventArgs.cs
- FragmentQuery.cs
- DrawingGroupDrawingContext.cs
- CreateUserWizardStep.cs
- ButtonAutomationPeer.cs
- AutomationPeer.cs
- HttpModuleAction.cs
- DiagnosticsConfiguration.cs
- RemoteAsymmetricSignatureFormatter.cs
- CounterCreationDataCollection.cs
- CancellationState.cs
- WizardSideBarListControlItem.cs
- WebPartTracker.cs
- Typography.cs
- RegexCapture.cs
- ClientRolePrincipal.cs
- Section.cs
- EncodingInfo.cs
- SystemWebSectionGroup.cs
- ChtmlMobileTextWriter.cs
- TemplateComponentConnector.cs
- CryptographicAttribute.cs
- EntityTemplateUserControl.cs
- XmlSchemaSubstitutionGroup.cs
- TabControl.cs
- WebPartConnectionsDisconnectVerb.cs
- PrintPreviewGraphics.cs
- UniqueConstraint.cs
- WebPartsPersonalization.cs
- UpdateCompiler.cs
- RadioButtonAutomationPeer.cs
- SchemaCollectionPreprocessor.cs
- DescendentsWalkerBase.cs
- SmiMetaData.cs
- DmlSqlGenerator.cs
- ToolStripTextBox.cs
- SQLInt16.cs
- RIPEMD160Managed.cs
- ItemContainerGenerator.cs
- ISCIIEncoding.cs
- NamedPipeActivation.cs
- ConfigXmlText.cs
- ExternalException.cs
- InternalDispatchObject.cs
- DataGridItem.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- _LocalDataStoreMgr.cs
- XmlQueryTypeFactory.cs
- Size3D.cs
- ParentControlDesigner.cs
- TextRangeBase.cs
- EncryptedReference.cs
- CategoryValueConverter.cs
- WebSysDisplayNameAttribute.cs
- FileInfo.cs
- TypeNameParser.cs
- HttpConfigurationSystem.cs