1 //------------------------------------------------------------------------------
2 // <copyright file="ValueUtilsSmi.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 namespace Microsoft.SqlServer.Server {
12 using System.Collections;
13 using System.Collections.Generic;
15 using System.Data.Sql;
16 using System.Data.Common;
17 using System.Data.SqlClient;
18 using System.Data.SqlTypes;
19 using System.Diagnostics;
20 using System.Globalization;
22 using System.Reflection;
26 // Utilities for manipulating values with the Smi interface.
28 // THIS CLASS IS BUILT ON TOP OF THE SMI INTERFACE -- SMI SHOULD NOT DEPEND ON IT!
30 // These are all based off of knowing the clr type of the value
31 // as an ExtendedClrTypeCode enum for rapid access (lookup in static array is best, if possible).
32 internal static class ValueUtilsSmi {
33 const int __maxByteChunkSize = TdsEnums.MAXSIZE;
34 const int __maxCharChunkSize = TdsEnums.MAXSIZE / sizeof(char);
35 const int NoLengthLimit = (int)SmiMetaData.UnlimitedMaxLengthIndicator; // make sure we use the same constant
38 const int constBinBufferSize = 4096; // Size of the buffer used to read input parameter of type Stream
39 const int constTextBufferSize = 4096; // Size of the buffer (in chars) user to read input parameter of type TextReader
42 // User-visible semantics-laden Getter/Setter support methods
43 // These methods implement common semantics for getters & setters
44 // All access to underlying Smi getters/setters must validate parameters
48 // The idea for the getters is that there are two types associated with the field/column,
49 // the one the user asks for (implicitly via a strongly-typed getter) and the one the data
50 // is stored in (SmiMetaData).
51 // When a strong getter is invoked, we try one of two ways to get the value
52 // 1) go directly to the source for the requested type if possible
53 // 2) instantiate the value based on the stored type (GetValue), then ask the Clr
55 internal static bool IsDBNull( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
56 return IsDBNull_Unchecked( sink, getters, ordinal );
59 internal static bool GetBoolean( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
60 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
61 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Boolean ) ) {
62 return GetBoolean_Unchecked( sink, getters, ordinal );
65 object result = GetValue( sink, getters, ordinal, metaData, null );
67 throw ADP.InvalidCast();
69 return (Boolean)result;
72 internal static byte GetByte( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
73 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
74 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Byte ) ) {
75 return GetByte_Unchecked( sink, getters, ordinal );
77 object result = GetValue( sink, getters, ordinal, metaData, null );
79 throw ADP.InvalidCast();
84 private static long GetBytesConversion(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, long fieldOffset, byte[] buffer, int bufferOffset, int length, bool throwOnNull) {
85 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
87 throw ADP.InvalidCast();
89 SqlBinary value = (SqlBinary) obj;
93 throw SQL.SqlNullValue();
96 // return zero length in any case
101 if ( null == buffer ) {
105 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength * sizeof(char), value.Length,
106 fieldOffset, buffer.Length, bufferOffset, length );
107 Array.Copy( value.Value, checked((int)fieldOffset), buffer, bufferOffset, length );
111 internal static long GetBytes( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiExtendedMetaData metaData, long fieldOffset, byte[] buffer, int bufferOffset, int length, bool throwOnNull ) {
112 // Additional exclusions not caught by GetBytesInternal
113 if ( (SmiMetaData.UnlimitedMaxLengthIndicator != metaData.MaxLength &&
114 (SqlDbType.VarChar == metaData.SqlDbType ||
115 SqlDbType.NVarChar == metaData.SqlDbType ||
116 SqlDbType.Char == metaData.SqlDbType ||
117 SqlDbType.NChar == metaData.SqlDbType)) ||
118 SqlDbType.Xml == metaData.SqlDbType) {
119 throw SQL.NonBlobColumn(metaData.Name);
122 return GetBytesInternal(sink, getters, ordinal, metaData, fieldOffset, buffer, bufferOffset, length, throwOnNull);
126 internal static long GetBytesInternal( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, long fieldOffset, byte[] buffer, int bufferOffset, int length, bool throwOnNull ) {
127 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.ByteArray ) ) {
128 if (IsDBNull_Unchecked( sink, getters, ordinal )) {
130 throw SQL.SqlNullValue();
133 // check user's parameters for validity against a zero-length value
134 CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, 0, fieldOffset, buffer.Length, bufferOffset, length );
136 // return zero length in any case
140 long actualLength = GetBytesLength_Unchecked( sink, getters, ordinal );
141 if ( null == buffer ) {
144 if (MetaDataUtilsSmi.IsCharOrXmlType(metaData.SqlDbType)) {
145 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength * sizeof(char), actualLength,
146 fieldOffset, buffer.Length, bufferOffset, length );
149 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, actualLength, fieldOffset, buffer.Length, bufferOffset, length );
151 Debug.Assert( length >= 0, "Invalid CheckXetParameters return length!" );
153 length = GetBytes_Unchecked( sink, getters, ordinal, fieldOffset, buffer, bufferOffset, length);
158 return GetBytesConversion(sink, getters, ordinal, metaData, fieldOffset, buffer, bufferOffset, length, throwOnNull);
161 internal static long GetChars( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, long fieldOffset, char[] buffer, int bufferOffset, int length ) {
162 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
163 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.CharArray ) ) {
164 long actualLength = GetCharsLength_Unchecked( sink, getters, ordinal );
165 if ( null == buffer ) {
168 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, actualLength, fieldOffset, buffer.Length, bufferOffset, length );
169 Debug.Assert( length >= 0, "Buffer.Length was invalid!" );
171 length = GetChars_Unchecked( sink, getters, ordinal, fieldOffset, buffer, bufferOffset, length);
176 String value = ( (String) GetValue( sink, getters, ordinal, metaData, null ) );
178 throw ADP.InvalidCast();
180 if ( null == buffer ) {
183 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength * sizeof(char), value.Length,
184 fieldOffset, buffer.Length, bufferOffset, length );
185 value.CopyTo( checked((int)fieldOffset), buffer, bufferOffset, length );
189 internal static DateTime GetDateTime( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
190 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
191 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.DateTime ) ) {
192 return GetDateTime_Unchecked( sink, getters, ordinal );
194 object result = GetValue( sink, getters, ordinal, metaData, null );
195 if (null == result) {
196 throw ADP.InvalidCast();
198 return (DateTime) result;
201 // calling GetDateTimeOffset on possibly v100 SMI
202 internal static DateTimeOffset GetDateTimeOffset(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupportKatmaiDateTime) {
203 if (gettersSupportKatmaiDateTime) {
204 return GetDateTimeOffset(sink, (SmiTypedGetterSetter)getters, ordinal, metaData);
206 ThrowIfITypedGettersIsNull(sink, getters, ordinal);
207 object result = GetValue(sink, getters, ordinal, metaData, null);
208 if (null == result) {
209 throw ADP.InvalidCast();
211 return (DateTimeOffset)result;
214 // dealing with v200 SMI
215 internal static DateTimeOffset GetDateTimeOffset(SmiEventSink_Default sink, SmiTypedGetterSetter getters, int ordinal, SmiMetaData metaData) {
216 ThrowIfITypedGettersIsNull(sink, getters, ordinal);
217 if (CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.DateTimeOffset)) {
218 return GetDateTimeOffset_Unchecked(sink, getters, ordinal);
220 return (DateTimeOffset)GetValue200(sink, getters, ordinal, metaData, null);
223 internal static Decimal GetDecimal( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
224 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
225 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Decimal ) ) {
226 return GetDecimal_PossiblyMoney( sink, getters, ordinal, metaData );
228 object result = GetValue( sink, getters, ordinal, metaData, null );
229 if (null == result) {
230 throw ADP.InvalidCast();
232 return (Decimal) result;
235 internal static Double GetDouble( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
236 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
237 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Double ) ) {
238 return GetDouble_Unchecked( sink, getters, ordinal );
240 object result = GetValue( sink, getters, ordinal, metaData, null );
241 if (null == result) {
242 throw ADP.InvalidCast();
244 return (Double) result;
247 internal static Guid GetGuid( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
248 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
249 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Guid ) ) {
250 return GetGuid_Unchecked( sink, getters, ordinal );
252 object result = GetValue( sink, getters, ordinal, metaData, null );
253 if (null == result) {
254 throw ADP.InvalidCast();
256 return (Guid) result;
259 internal static Int16 GetInt16( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
260 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
261 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Int16 ) ) {
262 return GetInt16_Unchecked( sink, getters, ordinal );
264 object obj = GetValue( sink, getters, ordinal, metaData, null );
266 throw ADP.InvalidCast();
271 internal static Int32 GetInt32( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
272 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
273 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Int32 ) ) {
274 return GetInt32_Unchecked( sink, getters, ordinal );
276 object result = GetValue( sink, getters, ordinal, metaData, null );
277 if (null == result) {
278 throw ADP.InvalidCast();
280 return (Int32) result;
283 internal static Int64 GetInt64( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
284 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
285 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Int64 ) ) {
286 return GetInt64_Unchecked( sink, getters, ordinal );
288 object result = GetValue( sink, getters, ordinal, metaData, null );
289 if (null == result) {
290 throw ADP.InvalidCast();
292 return (Int64) result;
295 internal static Single GetSingle( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
296 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
297 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Single ) ) {
298 return GetSingle_Unchecked( sink, getters, ordinal );
300 object result = GetValue( sink, getters, ordinal, metaData, null );
301 if (null == result) {
302 throw ADP.InvalidCast();
304 return (Single) result;
307 internal static SqlBinary GetSqlBinary( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
308 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlBinary ) ) {
309 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
310 return SqlBinary.Null;
312 return GetSqlBinary_Unchecked( sink, getters, ordinal );
314 object result = GetSqlValue( sink, getters, ordinal, metaData, null );
315 if (null == result) {
316 throw ADP.InvalidCast();
318 return (SqlBinary) result;
321 internal static SqlBoolean GetSqlBoolean( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
322 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlBoolean ) ) {
323 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
324 return SqlBoolean.Null;
326 return new SqlBoolean( GetBoolean_Unchecked( sink, getters, ordinal ) );
328 object result = GetSqlValue( sink, getters, ordinal, metaData, null );
329 if (null == result) {
330 throw ADP.InvalidCast();
332 return (SqlBoolean) result;
335 internal static SqlByte GetSqlByte( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
336 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlByte ) ) {
337 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
340 return new SqlByte( GetByte_Unchecked( sink, getters, ordinal ) );
342 object result = GetSqlValue( sink, getters, ordinal, metaData, null );
343 if (null == result) {
344 throw ADP.InvalidCast();
346 return (SqlByte) result;
349 internal static SqlBytes GetSqlBytes( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, SmiContext context ) {
351 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlBytes ) ) {
352 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
353 result = SqlBytes.Null;
356 long length = GetBytesLength_Unchecked( sink, getters, ordinal );
357 if ( 0 <= length && length < __maxByteChunkSize ) {
358 byte[] byteBuffer = GetByteArray_Unchecked( sink, getters, ordinal );
359 result = new SqlBytes( byteBuffer );
362 Stream s = new SmiGettersStream( sink, getters, ordinal, metaData );
363 s = CopyIntoNewSmiScratchStream( s, sink, context );
364 result = new SqlBytes( s );
369 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
371 throw ADP.InvalidCast();
373 SqlBinary binaryVal = (SqlBinary) obj;
374 if ( binaryVal.IsNull ) {
375 result = SqlBytes.Null;
378 result = new SqlBytes( binaryVal.Value );
385 internal static SqlChars GetSqlChars( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, SmiContext context ) {
387 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlChars ) ) {
388 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
389 result = SqlChars.Null;
392 long length = GetCharsLength_Unchecked( sink, getters, ordinal );
393 if ( length < __maxCharChunkSize || !InOutOfProcHelper.InProc) {
394 char[] charBuffer = GetCharArray_Unchecked( sink, getters, ordinal );
395 result = new SqlChars( charBuffer );
397 else { // InProc only
398 Stream s = new SmiGettersStream( sink, getters, ordinal, metaData );
399 SqlStreamChars sc = CopyIntoNewSmiScratchStreamChars( s, sink, context );
400 result = new SqlChars( sc );
405 SqlString stringValue;
406 if (SqlDbType.Xml == metaData.SqlDbType) {
407 SqlXml xmlValue = GetSqlXml_Unchecked( sink, getters, ordinal, null );
409 if (xmlValue.IsNull) {
410 result = SqlChars.Null;
413 result = new SqlChars( xmlValue.Value.ToCharArray() );
417 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
419 throw ADP.InvalidCast();
421 stringValue = (SqlString) obj;
423 if ( stringValue.IsNull ) {
424 result = SqlChars.Null;
427 result = new SqlChars( stringValue.Value.ToCharArray() );
435 internal static SqlDateTime GetSqlDateTime( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
437 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlDateTime ) ) {
438 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
439 result = SqlDateTime.Null;
442 DateTime temp = GetDateTime_Unchecked( sink, getters, ordinal );
443 result = new SqlDateTime( temp );
447 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
449 throw ADP.InvalidCast();
451 result = (SqlDateTime) obj;
457 internal static SqlDecimal GetSqlDecimal( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
459 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlDecimal ) ) {
460 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
461 result = SqlDecimal.Null;
464 result = GetSqlDecimal_Unchecked( sink, getters, ordinal );
468 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
470 throw ADP.InvalidCast();
472 result = (SqlDecimal) obj;
478 internal static SqlDouble GetSqlDouble( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
480 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlDouble ) ) {
481 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
482 result = SqlDouble.Null;
485 Double temp = GetDouble_Unchecked( sink, getters, ordinal );
486 result = new SqlDouble( temp );
490 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
492 throw ADP.InvalidCast();
494 result = (SqlDouble) obj;
500 internal static SqlGuid GetSqlGuid( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
502 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlGuid ) ) {
503 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
504 result = SqlGuid.Null;
507 Guid temp = GetGuid_Unchecked( sink, getters, ordinal );
508 result = new SqlGuid( temp );
512 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
514 throw ADP.InvalidCast();
516 result = (SqlGuid) obj;
522 internal static SqlInt16 GetSqlInt16( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
524 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlInt16 ) ) {
525 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
526 result = SqlInt16.Null;
529 Int16 temp = GetInt16_Unchecked( sink, getters, ordinal );
530 result = new SqlInt16( temp );
534 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
536 throw ADP.InvalidCast();
538 result = (SqlInt16) obj;
544 internal static SqlInt32 GetSqlInt32( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
546 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlInt32 ) ) {
547 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
548 result = SqlInt32.Null;
551 Int32 temp = GetInt32_Unchecked( sink, getters, ordinal );
552 result = new SqlInt32( temp );
556 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
558 throw ADP.InvalidCast();
560 result = (SqlInt32) obj;
565 internal static SqlInt64 GetSqlInt64( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
567 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlInt64 ) ) {
568 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
569 result = SqlInt64.Null;
572 Int64 temp = GetInt64_Unchecked( sink, getters, ordinal );
573 result = new SqlInt64( temp );
577 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
579 throw ADP.InvalidCast();
581 result = (SqlInt64) obj;
587 internal static SqlMoney GetSqlMoney( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
589 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlMoney ) ) {
590 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
591 result = SqlMoney.Null;
594 result = GetSqlMoney_Unchecked( sink, getters, ordinal );
598 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
600 throw ADP.InvalidCast();
602 result = (SqlMoney) obj;
608 internal static SqlSingle GetSqlSingle( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
610 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlSingle ) ) {
611 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
612 result = SqlSingle.Null;
615 Single temp = GetSingle_Unchecked( sink, getters, ordinal );
616 result = new SqlSingle( temp );
620 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
622 throw ADP.InvalidCast();
624 result = (SqlSingle) obj;
630 internal static SqlString GetSqlString( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
632 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlString ) ) {
633 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
634 result = SqlString.Null;
637 String temp = GetString_Unchecked( sink, getters, ordinal );
638 result = new SqlString( temp );
641 else if (SqlDbType.Xml == metaData.SqlDbType) {
642 SqlXml xmlValue = GetSqlXml_Unchecked( sink, getters, ordinal, null );
644 if (xmlValue.IsNull) {
645 result = SqlString.Null;
648 result = new SqlString( xmlValue.Value );
652 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
654 throw ADP.InvalidCast();
656 result = (SqlString) obj;
662 internal static SqlXml GetSqlXml( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, SmiContext context ) {
664 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.SqlXml ) ) {
665 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
666 result = SqlXml.Null;
669 result = GetSqlXml_Unchecked( sink, getters, ordinal, context );
673 object obj = GetSqlValue( sink, getters, ordinal, metaData, null );
675 throw ADP.InvalidCast();
677 result = (SqlXml) obj;
683 internal static String GetString( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
684 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
685 if ( CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.String ) ) {
686 return GetString_Unchecked( sink, getters, ordinal );
688 object obj = GetValue( sink, getters, ordinal, metaData, null );
690 throw ADP.InvalidCast();
695 internal static SqlSequentialStreamSmi GetSequentialStream( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool bypassTypeCheck = false ) {
696 Debug.Assert( !ValueUtilsSmi.IsDBNull_Unchecked( sink, getters, ordinal ), "Should not try to get a SqlSequentialStreamSmi on a null column" );
697 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
698 if ( ( !bypassTypeCheck ) && ( !CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.Stream ) ) ) {
699 throw ADP.InvalidCast();
702 // This will advance the column to ordinal
703 long length = GetBytesLength_Unchecked(sink, getters, ordinal);
704 return new SqlSequentialStreamSmi(sink, getters, ordinal, length);
707 internal static SqlSequentialTextReaderSmi GetSequentialTextReader( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
708 Debug.Assert(!ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal), "Should not try to get a SqlSequentialTextReaderSmi on a null column");
709 ThrowIfITypedGettersIsNull( sink, getters, ordinal );
710 if ( !CanAccessGetterDirectly( metaData, ExtendedClrTypeCode.TextReader ) ) {
711 throw ADP.InvalidCast();
714 // This will advance the column to ordinal
715 long length = GetCharsLength_Unchecked(sink, getters, ordinal);
716 return new SqlSequentialTextReaderSmi(sink, getters, ordinal, length);
719 internal static Stream GetStream(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool bypassTypeCheck = false) {
720 bool isDbNull = ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal);
722 // If a sql_variant, get the internal type
723 if ( !bypassTypeCheck ) {
724 if ((!isDbNull) && (metaData.SqlDbType == SqlDbType.Variant)) {
725 metaData = getters.GetVariantType(sink, ordinal);
727 // If the SqlDbType is still variant, then it must contain null, so don't throw InvalidCast
728 if ((metaData.SqlDbType != SqlDbType.Variant) && (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.Stream))) {
729 throw ADP.InvalidCast();
740 data = GetByteArray_Unchecked(sink, getters, ordinal);
743 // Wrap data in pre-built object
744 return new MemoryStream(data, writable: false);
747 internal static TextReader GetTextReader( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
748 bool isDbNull = ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal);
750 // If a sql_variant, get the internal type
751 if ((!isDbNull) && (metaData.SqlDbType == SqlDbType.Variant)) {
752 metaData = getters.GetVariantType(sink, ordinal);
754 // If the SqlDbType is still variant, then it must contain null, so don't throw InvalidCast
755 if ((metaData.SqlDbType != SqlDbType.Variant) && (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.TextReader))) {
756 throw ADP.InvalidCast();
766 data = GetString_Unchecked(sink, getters, ordinal);
769 // Wrap in pre-built object
770 return new StringReader(data);
773 // calling GetTimeSpan on possibly v100 SMI
774 internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupportKatmaiDateTime) {
775 if (gettersSupportKatmaiDateTime) {
776 return GetTimeSpan(sink, (SmiTypedGetterSetter)getters, ordinal, metaData);
778 ThrowIfITypedGettersIsNull(sink, getters, ordinal);
779 object obj = GetValue(sink, getters, ordinal, metaData, null);
781 throw ADP.InvalidCast();
783 return (TimeSpan) obj;
786 // dealing with v200 SMI
787 internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, SmiTypedGetterSetter getters, int ordinal, SmiMetaData metaData) {
788 ThrowIfITypedGettersIsNull(sink, getters, ordinal);
789 if (CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.TimeSpan)) {
790 return GetTimeSpan_Unchecked(sink, getters, ordinal);
792 return (TimeSpan)GetValue200(sink, getters, ordinal, metaData, null);
795 // GetValue() for v200 SMI (new Katmai Date/Time types)
796 internal static object GetValue200(
797 SmiEventSink_Default sink,
798 SmiTypedGetterSetter getters,
800 SmiMetaData metaData,
803 object result = null;
804 if (IsDBNull_Unchecked(sink, getters, ordinal)) {
805 result = DBNull.Value;
807 switch (metaData.SqlDbType) {
808 case SqlDbType.Variant: // Handle variants specifically for v200, since they could contain v200 types
809 metaData = getters.GetVariantType(sink, ordinal);
810 sink.ProcessMessagesAndThrow();
811 Debug.Assert(SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant causes endless recursion!");
812 result = GetValue200(sink, getters, ordinal, metaData, context);
815 case SqlDbType.DateTime2:
816 result = GetDateTime_Unchecked(sink, getters, ordinal);
819 result = GetTimeSpan_Unchecked(sink, getters, ordinal);
821 case SqlDbType.DateTimeOffset:
822 result = GetDateTimeOffset_Unchecked(sink, getters, ordinal);
825 result = GetValue(sink, getters, ordinal, metaData, context);
833 // implements SqlClient 1.1-compatible GetValue() semantics for everything except output parameters
834 internal static object GetValue(
835 SmiEventSink_Default sink,
836 ITypedGettersV3 getters,
838 SmiMetaData metaData,
841 object result = null;
842 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
843 result = DBNull.Value;
846 switch( metaData.SqlDbType ) {
847 case SqlDbType.BigInt:
848 result = GetInt64_Unchecked( sink, getters, ordinal );
850 case SqlDbType.Binary:
851 result = GetByteArray_Unchecked( sink, getters, ordinal );
854 result = GetBoolean_Unchecked( sink, getters, ordinal );
857 result = GetString_Unchecked( sink, getters, ordinal );
859 case SqlDbType.DateTime:
860 result = GetDateTime_Unchecked( sink, getters, ordinal );
862 case SqlDbType.Decimal:
863 result = GetSqlDecimal_Unchecked( sink, getters, ordinal ).Value;
865 case SqlDbType.Float:
866 result = GetDouble_Unchecked( sink, getters, ordinal );
868 case SqlDbType.Image:
869 result = GetByteArray_Unchecked( sink, getters, ordinal );
872 result = GetInt32_Unchecked( sink, getters, ordinal );
874 case SqlDbType.Money:
875 result = GetSqlMoney_Unchecked( sink, getters, ordinal ).Value;
877 case SqlDbType.NChar:
878 result = GetString_Unchecked( sink, getters, ordinal );
880 case SqlDbType.NText:
881 result = GetString_Unchecked( sink, getters, ordinal );
883 case SqlDbType.NVarChar:
884 result = GetString_Unchecked( sink, getters, ordinal );
887 result = GetSingle_Unchecked( sink, getters, ordinal );
889 case SqlDbType.UniqueIdentifier:
890 result = GetGuid_Unchecked( sink, getters, ordinal );
892 case SqlDbType.SmallDateTime:
893 result = GetDateTime_Unchecked( sink, getters, ordinal );
895 case SqlDbType.SmallInt:
896 result = GetInt16_Unchecked( sink, getters, ordinal );
898 case SqlDbType.SmallMoney:
899 result = GetSqlMoney_Unchecked( sink, getters, ordinal ).Value;
902 result = GetString_Unchecked( sink, getters, ordinal );
904 case SqlDbType.Timestamp:
905 result = GetByteArray_Unchecked( sink, getters, ordinal );
907 case SqlDbType.TinyInt:
908 result = GetByte_Unchecked( sink, getters, ordinal );
910 case SqlDbType.VarBinary:
911 result = GetByteArray_Unchecked( sink, getters, ordinal );
913 case SqlDbType.VarChar:
914 result = GetString_Unchecked( sink, getters, ordinal );
916 case SqlDbType.Variant:
917 metaData = getters.GetVariantType( sink, ordinal );
918 sink.ProcessMessagesAndThrow();
919 Debug.Assert( SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant causes endless recursion!" );
920 result = GetValue( sink, getters, ordinal, metaData, context );
923 result = GetSqlXml_Unchecked( sink, getters, ordinal, context ).Value;
926 result = GetUdt_LengthChecked( sink, getters, ordinal, metaData );
934 // dealing with v200 SMI
935 internal static object GetSqlValue200(
936 SmiEventSink_Default sink,
937 SmiTypedGetterSetter getters,
939 SmiMetaData metaData,
942 object result = null;
943 if (IsDBNull_Unchecked(sink, getters, ordinal)) {
944 if (SqlDbType.Udt == metaData.SqlDbType) {
945 result = NullUdtInstance(metaData);
947 result = __typeSpecificNullForSqlValue[(int)metaData.SqlDbType];
950 switch (metaData.SqlDbType) {
951 case SqlDbType.Variant: // Handle variants specifically for v200, since they could contain v200 types
952 metaData = getters.GetVariantType(sink, ordinal);
953 sink.ProcessMessagesAndThrow();
954 Debug.Assert(SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant causes endless recursion!");
955 result = GetSqlValue200(sink, getters, ordinal, metaData, context);
958 case SqlDbType.DateTime2:
959 result = GetDateTime_Unchecked(sink, getters, ordinal);
962 result = GetTimeSpan_Unchecked(sink, getters, ordinal);
964 case SqlDbType.DateTimeOffset:
965 result = GetDateTimeOffset_Unchecked(sink, getters, ordinal);
968 result = GetSqlValue(sink, getters, ordinal, metaData, context);
976 // implements SqlClient 1.1-compatible GetSqlValue() semantics for everything except output parameters
977 internal static object GetSqlValue(
978 SmiEventSink_Default sink,
979 ITypedGettersV3 getters,
981 SmiMetaData metaData,
984 object result = null;
985 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
986 if (SqlDbType.Udt == metaData.SqlDbType) {
987 result = NullUdtInstance(metaData);
990 result = __typeSpecificNullForSqlValue[(int)metaData.SqlDbType];
994 switch( metaData.SqlDbType ) {
995 case SqlDbType.BigInt:
996 result = new SqlInt64( GetInt64_Unchecked( sink, getters, ordinal ) );
998 case SqlDbType.Binary:
999 result = GetSqlBinary_Unchecked( sink, getters, ordinal );
1002 result = new SqlBoolean( GetBoolean_Unchecked( sink, getters, ordinal ) );
1004 case SqlDbType.Char:
1005 result = new SqlString( GetString_Unchecked( sink, getters, ordinal ) );
1007 case SqlDbType.DateTime:
1008 result = new SqlDateTime( GetDateTime_Unchecked( sink, getters, ordinal ) );
1010 case SqlDbType.Decimal:
1011 result = GetSqlDecimal_Unchecked( sink, getters, ordinal );
1013 case SqlDbType.Float:
1014 result = new SqlDouble( GetDouble_Unchecked( sink, getters, ordinal ) );
1016 case SqlDbType.Image:
1017 result = GetSqlBinary_Unchecked( sink, getters, ordinal );
1020 result = new SqlInt32( GetInt32_Unchecked( sink, getters, ordinal ) );
1022 case SqlDbType.Money:
1023 result = GetSqlMoney_Unchecked( sink, getters, ordinal );
1025 case SqlDbType.NChar:
1026 result = new SqlString( GetString_Unchecked( sink, getters, ordinal ) );
1028 case SqlDbType.NText:
1029 result = new SqlString( GetString_Unchecked( sink, getters, ordinal ) );
1031 case SqlDbType.NVarChar:
1032 result = new SqlString( GetString_Unchecked( sink, getters, ordinal ) );
1034 case SqlDbType.Real:
1035 result = new SqlSingle( GetSingle_Unchecked( sink, getters, ordinal ) );
1037 case SqlDbType.UniqueIdentifier:
1038 result = new SqlGuid( GetGuid_Unchecked( sink, getters, ordinal ) );
1040 case SqlDbType.SmallDateTime:
1041 result = new SqlDateTime( GetDateTime_Unchecked( sink, getters, ordinal ) );
1043 case SqlDbType.SmallInt:
1044 result = new SqlInt16( GetInt16_Unchecked( sink, getters, ordinal ) );
1046 case SqlDbType.SmallMoney:
1047 result = GetSqlMoney_Unchecked( sink, getters, ordinal );
1049 case SqlDbType.Text:
1050 result = new SqlString( GetString_Unchecked( sink, getters, ordinal ) );
1052 case SqlDbType.Timestamp:
1053 result = GetSqlBinary_Unchecked( sink, getters, ordinal );
1055 case SqlDbType.TinyInt:
1056 result = new SqlByte( GetByte_Unchecked( sink, getters, ordinal ) );
1058 case SqlDbType.VarBinary:
1059 result = GetSqlBinary_Unchecked( sink, getters, ordinal );
1061 case SqlDbType.VarChar:
1062 result = new SqlString( GetString_Unchecked( sink, getters, ordinal ) );
1064 case SqlDbType.Variant:
1065 metaData = getters.GetVariantType( sink, ordinal );
1066 sink.ProcessMessagesAndThrow();
1067 Debug.Assert( SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant causes endless recursion!" );
1068 result = GetSqlValue( sink, getters, ordinal, metaData, context );
1071 result = GetSqlXml_Unchecked( sink, getters, ordinal, context );
1074 result = GetUdt_LengthChecked( sink, getters, ordinal, metaData );
1082 // null return values for SqlClient 1.1-compatible GetSqlValue()
1083 private static object[] __typeSpecificNullForSqlValue = {
1084 SqlInt64.Null, // SqlDbType.BigInt
1085 SqlBinary.Null, // SqlDbType.Binary
1086 SqlBoolean.Null, // SqlDbType.Bit
1087 SqlString.Null, // SqlDbType.Char
1088 SqlDateTime.Null, // SqlDbType.DateTime
1089 SqlDecimal.Null, // SqlDbType.Decimal
1090 SqlDouble.Null, // SqlDbType.Float
1091 SqlBinary.Null, // SqlDbType.Image
1092 SqlInt32.Null, // SqlDbType.Int
1093 SqlMoney.Null, // SqlDbType.Money
1094 SqlString.Null, // SqlDbType.NChar
1095 SqlString.Null, // SqlDbType.NText
1096 SqlString.Null, // SqlDbType.NVarChar
1097 SqlSingle.Null, // SqlDbType.Real
1098 SqlGuid.Null, // SqlDbType.UniqueIdentifier
1099 SqlDateTime.Null, // SqlDbType.SmallDateTime
1100 SqlInt16.Null, // SqlDbType.SmallInt
1101 SqlMoney.Null, // SqlDbType.SmallMoney
1102 SqlString.Null, // SqlDbType.Text
1103 SqlBinary.Null, // SqlDbType.Timestamp
1104 SqlByte.Null, // SqlDbType.TinyInt
1105 SqlBinary.Null, // SqlDbType.VarBinary
1106 SqlString.Null, // SqlDbType.VarChar
1107 DBNull.Value, // SqlDbType.Variant
1109 SqlXml.Null, // SqlDbType.Xml
1113 null, // SqlDbType.Udt -- requires instantiating udt-specific type
1114 null, // SqlDbType.Structured
1115 DBNull.Value, // SqlDbType.Date
1116 DBNull.Value, // SqlDbType.Time
1117 DBNull.Value, // SqlDbType.DateTime2
1118 DBNull.Value, // SqlDbType.DateTimeOffset
1121 internal static object NullUdtInstance(SmiMetaData metaData) {
1122 Type t = metaData.Type;
1123 Debug.Assert(t != null, "Unexpected null of Udt type on NullUdtInstance!");
1124 return t.InvokeMember("Null", BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Static, null, null, new Object[]{}, CultureInfo.InvariantCulture);
1127 internal static SqlBuffer.StorageType SqlDbTypeToStorageType(SqlDbType dbType) {
1128 int index = unchecked((int)dbType);
1129 Debug.Assert(index >= 0 && index < __dbTypeToStorageType.Length, string.Format(CultureInfo.InvariantCulture, "Unexpected dbType value: {0}", dbType));
1130 return __dbTypeToStorageType[index];
1133 private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result) {
1134 if (SqlDbType.Udt == metaData.SqlDbType) {
1135 result = NullUdtInstance(metaData);
1138 SqlBuffer.StorageType stype = SqlDbTypeToStorageType(metaData.SqlDbType);
1139 if ( SqlBuffer.StorageType.Empty == stype ) {
1140 result = DBNull.Value;
1142 else if (SqlBuffer.StorageType.SqlBinary == stype) {
1143 // special case SqlBinary, 'cause tds parser never sets SqlBuffer to null, just to empty!
1144 targetBuffer.SqlBinary = SqlBinary.Null;
1146 else if (SqlBuffer.StorageType.SqlGuid == stype) {
1147 targetBuffer.SqlGuid = SqlGuid.Null;
1150 targetBuffer.SetToNullOfType( stype );
1155 // UDTs and null variants come back via return value, all else is via targetBuffer.
1156 // implements SqlClient 2.0-compatible output parameter semantics
1157 internal static object GetOutputParameterV3Smi(
1158 SmiEventSink_Default sink, // event sink for errors
1159 ITypedGettersV3 getters, // getters interface to grab value from
1160 int ordinal, // parameter within getters
1161 SmiMetaData metaData, // Getter's type for this ordinal
1162 SmiContext context, // used to obtain scratch streams
1163 SqlBuffer targetBuffer // destination
1165 object result = null; // Workaround for UDT hack in non-Smi code paths.
1166 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
1167 GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
1170 switch( metaData.SqlDbType )
1172 case SqlDbType.BigInt:
1173 targetBuffer.Int64 = GetInt64_Unchecked( sink, getters, ordinal );
1175 case SqlDbType.Binary:
1176 case SqlDbType.Image:
1177 case SqlDbType.Timestamp:
1178 case SqlDbType.VarBinary:
1179 targetBuffer.SqlBinary = GetSqlBinary_Unchecked( sink, getters, ordinal );
1182 targetBuffer.Boolean = GetBoolean_Unchecked( sink, getters, ordinal );
1184 case SqlDbType.NChar:
1185 case SqlDbType.NText:
1186 case SqlDbType.NVarChar:
1187 case SqlDbType.Char:
1188 case SqlDbType.VarChar:
1189 case SqlDbType.Text:
1190 targetBuffer.SetToString( GetString_Unchecked( sink, getters, ordinal ) );
1192 case SqlDbType.DateTime:
1193 case SqlDbType.SmallDateTime: {
1194 SqlDateTime dt = new SqlDateTime( GetDateTime_Unchecked( sink, getters, ordinal ) );
1195 targetBuffer.SetToDateTime( dt.DayTicks, dt.TimeTicks );
1198 case SqlDbType.Decimal: {
1199 SqlDecimal dec = GetSqlDecimal_Unchecked( sink, getters, ordinal );
1200 targetBuffer.SetToDecimal( dec.Precision, dec.Scale, dec.IsPositive, dec.Data );
1203 case SqlDbType.Float:
1204 targetBuffer.Double = GetDouble_Unchecked( sink, getters, ordinal );
1207 targetBuffer.Int32 = GetInt32_Unchecked( sink, getters, ordinal );
1209 case SqlDbType.Money:
1210 case SqlDbType.SmallMoney:
1211 targetBuffer.SetToMoney( GetInt64_Unchecked( sink, getters, ordinal) );
1213 case SqlDbType.Real:
1214 targetBuffer.Single = GetSingle_Unchecked( sink, getters, ordinal );
1216 case SqlDbType.UniqueIdentifier:
1217 targetBuffer.SqlGuid = new SqlGuid( GetGuid_Unchecked( sink, getters, ordinal ) );
1219 case SqlDbType.SmallInt:
1220 targetBuffer.Int16 = GetInt16_Unchecked( sink, getters, ordinal );
1222 case SqlDbType.TinyInt:
1223 targetBuffer.Byte = GetByte_Unchecked( sink, getters, ordinal );
1225 case SqlDbType.Variant:
1226 // For variants, recur using the current value's sqldbtype
1227 metaData = getters.GetVariantType( sink, ordinal );
1228 sink.ProcessMessagesAndThrow();
1229 Debug.Assert( SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!" );
1230 GetOutputParameterV3Smi( sink, getters, ordinal, metaData, context, targetBuffer );
1233 result = GetUdt_LengthChecked( sink, getters, ordinal, metaData );
1236 targetBuffer.SqlXml = GetSqlXml_Unchecked( sink, getters, ordinal, null );
1239 Debug.Assert( false, "Unexpected SqlDbType" );
1247 // UDTs and null variants come back via return value, all else is via targetBuffer.
1248 // implements SqlClient 1.1-compatible output parameter semantics
1249 internal static object GetOutputParameterV200Smi(
1250 SmiEventSink_Default sink, // event sink for errors
1251 SmiTypedGetterSetter getters, // getters interface to grab value from
1252 int ordinal, // parameter within getters
1253 SmiMetaData metaData, // Getter's type for this ordinal
1254 SmiContext context, // used to obtain scratch streams
1255 SqlBuffer targetBuffer // destination
1257 object result = null; // Workaround for UDT hack in non-Smi code paths.
1258 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
1259 GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
1262 switch(metaData.SqlDbType) {
1263 // new types go here
1264 case SqlDbType.Variant: // Handle variants specifically for v200, since they could contain v200 types
1265 // For variants, recur using the current value's sqldbtype
1266 metaData = getters.GetVariantType( sink, ordinal );
1267 sink.ProcessMessagesAndThrow();
1268 Debug.Assert( SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!" );
1269 GetOutputParameterV200Smi( sink, getters, ordinal, metaData, context, targetBuffer );
1271 case SqlDbType.Date:
1272 targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal));
1274 case SqlDbType.DateTime2:
1275 targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale);
1277 case SqlDbType.Time:
1278 targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale);
1280 case SqlDbType.DateTimeOffset:
1281 targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale);
1284 result = GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
1292 private static SqlBuffer.StorageType[] __dbTypeToStorageType = new SqlBuffer.StorageType[] {
1293 SqlBuffer.StorageType.Int64, // BigInt
1294 SqlBuffer.StorageType.SqlBinary, // Binary
1295 SqlBuffer.StorageType.Boolean, // Bit
1296 SqlBuffer.StorageType.String, // Char
1297 SqlBuffer.StorageType.DateTime, // DateTime
1298 SqlBuffer.StorageType.Decimal, // Decimal
1299 SqlBuffer.StorageType.Double, // Float
1300 SqlBuffer.StorageType.SqlBinary, // Image
1301 SqlBuffer.StorageType.Int32, // Int
1302 SqlBuffer.StorageType.Money, // Money
1303 SqlBuffer.StorageType.String, // NChar
1304 SqlBuffer.StorageType.String, // NText
1305 SqlBuffer.StorageType.String, // NVarChar
1306 SqlBuffer.StorageType.Single, // Real
1307 SqlBuffer.StorageType.SqlGuid, // UniqueIdentifier
1308 SqlBuffer.StorageType.DateTime, // SmallDateTime
1309 SqlBuffer.StorageType.Int16, // SmallInt
1310 SqlBuffer.StorageType.Money, // SmallMoney
1311 SqlBuffer.StorageType.String, // Text
1312 SqlBuffer.StorageType.SqlBinary, // Timestamp
1313 SqlBuffer.StorageType.Byte, // TinyInt
1314 SqlBuffer.StorageType.SqlBinary, // VarBinary
1315 SqlBuffer.StorageType.String, // VarChar
1316 SqlBuffer.StorageType.Empty, // Variant
1317 SqlBuffer.StorageType.Empty, // 24
1318 SqlBuffer.StorageType.SqlXml, // Xml
1319 SqlBuffer.StorageType.Empty, // 26
1320 SqlBuffer.StorageType.Empty, // 27
1321 SqlBuffer.StorageType.Empty, // 28
1322 SqlBuffer.StorageType.Empty, // Udt
1323 SqlBuffer.StorageType.Empty, // Structured
1324 SqlBuffer.StorageType.Date, // Date
1325 SqlBuffer.StorageType.Time, // Time
1326 SqlBuffer.StorageType.DateTime2, // DateTime2
1327 SqlBuffer.StorageType.DateTimeOffset, // DateTimeOffset
1330 // Strongly-typed setters are a bit simpler than their corresponding getters.
1331 // 1) check to make sure the type is compatible (exception if not)
1333 internal static void SetDBNull( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Boolean value ) {
1334 SetDBNull_Unchecked( sink, setters, ordinal );
1337 internal static void SetBoolean( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Boolean value ) {
1338 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Boolean );
1340 SetBoolean_Unchecked( sink, setters, ordinal, value );
1343 internal static void SetByte( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Byte value ) {
1344 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Byte );
1346 SetByte_Unchecked( sink, setters, ordinal, value );
1349 internal static long SetBytes( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, long fieldOffset, byte[] buffer, int bufferOffset, int length ) {
1350 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.ByteArray );
1351 if ( null == buffer ) {
1352 throw ADP.ArgumentNull( "buffer" );
1354 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, fieldOffset, buffer.Length, bufferOffset, length );
1355 Debug.Assert( length >= 0, "Buffer.Length was invalid!" );
1357 // Front end semantics says to ignore fieldOffset and bufferOffset
1358 // if not doing any actual work.
1359 // Back end semantics says they must be valid, even for no work.
1360 // Compensate by setting offsets to zero here (valid for any scenario)
1364 return SetBytes_Unchecked( sink, setters, ordinal, fieldOffset, buffer, bufferOffset, length );
1367 internal static long SetBytesLength( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, long length ) {
1368 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.ByteArray );
1371 throw ADP.InvalidDataLength( length );
1374 if ( metaData.MaxLength >= 0 && length > metaData.MaxLength ) {
1375 length = metaData.MaxLength;
1378 setters.SetBytesLength( sink, ordinal, length );
1379 sink.ProcessMessagesAndThrow();
1384 internal static long SetChars( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, long fieldOffset, char[] buffer, int bufferOffset, int length ) {
1385 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.CharArray );
1386 if ( null == buffer ) {
1387 throw ADP.ArgumentNull( "buffer" );
1389 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, fieldOffset, buffer.Length, bufferOffset, length );
1390 Debug.Assert( length >= 0, "Buffer.Length was invalid!" );
1392 // Front end semantics says to ignore fieldOffset and bufferOffset
1393 // if not doing any actual work.
1394 // Back end semantics says they must be valid, even for no work.
1395 // Compensate by setting offsets to zero here (valid for any scenario)
1399 return SetChars_Unchecked( sink, setters, ordinal, fieldOffset, buffer, bufferOffset, length );
1402 internal static void SetDateTime( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTime value ) {
1403 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.DateTime );
1405 SetDateTime_Checked( sink, setters, ordinal, metaData, value );
1408 internal static void SetDateTimeOffset(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTimeOffset value, bool settersSupportKatmaiDateTime) {
1409 if (!settersSupportKatmaiDateTime) {
1410 throw ADP.InvalidCast();
1412 ThrowIfInvalidSetterAccess(metaData, ExtendedClrTypeCode.DateTimeOffset);
1413 SetDateTimeOffset_Unchecked(sink, (SmiTypedGetterSetter)setters, ordinal, value);
1416 internal static void SetDecimal( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Decimal value ) {
1417 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Decimal );
1419 SetDecimal_PossiblyMoney( sink, setters, ordinal, metaData, value );
1422 internal static void SetDouble( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Double value ) {
1423 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Double );
1425 SetDouble_Unchecked( sink, setters, ordinal, value );
1428 internal static void SetGuid( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Guid value ) {
1429 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Guid );
1431 SetGuid_Unchecked( sink, setters, ordinal, value );
1434 internal static void SetInt16( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Int16 value ) {
1435 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Int16 );
1437 SetInt16_Unchecked( sink, setters, ordinal, value );
1440 internal static void SetInt32( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Int32 value ) {
1441 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Int32 );
1443 SetInt32_Unchecked( sink, setters, ordinal, value );
1446 internal static void SetInt64( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Int64 value ) {
1447 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Int64 );
1449 SetInt64_Unchecked( sink, setters, ordinal, value );
1452 internal static void SetSingle( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Single value ) {
1453 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.Single );
1455 SetSingle_Unchecked( sink, setters, ordinal, value );
1458 internal static void SetSqlBinary( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlBinary value ) {
1459 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlBinary );
1460 SetSqlBinary_LengthChecked( sink, setters, ordinal, metaData, value, 0 );
1463 internal static void SetSqlBoolean( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlBoolean value ) {
1464 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlBoolean );
1466 SetSqlBoolean_Unchecked( sink, setters, ordinal, value );
1469 internal static void SetSqlByte( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlByte value ) {
1470 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlByte );
1472 SetSqlByte_Unchecked( sink, setters, ordinal, value );
1475 internal static void SetSqlBytes( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlBytes value ) {
1476 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlBytes );
1478 SetSqlBytes_LengthChecked( sink, setters, ordinal, metaData, value, 0 );
1481 internal static void SetSqlChars( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlChars value ) {
1482 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlChars );
1483 SetSqlChars_LengthChecked( sink, setters, ordinal, metaData, value, 0 );
1486 internal static void SetSqlDateTime( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDateTime value ) {
1487 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlDateTime );
1489 SetSqlDateTime_Checked( sink, setters, ordinal, metaData, value );
1492 internal static void SetSqlDecimal( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDecimal value ) {
1493 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlDecimal );
1495 SetSqlDecimal_Unchecked( sink, setters, ordinal, value );
1498 internal static void SetSqlDouble( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDouble value ) {
1499 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlDouble );
1501 SetSqlDouble_Unchecked( sink, setters, ordinal, value );
1504 internal static void SetSqlGuid( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlGuid value ) {
1505 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlGuid );
1507 SetSqlGuid_Unchecked( sink, setters, ordinal, value );
1510 internal static void SetSqlInt16( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlInt16 value ) {
1511 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlInt16 );
1513 SetSqlInt16_Unchecked( sink, setters, ordinal, value );
1516 internal static void SetSqlInt32( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlInt32 value ) {
1517 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlInt32 );
1519 SetSqlInt32_Unchecked( sink, setters, ordinal, value );
1522 internal static void SetSqlInt64( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlInt64 value ) {
1523 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlInt64 );
1525 SetSqlInt64_Unchecked( sink, setters, ordinal, value );
1528 internal static void SetSqlMoney( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlMoney value ) {
1529 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlMoney );
1531 SetSqlMoney_Checked( sink, setters, ordinal, metaData, value );
1534 internal static void SetSqlSingle( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlSingle value ) {
1535 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlSingle );
1537 SetSqlSingle_Unchecked( sink, setters, ordinal, value );
1540 internal static void SetSqlString( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlString value ) {
1541 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlString );
1542 SetSqlString_LengthChecked( sink, setters, ordinal, metaData, value, 0 );
1545 internal static void SetSqlXml( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlXml value ) {
1546 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.SqlXml );
1548 SetSqlXml_Unchecked( sink, setters, ordinal, value );
1551 internal static void SetString( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, String value ) {
1552 ThrowIfInvalidSetterAccess( metaData, ExtendedClrTypeCode.String );
1554 SetString_LengthChecked( sink, setters, ordinal, metaData, value, 0 );
1557 internal static void SetTimeSpan(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, TimeSpan value, bool settersSupportKatmaiDateTime) {
1558 if (!settersSupportKatmaiDateTime) {
1559 throw ADP.InvalidCast();
1561 ThrowIfInvalidSetterAccess(metaData, ExtendedClrTypeCode.TimeSpan);
1562 SetTimeSpan_Checked(sink, (SmiTypedGetterSetter)setters, ordinal, metaData, value);
1565 // Implements SqlClient 2.0-compatible SetValue() semantics
1566 // Assumes caller already validated type against the metadata, other than trimming lengths
1567 internal static void SetCompatibleValue(
1568 SmiEventSink_Default sink,
1569 ITypedSettersV3 setters,
1571 SmiMetaData metaData, // metadata for target setter column
1573 ExtendedClrTypeCode typeCode,
1576 // Ensure either an invalid type, or caller validated compatibility
1577 // SqlDbType.Variant and have special handling
1578 Debug.Assert( typeCode == ExtendedClrTypeCode.Invalid ||
1579 typeCode == ExtendedClrTypeCode.SByte ||
1580 typeCode == ExtendedClrTypeCode.UInt16 ||
1581 typeCode == ExtendedClrTypeCode.UInt32 ||
1582 typeCode == ExtendedClrTypeCode.UInt64 ||
1583 typeCode == ExtendedClrTypeCode.DBNull ||
1584 typeCode == ExtendedClrTypeCode.Empty ||
1585 CanAccessSetterDirectly( metaData, typeCode ) ||
1586 value is DataFeed /* already validated */);
1588 switch ( typeCode ) {
1589 case ExtendedClrTypeCode.Invalid: throw ADP.UnknownDataType( value.GetType() );
1590 case ExtendedClrTypeCode.Boolean: SetBoolean_Unchecked( sink, setters, ordinal, (Boolean) value ); break;
1591 case ExtendedClrTypeCode.Byte: SetByte_Unchecked( sink, setters, ordinal, (Byte) value ); break;
1592 case ExtendedClrTypeCode.Char: {
1593 char[] charsValue = new char[] {(char) value};
1594 // recur with array type
1595 SetCompatibleValue( sink, setters, ordinal, metaData, charsValue, ExtendedClrTypeCode.CharArray, 0 );
1598 case ExtendedClrTypeCode.DateTime: SetDateTime_Checked( sink, setters, ordinal, metaData, (DateTime)value ); break;
1599 case ExtendedClrTypeCode.DBNull: SetDBNull_Unchecked( sink, setters, ordinal ); break;
1600 case ExtendedClrTypeCode.Decimal: SetDecimal_PossiblyMoney( sink, setters, ordinal, metaData, (Decimal) value ); break;
1601 case ExtendedClrTypeCode.Double: SetDouble_Unchecked( sink, setters, ordinal, (Double) value ); break;
1602 case ExtendedClrTypeCode.Empty: SetDBNull_Unchecked( sink, setters, ordinal ); break;
1603 case ExtendedClrTypeCode.Int16: SetInt16_Unchecked( sink, setters, ordinal, (Int16) value ); break;
1604 case ExtendedClrTypeCode.Int32: SetInt32_Unchecked( sink, setters, ordinal, (Int32) value ); break;
1605 case ExtendedClrTypeCode.Int64: SetInt64_Unchecked( sink, setters, ordinal, (Int64) value ); break;
1606 case ExtendedClrTypeCode.SByte: throw ADP.InvalidCast();
1607 case ExtendedClrTypeCode.Single: SetSingle_Unchecked( sink, setters, ordinal, (Single) value ); break;
1608 case ExtendedClrTypeCode.String: SetString_LengthChecked( sink, setters, ordinal, metaData, (string) value, offset ); break;
1609 case ExtendedClrTypeCode.UInt16: throw ADP.InvalidCast();
1610 case ExtendedClrTypeCode.UInt32: throw ADP.InvalidCast();
1611 case ExtendedClrTypeCode.UInt64: throw ADP.InvalidCast();
1612 case ExtendedClrTypeCode.Object: SetUdt_LengthChecked( sink, setters, ordinal, metaData, value ); break;
1613 case ExtendedClrTypeCode.ByteArray: SetByteArray_LengthChecked( sink, setters, ordinal, metaData, (byte[]) value, offset ); break;
1614 case ExtendedClrTypeCode.CharArray: SetCharArray_LengthChecked( sink, setters, ordinal, metaData, (char[]) value, offset ); break;
1615 case ExtendedClrTypeCode.Guid: SetGuid_Unchecked( sink, setters, ordinal, (Guid) value ); break;
1616 case ExtendedClrTypeCode.SqlBinary: SetSqlBinary_LengthChecked( sink, setters, ordinal, metaData, (SqlBinary) value, offset ); break;
1617 case ExtendedClrTypeCode.SqlBoolean: SetSqlBoolean_Unchecked( sink, setters, ordinal, (SqlBoolean) value ); break;
1618 case ExtendedClrTypeCode.SqlByte: SetSqlByte_Unchecked( sink, setters, ordinal, (SqlByte) value ); break;
1619 case ExtendedClrTypeCode.SqlDateTime: SetSqlDateTime_Checked( sink, setters, ordinal, metaData, (SqlDateTime) value ); break;
1620 case ExtendedClrTypeCode.SqlDouble: SetSqlDouble_Unchecked( sink, setters, ordinal, (SqlDouble) value ); break;
1621 case ExtendedClrTypeCode.SqlGuid: SetSqlGuid_Unchecked( sink, setters, ordinal, (SqlGuid) value ); break;
1622 case ExtendedClrTypeCode.SqlInt16: SetSqlInt16_Unchecked( sink, setters, ordinal, (SqlInt16) value ); break;
1623 case ExtendedClrTypeCode.SqlInt32: SetSqlInt32_Unchecked( sink, setters, ordinal, (SqlInt32) value ); break;
1624 case ExtendedClrTypeCode.SqlInt64: SetSqlInt64_Unchecked( sink, setters, ordinal, (SqlInt64) value ); break;
1625 case ExtendedClrTypeCode.SqlMoney: SetSqlMoney_Checked( sink, setters, ordinal, metaData, (SqlMoney) value ); break;
1626 case ExtendedClrTypeCode.SqlDecimal: SetSqlDecimal_Unchecked( sink, setters, ordinal, (SqlDecimal) value ); break;
1627 case ExtendedClrTypeCode.SqlSingle: SetSqlSingle_Unchecked( sink, setters, ordinal, (SqlSingle) value ); break;
1628 case ExtendedClrTypeCode.SqlString: SetSqlString_LengthChecked( sink, setters, ordinal, metaData, (SqlString) value, offset ); break;
1629 case ExtendedClrTypeCode.SqlChars: SetSqlChars_LengthChecked( sink, setters, ordinal, metaData, (SqlChars) value, offset ); break;
1630 case ExtendedClrTypeCode.SqlBytes: SetSqlBytes_LengthChecked( sink, setters, ordinal, metaData, (SqlBytes) value, offset ); break;
1631 case ExtendedClrTypeCode.SqlXml: SetSqlXml_Unchecked( sink, setters, ordinal, (SqlXml) value ); break;
1632 case ExtendedClrTypeCode.Stream: SetStream_Unchecked(sink, setters, ordinal, metaData, (StreamDataFeed) value); break;
1633 case ExtendedClrTypeCode.TextReader: SetTextReader_Unchecked(sink, setters, ordinal, metaData, (TextDataFeed) value); break;
1634 case ExtendedClrTypeCode.XmlReader: SetXmlReader_Unchecked(sink, setters, ordinal, ((XmlDataFeed) value)._source); break;
1636 Debug.Assert( false, "Unvalidated extendedtypecode: " + typeCode );
1641 // VSTFDevDiv#479681 - Data corruption when sending Katmai Date types to the server via TVP
1642 // Ensures proper handling on DateTime2 sub type for Sql_Variants and TVPs.
1643 internal static void SetCompatibleValueV200(
1644 SmiEventSink_Default sink,
1645 SmiTypedGetterSetter setters,
1647 SmiMetaData metaData,
1649 ExtendedClrTypeCode typeCode,
1652 ParameterPeekAheadValue peekAhead,
1653 SqlBuffer.StorageType storageType
1656 // Ensure caller validated compatibility for types handled directly in this method
1657 Debug.Assert((ExtendedClrTypeCode.DataTable != typeCode &&
1658 ExtendedClrTypeCode.DbDataReader != typeCode &&
1659 ExtendedClrTypeCode.IEnumerableOfSqlDataRecord != typeCode) ||
1660 CanAccessSetterDirectly(metaData, typeCode), "Un-validated type '" + typeCode + "' for metaData: " + metaData.SqlDbType);
1662 if (typeCode == ExtendedClrTypeCode.DateTime)
1664 if (storageType == SqlBuffer.StorageType.DateTime2)
1665 SetDateTime2_Checked(sink, setters, ordinal, metaData, (DateTime)value);
1666 else if (storageType == SqlBuffer.StorageType.Date)
1667 SetDate_Checked(sink, setters, ordinal, metaData, (DateTime)value);
1669 SetDateTime_Checked(sink, setters, ordinal, metaData, (DateTime)value);
1673 SetCompatibleValueV200(sink, setters, ordinal, metaData, value, typeCode, offset, length, peekAhead);
1677 // Implements SqlClient 2.0-compatible SetValue() semantics + Orcas extensions
1678 // Assumes caller already validated basic type against the metadata, other than trimming lengths and
1679 // checking individual field values (TVPs)
1680 internal static void SetCompatibleValueV200(
1681 SmiEventSink_Default sink,
1682 SmiTypedGetterSetter setters,
1684 SmiMetaData metaData,
1686 ExtendedClrTypeCode typeCode,
1689 ParameterPeekAheadValue peekAhead
1691 // Ensure caller validated compatibility for types handled directly in this method
1692 Debug.Assert( (ExtendedClrTypeCode.DataTable != typeCode &&
1693 ExtendedClrTypeCode.DbDataReader != typeCode &&
1694 ExtendedClrTypeCode.IEnumerableOfSqlDataRecord != typeCode) ||
1695 CanAccessSetterDirectly(metaData, typeCode), "Un-validated type '" + typeCode + "' for metaData: " + metaData.SqlDbType);
1698 case ExtendedClrTypeCode.DataTable:
1699 SetDataTable_Unchecked(sink, setters, ordinal, metaData, (DataTable)value);
1701 case ExtendedClrTypeCode.DbDataReader:
1702 SetDbDataReader_Unchecked(sink, setters, ordinal, metaData, (DbDataReader)value);
1704 case ExtendedClrTypeCode.IEnumerableOfSqlDataRecord:
1705 SetIEnumerableOfSqlDataRecord_Unchecked(sink, setters, ordinal, metaData, (IEnumerable<SqlDataRecord>)value, peekAhead);
1707 case ExtendedClrTypeCode.TimeSpan:
1708 SetTimeSpan_Checked(sink, setters, ordinal, metaData, (TimeSpan)value);
1710 case ExtendedClrTypeCode.DateTimeOffset:
1711 SetDateTimeOffset_Unchecked(sink, setters, ordinal, (DateTimeOffset)value);
1714 SetCompatibleValue(sink, setters, ordinal, metaData, value, typeCode, offset);
1719 // Copy multiple fields from reader to ITypedSettersV3
1720 // Assumes caller enforces that reader and setter metadata are compatible
1721 internal static void FillCompatibleITypedSettersFromReader( SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataReader reader ) {
1722 for ( int i = 0; i < metaData.Length; i++ ) {
1723 if ( reader.IsDBNull(i) ) {
1724 ValueUtilsSmi.SetDBNull_Unchecked( sink, setters, i );
1727 switch ( metaData[i].SqlDbType ) {
1728 case SqlDbType.BigInt:
1729 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Int64 ) );
1730 ValueUtilsSmi.SetInt64_Unchecked( sink, setters, i, reader.GetInt64(i) );
1732 case SqlDbType.Binary:
1733 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
1734 ValueUtilsSmi.SetSqlBytes_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlBytes(i), 0 );
1737 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Boolean ) );
1738 SetBoolean_Unchecked( sink, setters, i, reader.GetBoolean(i) );
1740 case SqlDbType.Char:
1741 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlChars ) );
1742 SetSqlChars_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlChars(i), 0 );
1744 case SqlDbType.DateTime:
1745 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.DateTime ) );
1746 SetDateTime_Checked( sink, setters, i, metaData[i], reader.GetDateTime(i) );
1748 case SqlDbType.Decimal:
1749 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlDecimal ) );
1750 SetSqlDecimal_Unchecked( sink, setters, i, reader.GetSqlDecimal(i) );
1752 case SqlDbType.Float:
1753 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Double ) );
1754 SetDouble_Unchecked( sink, setters, i, reader.GetDouble(i) );
1756 case SqlDbType.Image:
1757 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
1758 SetSqlBytes_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlBytes(i), 0 );
1761 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Int32 ) );
1762 SetInt32_Unchecked( sink, setters, i, reader.GetInt32(i) );
1764 case SqlDbType.Money:
1765 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlMoney ) );
1766 SetSqlMoney_Unchecked( sink, setters, i, metaData[i], reader.GetSqlMoney(i) );
1768 case SqlDbType.NChar:
1769 case SqlDbType.NText:
1770 case SqlDbType.NVarChar:
1771 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlChars ) );
1772 SetSqlChars_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlChars(i), 0 );
1774 case SqlDbType.Real:
1775 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Single ) );
1776 SetSingle_Unchecked( sink, setters, i, reader.GetFloat(i) );
1778 case SqlDbType.UniqueIdentifier:
1779 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Guid ) );
1780 SetGuid_Unchecked( sink, setters, i, reader.GetGuid(i) );
1782 case SqlDbType.SmallDateTime:
1783 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.DateTime ) );
1784 SetDateTime_Checked( sink, setters, i, metaData[i], reader.GetDateTime(i) );
1786 case SqlDbType.SmallInt:
1787 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Int16 ) );
1788 SetInt16_Unchecked( sink, setters, i, reader.GetInt16(i) );
1790 case SqlDbType.SmallMoney:
1791 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlMoney ) );
1792 SetSqlMoney_Checked( sink, setters, i, metaData[i], reader.GetSqlMoney(i) );
1794 case SqlDbType.Text:
1795 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlChars ) );
1796 SetSqlChars_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlChars(i), 0 );
1798 case SqlDbType.Timestamp:
1799 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
1800 SetSqlBytes_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlBytes(i), 0 );
1802 case SqlDbType.TinyInt:
1803 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Byte ) );
1804 SetByte_Unchecked( sink, setters, i, reader.GetByte(i) );
1806 case SqlDbType.VarBinary:
1807 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
1808 SetSqlBytes_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlBytes(i), 0 );
1810 case SqlDbType.VarChar:
1811 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.String ) );
1812 SetSqlChars_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlChars(i), 0 );
1815 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlXml ) );
1816 SetSqlXml_Unchecked( sink, setters, i, reader.GetSqlXml(i) );
1818 case SqlDbType.Variant:
1819 object o = reader.GetSqlValue(i);
1820 ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCode( o );
1821 SetCompatibleValue( sink, setters, i, metaData[i], o, typeCode, 0 );
1825 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
1826 SetSqlBytes_LengthChecked( sink, setters, i, metaData[i], reader.GetSqlBytes(i), 0 );
1830 // In order for us to get here we would have to have an
1831 // invalid instance of SqlDbType, or one would have to add
1832 // new member to SqlDbType without adding a case in this
1833 // switch, hence the assert - it must be bug in our code
1834 // not invalid user parameters.
1835 Debug.Assert( false, "unsupported DbType:" + metaData[i].SqlDbType.ToString() );
1836 throw ADP.NotSupported();
1843 // Copy multiple fields from reader to SmiTypedGetterSetter
1844 // Supports V200 code path, without damaging backward compat for V100 code.
1845 // Main differences are supporting DbDataReader, and for binary, character, decimal and Udt types.
1846 // Assumes caller enforces that reader and setter metadata are compatible
1847 internal static void FillCompatibleSettersFromReader(SmiEventSink_Default sink, SmiTypedGetterSetter setters, IList<SmiExtendedMetaData> metaData, DbDataReader reader) {
1848 for (int i = 0; i < metaData.Count; i++) {
1849 if (reader.IsDBNull(i)) {
1850 ValueUtilsSmi.SetDBNull_Unchecked(sink, setters, i);
1853 switch (metaData[i].SqlDbType) {
1854 case SqlDbType.BigInt:
1855 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int64));
1856 SetInt64_Unchecked(sink, setters, i, reader.GetInt64(i));
1858 case SqlDbType.Binary:
1859 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.ByteArray));
1860 SetBytes_FromReader(sink, setters, i, metaData[i], reader, 0);
1863 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Boolean));
1864 SetBoolean_Unchecked(sink, setters, i, reader.GetBoolean(i));
1866 case SqlDbType.Char:
1867 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.CharArray));
1868 SetCharsOrString_FromReader(sink, setters, i, metaData[i], reader, 0);
1870 case SqlDbType.DateTime:
1871 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
1872 SetDateTime_Checked(sink, setters, i, metaData[i], reader.GetDateTime(i));
1874 case SqlDbType.Decimal: { // block to scope sqlReader local to avoid conflicts
1875 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlDecimal));
1876 // Support full fidelity for SqlDataReader
1877 SqlDataReader sqlReader = reader as SqlDataReader;
1878 if (null != sqlReader) {
1879 SetSqlDecimal_Unchecked(sink, setters, i, sqlReader.GetSqlDecimal(i));
1882 SetSqlDecimal_Unchecked(sink, setters, i, new SqlDecimal(reader.GetDecimal(i)));
1886 case SqlDbType.Float:
1887 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Double));
1888 SetDouble_Unchecked(sink, setters, i, reader.GetDouble(i));
1890 case SqlDbType.Image:
1891 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.ByteArray));
1892 SetBytes_FromReader(sink, setters, i, metaData[i], reader, 0);
1895 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int32));
1896 SetInt32_Unchecked(sink, setters, i, reader.GetInt32(i));
1898 case SqlDbType.Money:
1899 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney));
1900 SetSqlMoney_Checked(sink, setters, i, metaData[i], new SqlMoney(reader.GetDecimal(i)));
1902 case SqlDbType.NChar:
1903 case SqlDbType.NText:
1904 case SqlDbType.NVarChar:
1905 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.CharArray));
1906 SetCharsOrString_FromReader(sink, setters, i, metaData[i], reader, 0);
1908 case SqlDbType.Real:
1909 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Single));
1910 SetSingle_Unchecked(sink, setters, i, reader.GetFloat(i));
1912 case SqlDbType.UniqueIdentifier:
1913 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Guid));
1914 SetGuid_Unchecked(sink, setters, i, reader.GetGuid(i));
1916 case SqlDbType.SmallDateTime:
1917 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
1918 SetDateTime_Checked(sink, setters, i,metaData[i], reader.GetDateTime(i));
1920 case SqlDbType.SmallInt:
1921 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int16));
1922 SetInt16_Unchecked(sink, setters, i, reader.GetInt16(i));
1924 case SqlDbType.SmallMoney:
1925 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney));
1926 SetSqlMoney_Checked(sink, setters, i, metaData[i], new SqlMoney(reader.GetDecimal(i)));
1928 case SqlDbType.Text:
1929 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.CharArray));
1930 SetCharsOrString_FromReader(sink, setters, i, metaData[i], reader, 0);
1932 case SqlDbType.Timestamp:
1933 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.ByteArray));
1934 SetBytes_FromReader(sink, setters, i, metaData[i], reader, 0);
1936 case SqlDbType.TinyInt:
1937 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Byte));
1938 SetByte_Unchecked(sink, setters, i, reader.GetByte(i));
1940 case SqlDbType.VarBinary:
1941 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.ByteArray));
1942 SetBytes_FromReader(sink, setters, i, metaData[i], reader, 0);
1944 case SqlDbType.VarChar:
1945 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.String));
1946 SetCharsOrString_FromReader(sink, setters, i, metaData[i], reader, 0);
1948 case SqlDbType.Xml: {
1949 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlXml));
1950 SqlDataReader sqlReader = reader as SqlDataReader;
1951 if (null != sqlReader) {
1952 SetSqlXml_Unchecked(sink, setters, i, sqlReader.GetSqlXml(i));
1955 SetBytes_FromReader(sink, setters, i, metaData[i], reader, 0);
1959 case SqlDbType.Variant: { // block to scope sqlReader local and avoid conflicts
1960 // Support better options for SqlDataReader
1961 SqlDataReader sqlReader = reader as SqlDataReader;
1962 SqlBuffer.StorageType storageType = SqlBuffer.StorageType.Empty;
1964 if (null != sqlReader) {
1965 o = sqlReader.GetSqlValue(i);
1966 storageType = sqlReader.GetVariantInternalStorageType(i);
1969 o = reader.GetValue(i);
1971 ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType(metaData[i].SqlDbType, metaData[i].IsMultiValued, o, null,
1974 SmiContextFactory.KatmaiVersion
1976 if ((storageType == SqlBuffer.StorageType.DateTime2) || (storageType == SqlBuffer.StorageType.Date))
1977 SetCompatibleValueV200(sink, setters, i, metaData[i], o, typeCode, 0, 0, null, storageType);
1979 SetCompatibleValueV200(sink, setters, i, metaData[i], o, typeCode, 0, 0, null);
1984 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.ByteArray));
1985 // Skip serialization for Udt types.
1986 SetBytes_FromReader(sink, setters, i, metaData[i], reader, 0);
1989 // SqlDbType.Structured should have been caught before this point for TVPs. SUDTs will still need to implement.
1991 case SqlDbType.Date:
1992 case SqlDbType.DateTime2:
1993 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
1994 SetDateTime_Checked(sink, setters, i, metaData[i], reader.GetDateTime(i));
1996 case SqlDbType.Time: { // block to scope sqlReader local and avoid conflicts
1997 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.TimeSpan));
1998 SqlDataReader sqlReader = reader as SqlDataReader;
2000 if (null != sqlReader) {
2001 ts = sqlReader.GetTimeSpan(i);
2003 ts = (TimeSpan)reader.GetValue(i);
2005 SetTimeSpan_Checked(sink, setters, i, metaData[i], ts);
2008 case SqlDbType.DateTimeOffset: { // block to scope sqlReader local and avoid conflicts
2009 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTimeOffset));
2010 SqlDataReader sqlReader = reader as SqlDataReader;
2012 if (null != sqlReader) {
2013 dto = sqlReader.GetDateTimeOffset(i);
2015 dto = (DateTimeOffset)reader.GetValue(i);
2017 SetDateTimeOffset_Unchecked(sink, setters, i, dto);
2022 // In order for us to get here we would have to have an
2023 // invalid instance of SqlDbType, or one would have to add
2024 // new member to SqlDbType without adding a case in this
2025 // switch, hence the assert - it must be bug in our code
2026 // not invalid user parameters.
2027 Debug.Assert(false, "unsupported DbType:" + metaData[i].SqlDbType.ToString());
2028 throw ADP.NotSupported();
2035 internal static void FillCompatibleITypedSettersFromRecord(SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataRecord record) {
2036 FillCompatibleITypedSettersFromRecord(sink, setters, metaData, record, null);
2039 internal static void FillCompatibleITypedSettersFromRecord(SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataRecord record, SmiDefaultFieldsProperty useDefaultValues) {
2040 for (int i = 0; i < metaData.Length; ++i) {
2041 if (null != useDefaultValues && useDefaultValues[i]) {
2044 if (record.IsDBNull(i)) {
2045 ValueUtilsSmi.SetDBNull_Unchecked(sink, setters, i);
2047 switch (metaData[i].SqlDbType) {
2048 case SqlDbType.BigInt:
2049 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Int64 ) );
2050 SetInt64_Unchecked( sink, setters, i, record.GetInt64(i) );
2052 case SqlDbType.Binary:
2053 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
2054 SetBytes_FromRecord( sink, setters, i, metaData[i], record, 0 );
2057 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Boolean ) );
2058 SetBoolean_Unchecked( sink, setters, i, record.GetBoolean(i) );
2060 case SqlDbType.Char:
2061 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlChars ) );
2062 SetChars_FromRecord( sink, setters, i, metaData[i], record, 0 );
2064 case SqlDbType.DateTime:
2065 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.DateTime ) );
2066 SetDateTime_Checked( sink, setters, i, metaData[i], record.GetDateTime(i) );
2068 case SqlDbType.Decimal:
2069 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlDecimal ) );
2070 SetSqlDecimal_Unchecked( sink, setters, i, record.GetSqlDecimal(i) );
2072 case SqlDbType.Float:
2073 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Double ) );
2074 SetDouble_Unchecked( sink, setters, i, record.GetDouble(i) );
2076 case SqlDbType.Image:
2077 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
2078 SetBytes_FromRecord( sink, setters, i, metaData[i], record, 0 );
2081 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Int32 ) );
2082 SetInt32_Unchecked( sink, setters, i, record.GetInt32(i) );
2084 case SqlDbType.Money:
2085 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlMoney ) );
2086 SetSqlMoney_Unchecked( sink, setters, i, metaData[i], record.GetSqlMoney(i) );
2088 case SqlDbType.NChar:
2089 case SqlDbType.NText:
2090 case SqlDbType.NVarChar:
2091 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlChars ) );
2092 SetChars_FromRecord( sink, setters, i, metaData[i], record, 0 );
2094 case SqlDbType.Real:
2095 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Single ) );
2096 SetSingle_Unchecked( sink, setters, i, record.GetFloat(i) );
2098 case SqlDbType.UniqueIdentifier:
2099 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Guid ) );
2100 SetGuid_Unchecked( sink, setters, i, record.GetGuid(i) );
2102 case SqlDbType.SmallDateTime:
2103 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.DateTime ) );
2104 SetDateTime_Checked( sink, setters, i, metaData[i], record.GetDateTime(i) );
2106 case SqlDbType.SmallInt:
2107 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Int16 ) );
2108 SetInt16_Unchecked( sink, setters, i, record.GetInt16(i) );
2110 case SqlDbType.SmallMoney:
2111 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlMoney ) );
2112 SetSqlMoney_Checked( sink, setters, i, metaData[i], record.GetSqlMoney(i) );
2114 case SqlDbType.Text:
2115 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlChars ) );
2116 SetChars_FromRecord( sink, setters, i, metaData[i], record, 0 );
2118 case SqlDbType.Timestamp:
2119 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
2120 SetBytes_FromRecord( sink, setters, i, metaData[i], record, 0 );
2122 case SqlDbType.TinyInt:
2123 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.Byte ) );
2124 SetByte_Unchecked( sink, setters, i, record.GetByte(i) );
2126 case SqlDbType.VarBinary:
2127 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
2128 SetBytes_FromRecord( sink, setters, i, metaData[i], record, 0 );
2130 case SqlDbType.VarChar:
2131 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.String ) );
2132 SetChars_FromRecord( sink, setters, i, metaData[i], record, 0 );
2135 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlXml ) );
2136 SetSqlXml_Unchecked( sink, setters, i, record.GetSqlXml(i) ); // perf improvement?
2138 case SqlDbType.Variant:
2139 object o = record.GetSqlValue(i);
2140 ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCode( o );
2141 SetCompatibleValue( sink, setters, i, metaData[i], o, typeCode, 0 );
2144 Debug.Assert( CanAccessSetterDirectly( metaData[i], ExtendedClrTypeCode.SqlBytes ) );
2145 SetBytes_FromRecord( sink, setters, i, metaData[i], record, 0 );
2148 Debug.Assert( false, "unsupported DbType:" + metaData[i].SqlDbType.ToString() );
2149 throw ADP.NotSupported();
2155 internal static void FillCompatibleSettersFromRecord(SmiEventSink_Default sink, SmiTypedGetterSetter setters, SmiMetaData[] metaData, SqlDataRecord record, SmiDefaultFieldsProperty useDefaultValues)
2157 for (int i = 0; i < metaData.Length; ++i)
2159 if (null != useDefaultValues && useDefaultValues[i])
2163 if (record.IsDBNull(i))
2165 ValueUtilsSmi.SetDBNull_Unchecked(sink, setters, i);
2169 switch (metaData[i].SqlDbType)
2171 case SqlDbType.BigInt:
2172 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int64));
2173 SetInt64_Unchecked(sink, setters, i, record.GetInt64(i));
2175 case SqlDbType.Binary:
2176 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
2177 SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
2180 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Boolean));
2181 SetBoolean_Unchecked(sink, setters, i, record.GetBoolean(i));
2183 case SqlDbType.Char:
2184 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars));
2185 SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
2187 case SqlDbType.DateTime:
2188 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
2189 SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i));
2191 case SqlDbType.Decimal:
2192 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlDecimal));
2193 SetSqlDecimal_Unchecked(sink, setters, i, record.GetSqlDecimal(i));
2195 case SqlDbType.Float:
2196 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Double));
2197 SetDouble_Unchecked(sink, setters, i, record.GetDouble(i));
2199 case SqlDbType.Image:
2200 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
2201 SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
2204 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int32));
2205 SetInt32_Unchecked(sink, setters, i, record.GetInt32(i));
2207 case SqlDbType.Money:
2208 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney));
2209 SetSqlMoney_Unchecked(sink, setters, i, metaData[i], record.GetSqlMoney(i));
2211 case SqlDbType.NChar:
2212 case SqlDbType.NText:
2213 case SqlDbType.NVarChar:
2214 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars));
2215 SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
2217 case SqlDbType.Real:
2218 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Single));
2219 SetSingle_Unchecked(sink, setters, i, record.GetFloat(i));
2221 case SqlDbType.UniqueIdentifier:
2222 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Guid));
2223 SetGuid_Unchecked(sink, setters, i, record.GetGuid(i));
2225 case SqlDbType.SmallDateTime:
2226 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
2227 SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i));
2229 case SqlDbType.SmallInt:
2230 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int16));
2231 SetInt16_Unchecked(sink, setters, i, record.GetInt16(i));
2233 case SqlDbType.SmallMoney:
2234 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney));
2235 SetSqlMoney_Checked(sink, setters, i, metaData[i], record.GetSqlMoney(i));
2237 case SqlDbType.Text:
2238 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars));
2239 SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
2241 case SqlDbType.Timestamp:
2242 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
2243 SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
2245 case SqlDbType.TinyInt:
2246 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Byte));
2247 SetByte_Unchecked(sink, setters, i, record.GetByte(i));
2249 case SqlDbType.VarBinary:
2250 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
2251 SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
2253 case SqlDbType.VarChar:
2254 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.String));
2255 SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
2258 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlXml));
2259 SetSqlXml_Unchecked(sink, setters, i, record.GetSqlXml(i)); // perf improvement?
2261 case SqlDbType.Variant:
2262 object o = record.GetSqlValue(i);
2263 ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCode(o);
2264 SetCompatibleValueV200(sink, setters, i, metaData[i], o, typeCode, 0, -1 /* no length restriction */, null /* no peekahead */);
2267 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
2268 SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
2270 case SqlDbType.Date:
2271 case SqlDbType.DateTime2:
2272 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
2273 SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i));
2275 case SqlDbType.Time:
2276 { // block to scope sqlReader local and avoid conflicts
2277 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.TimeSpan));
2278 SqlDataRecord sqlRecord = record as SqlDataRecord;
2280 if (null != sqlRecord)
2282 ts = sqlRecord.GetTimeSpan(i);
2286 ts = (TimeSpan)record.GetValue(i);
2288 SetTimeSpan_Checked(sink, setters, i, metaData[i], ts);
2291 case SqlDbType.DateTimeOffset:
2292 { // block to scope sqlReader local and avoid conflicts
2293 Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTimeOffset));
2294 SqlDataRecord sqlRecord = record as SqlDataRecord;
2296 if (null != sqlRecord)
2298 dto = sqlRecord.GetDateTimeOffset(i);
2302 dto = (DateTimeOffset)record.GetValue(i);
2304 SetDateTimeOffset_Unchecked(sink, setters, i, dto);
2309 Debug.Assert(false, "unsupported DbType:" + metaData[i].SqlDbType.ToString());
2310 throw ADP.NotSupported();
2316 // spool a Stream into a scratch stream from the Smi interface and return it as a Stream
2317 internal static Stream CopyIntoNewSmiScratchStream( Stream source, SmiEventSink_Default sink, SmiContext context ) {
2319 if (null == context) {
2320 dest = new MemoryStream();
2323 dest = new SqlClientWrapperSmiStream( sink, context.GetScratchStream( sink ) );
2327 if ( source.CanSeek && __maxByteChunkSize > source.Length ) {
2328 chunkSize = unchecked( (int) source.Length ); // unchecked cast is safe due to check on line above
2331 chunkSize = __maxByteChunkSize;
2334 byte[] copyBuffer = new byte[chunkSize];
2336 while ( 0 != ( bytesRead = source.Read( copyBuffer, 0, chunkSize ) ) ) {
2337 dest.Write( copyBuffer, 0, bytesRead );
2342 // Need to re-wind scratch stream to beginning before returning
2343 dest.Seek(0, SeekOrigin.Begin);
2348 // spool a Stream into a scratch stream from the Smi interface and return it as a SqlStreamChars
2349 internal static SqlStreamChars CopyIntoNewSmiScratchStreamChars( Stream source, SmiEventSink_Default sink, SmiContext context ) {
2350 SqlClientWrapperSmiStreamChars dest = new SqlClientWrapperSmiStreamChars( sink, context.GetScratchStream( sink ) );
2353 if ( source.CanSeek && __maxByteChunkSize > source.Length ) {
2354 chunkSize = unchecked( (int) source.Length ); // unchecked cast is safe due to check on line above
2357 chunkSize = __maxByteChunkSize;
2360 byte[] copyBuffer = new byte[chunkSize];
2362 while ( 0 != ( bytesRead = source.Read( copyBuffer, 0, chunkSize ) ) ) {
2363 dest.Write( copyBuffer, 0, bytesRead );
2368 // Need to re-wind scratch stream to beginning before returning
2369 dest.Seek(0, SeekOrigin.Begin);
2375 // Common utility code to get lengths correct for trimming
2377 private static object GetUdt_LengthChecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData ) {
2379 if (IsDBNull_Unchecked(sink, getters, ordinal)) {
2380 Type t = metaData.Type;
2381 Debug.Assert(t != null, "Unexpected null of udtType on GetUdt_LengthChecked!");
2382 result = t.InvokeMember("Null", BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Static, null, null, new Object[]{}, CultureInfo.InvariantCulture);
2383 Debug.Assert(result != null);
2386 // Note: do not need to copy getter stream, since it will not be used beyond
2387 // deserialization (valid lifetime of getters is limited).
2388 Stream s = new SmiGettersStream( sink, getters, ordinal, metaData );
2389 result = SerializationHelperSql9.Deserialize( s, metaData.Type );
2393 private static Decimal GetDecimal_PossiblyMoney(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData) {
2394 if (SqlDbType.Decimal == metaData.SqlDbType) {
2395 return GetSqlDecimal_Unchecked( sink, getters, ordinal ).Value;
2398 Debug.Assert( SqlDbType.Money == metaData.SqlDbType ||
2399 SqlDbType.SmallMoney == metaData.SqlDbType,
2400 "Unexpected sqldbtype=" + metaData.SqlDbType);
2401 return GetSqlMoney_Unchecked( sink, getters, ordinal ).Value;
2405 private static void SetDecimal_PossiblyMoney(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, Decimal value) {
2406 if (SqlDbType.Decimal == metaData.SqlDbType || SqlDbType.Variant == metaData.SqlDbType) {
2407 SetDecimal_Unchecked( sink, setters, ordinal, value );
2410 Debug.Assert( SqlDbType.Money == metaData.SqlDbType ||
2411 SqlDbType.SmallMoney == metaData.SqlDbType,
2412 "Unexpected sqldbtype=" + metaData.SqlDbType);
2413 SetSqlMoney_Checked( sink, setters, ordinal, metaData, new SqlMoney(value) );
2417 // Hard coding smalldatetime limits...
2418 private static readonly DateTime x_dtSmallMax = new DateTime(2079, 06, 06, 23, 59, 29, 998);
2419 private static readonly DateTime x_dtSmallMin = new DateTime(1899, 12, 31, 23, 59, 29, 999);
2420 private static void VerifyDateTimeRange(SqlDbType dbType, DateTime value) {
2421 if (SqlDbType.SmallDateTime == dbType && (x_dtSmallMax < value || x_dtSmallMin > value)) {
2422 throw ADP.InvalidMetaDataValue();
2426 private static readonly TimeSpan x_timeMin = TimeSpan.Zero;
2427 private static readonly TimeSpan x_timeMax = new TimeSpan(TimeSpan.TicksPerDay - 1);
2428 private static void VerifyTimeRange(SqlDbType dbType, TimeSpan value) {
2429 if (SqlDbType.Time == dbType && (x_timeMin > value || value > x_timeMax)) {
2430 throw ADP.InvalidMetaDataValue();
2434 private static void SetDateTime_Checked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTime value) {
2435 VerifyDateTimeRange(metaData.SqlDbType, value);
2436 SetDateTime_Unchecked(sink, setters, ordinal, ((SqlDbType.Date == metaData.SqlDbType) ? value.Date : value));
2439 private static void SetTimeSpan_Checked(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, SmiMetaData metaData, TimeSpan value) {
2440 VerifyTimeRange(metaData.SqlDbType, value);
2441 SetTimeSpan_Unchecked(sink, setters, ordinal, value);
2444 private static void SetSqlDateTime_Checked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDateTime value) {
2445 if (!value.IsNull) {
2446 VerifyDateTimeRange(metaData.SqlDbType, value.Value);
2448 SetSqlDateTime_Unchecked(sink, setters, ordinal, value);
2451 private static void SetDateTime2_Checked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTime value)
2453 VerifyDateTimeRange(metaData.SqlDbType, value);
2454 SetDateTime2_Unchecked(sink, setters, ordinal, metaData, value);
2457 private static void SetDate_Checked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTime value)
2459 VerifyDateTimeRange(metaData.SqlDbType, value);
2460 SetDate_Unchecked(sink, setters, ordinal, metaData, value);
2463 private static void SetSqlMoney_Checked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlMoney value) {
2464 if (!value.IsNull && SqlDbType.SmallMoney == metaData.SqlDbType) {
2465 decimal decimalValue = value.Value;
2466 if (TdsEnums.SQL_SMALL_MONEY_MIN > decimalValue || TdsEnums.SQL_SMALL_MONEY_MAX < decimalValue) {
2467 throw SQL.MoneyOverflow(decimalValue.ToString(CultureInfo.InvariantCulture));
2470 SetSqlMoney_Unchecked(sink, setters, ordinal, metaData, value);
2473 private static void SetByteArray_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, byte[] buffer, int offset ) {
2474 int length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, buffer.Length, offset, buffer.Length - offset );
2475 Debug.Assert( length >= 0, "buffer.Length was invalid!" );
2476 SetByteArray_Unchecked( sink, setters, ordinal, buffer, offset, length );
2479 private static void SetCharArray_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, char[] buffer, int offset ) {
2480 int length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, buffer.Length, offset, buffer.Length - offset );
2481 Debug.Assert( length >= 0, "buffer.Length was invalid!" );
2482 SetCharArray_Unchecked( sink, setters, ordinal, buffer, offset, length );
2485 private static void SetSqlBinary_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlBinary value, int offset ) {
2487 if ( !value.IsNull ) {
2488 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, value.Length, offset, value.Length - offset );
2489 Debug.Assert( length >= 0, "value.Length was invalid!" );
2491 SetSqlBinary_Unchecked( sink, setters, ordinal, value, offset, length );
2494 private static void SetBytes_FromRecord( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDataRecord record, int offset ) {
2497 // Deal with large values by sending bufferLength of NoLengthLimit (== assume
2498 // CheckXetParameters will ignore requested-length checks in this case
2499 long bufferLength = record.GetBytes(ordinal, 0, null, 0, 0);
2500 if ( bufferLength > Int32.MaxValue ) {
2501 bufferLength = NoLengthLimit;
2503 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, checked( (int) bufferLength ), offset, checked( (int) bufferLength ) );
2506 if ( length > __maxByteChunkSize || length < 0 ) {
2507 chunkSize = __maxByteChunkSize;
2510 chunkSize = checked( (int)length );
2513 byte[] buffer = new byte[ chunkSize ];
2515 long bytesWritten = 1; // prime value to get into write loop
2516 long currentOffset = offset;
2517 long lengthWritten = 0;
2519 while ( (length < 0 || lengthWritten < length) &&
2520 0 != ( bytesRead = record.GetBytes( ordinal, currentOffset, buffer, 0, chunkSize ) ) &&
2521 0 != bytesWritten ) {
2522 bytesWritten = setters.SetBytes( sink, ordinal, currentOffset, buffer, 0, checked( (int) bytesRead ) );
2523 sink.ProcessMessagesAndThrow();
2524 checked{ currentOffset += bytesWritten; }
2525 checked{ lengthWritten += bytesWritten; }
2528 // Make sure to trim any left-over data
2529 setters.SetBytesLength( sink, ordinal, currentOffset );
2530 sink.ProcessMessagesAndThrow();
2533 private static void SetBytes_FromReader(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, SmiMetaData metaData, DbDataReader reader, int offset) {
2536 // Deal with large values by sending bufferLength of NoLengthLimit (== assume
2537 // CheckXetParameters will ignore requested-length checks in this case)
2538 length = CheckXetParameters(metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, NoLengthLimit /* buffer length */, offset, NoLengthLimit /* requested length */ );
2540 // Use fixed chunk size for all cases to avoid inquiring from reader.
2541 int chunkSize = __maxByteChunkSize;
2543 byte[] buffer = new byte[ chunkSize ];
2545 long bytesWritten = 1; // prime value to get into write loop
2546 long currentOffset = offset;
2547 long lengthWritten = 0;
2549 while ((length < 0 || lengthWritten < length) &&
2550 0 != (bytesRead = reader.GetBytes(ordinal, currentOffset, buffer, 0, chunkSize)) &&
2551 0 != bytesWritten) {
2552 bytesWritten = setters.SetBytes(sink, ordinal, currentOffset, buffer, 0, checked((int) bytesRead));
2553 sink.ProcessMessagesAndThrow();
2554 checked{ currentOffset += bytesWritten; }
2555 checked{ lengthWritten += bytesWritten; }
2558 // Make sure to trim any left-over data (remember to trim at end of offset, not just the amount written
2559 setters.SetBytesLength(sink, ordinal, currentOffset);
2560 sink.ProcessMessagesAndThrow();
2563 private static void SetSqlBytes_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlBytes value, int offset ) {
2565 if ( !value.IsNull ) {
2566 // Deal with large values by sending bufferLength of NoLengthLimit (== assume
2567 // CheckXetParameters will ignore requested-length checks in this case
2568 long bufferLength = value.Length;
2569 if ( bufferLength > Int32.MaxValue ) {
2570 bufferLength = NoLengthLimit;
2572 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, checked( (int) bufferLength ), offset, checked( (int) bufferLength ) );
2574 SetSqlBytes_Unchecked( sink, setters, ordinal, value, 0, length );
2577 private static void SetChars_FromRecord( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDataRecord record, int offset ) {
2580 // Deal with large values by sending bufferLength of NoLengthLimit
2581 // CheckXetParameters will ignore length checks in this case
2582 long bufferLength = record.GetChars(ordinal, 0, null, 0, 0);
2583 if ( bufferLength > Int32.MaxValue ) {
2584 bufferLength = NoLengthLimit;
2586 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, checked( (int) bufferLength ), offset, checked( (int) bufferLength - offset ) );
2589 if ( length > __maxCharChunkSize || length < 0 ) {
2590 if (MetaDataUtilsSmi.IsAnsiType(metaData.SqlDbType)) {
2591 chunkSize = __maxByteChunkSize;
2593 chunkSize = __maxCharChunkSize;
2597 chunkSize = checked( (int)length );
2600 char[] buffer = new char[ chunkSize ];
2602 long charsWritten = 1; // prime value to get into write loop
2603 long currentOffset = offset;
2604 long lengthWritten = 0;
2606 while ( (length < 0 || lengthWritten < length) &&
2607 0 != ( charsRead = record.GetChars( ordinal, currentOffset, buffer, 0, chunkSize ) ) &&
2608 0 != charsWritten ) {
2609 charsWritten = setters.SetChars( sink, ordinal, currentOffset, buffer, 0, checked( (int) charsRead ) );
2610 sink.ProcessMessagesAndThrow();
2611 checked{ currentOffset += charsWritten; }
2612 checked{ lengthWritten += charsWritten;}
2615 // Make sure to trim any left-over data
2616 setters.SetCharsLength( sink, ordinal, currentOffset );
2617 sink.ProcessMessagesAndThrow();
2620 // Transfer a character value from a reader when we're not sure which GetXXX method the reader will support.
2621 // Prefers to chunk data via GetChars, but falls back to GetString if that fails.
2622 // Mainly put in place because DataTableReader doesn't support GetChars on string columns, but others could fail too...
2623 private static void SetCharsOrString_FromReader(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, SmiMetaData metaData, DbDataReader reader, int offset) {
2624 bool success = false;
2626 SetChars_FromReader(sink, setters, ordinal, metaData, reader, offset);
2629 catch(Exception e) {
2630 if (!ADP.IsCatchableExceptionType(e)) {
2636 SetString_FromReader(sink, setters, ordinal, metaData, reader, offset);
2640 // Use chunking via SetChars to transfer a value from a reader to a gettersetter
2641 private static void SetChars_FromReader(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, SmiMetaData metaData, DbDataReader reader, int offset) {
2644 // Deal with large values by sending bufferLength of NoLengthLimit (== assume
2645 // CheckXetParameters will ignore requested-length checks in this case)
2646 length = CheckXetParameters(metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, NoLengthLimit /* buffer length */, offset, NoLengthLimit /* requested length */ );
2648 // Use fixed chunk size for all cases to avoid inquiring from reader.
2650 if (MetaDataUtilsSmi.IsAnsiType(metaData.SqlDbType)) {
2651 chunkSize = __maxByteChunkSize;
2653 chunkSize = __maxCharChunkSize;
2656 char[] buffer = new char[ chunkSize ];
2658 long charsWritten = 1; // prime value to get into write loop
2659 long currentOffset = offset;
2660 long lengthWritten = 0;
2662 while ((length < 0 || lengthWritten < length) &&
2663 0 != (charsRead = reader.GetChars(ordinal, currentOffset, buffer, 0, chunkSize)) &&
2664 0 != charsWritten) {
2665 charsWritten = setters.SetChars(sink, ordinal, currentOffset, buffer, 0, checked((int) charsRead));
2666 sink.ProcessMessagesAndThrow();
2667 checked{ currentOffset += charsWritten; }
2668 checked{ lengthWritten += charsWritten; }
2671 // Make sure to trim any left-over data (remember to trim at end of offset, not just the amount written
2672 setters.SetCharsLength(sink, ordinal, currentOffset);
2673 sink.ProcessMessagesAndThrow();
2676 private static void SetString_FromReader(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, SmiMetaData metaData, DbDataReader reader, int offset) {
2677 string value = reader.GetString(ordinal);
2678 int length = CheckXetParameters(metaData.SqlDbType, metaData.MaxLength, value.Length, 0, NoLengthLimit /* buffer */, offset, NoLengthLimit /* request */);
2680 setters.SetString(sink, ordinal, value, offset, length);
2681 sink.ProcessMessagesAndThrow();
2684 private static void SetSqlChars_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlChars value, int offset ) {
2686 if ( !value.IsNull ) {
2687 // Deal with large values by sending bufferLength of NoLengthLimit
2688 // CheckXetParameters will ignore length checks in this case
2689 long bufferLength = value.Length;
2690 if ( bufferLength > Int32.MaxValue ) {
2691 bufferLength = NoLengthLimit;
2693 length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, checked( (int) bufferLength ), offset, checked( (int) bufferLength - offset ) );
2695 SetSqlChars_Unchecked( sink, setters, ordinal, value, 0, length );
2698 private static void SetSqlString_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlString value, int offset ) {
2699 if ( value.IsNull ) {
2700 SetDBNull_Unchecked( sink, setters, ordinal );
2703 string stringValue = value.Value;
2704 int length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, stringValue.Length, offset, stringValue.Length - offset );
2705 Debug.Assert( length >= 0, "value.Length was invalid!" );
2706 SetSqlString_Unchecked( sink, setters, ordinal, metaData, value, offset, length );
2710 private static void SetString_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, string value, int offset ) {
2711 int length = CheckXetParameters( metaData.SqlDbType, metaData.MaxLength, NoLengthLimit /* actual */, 0, value.Length, offset, checked( value.Length - offset ) );
2712 Debug.Assert( length >= 0, "value.Length was invalid!" );
2713 SetString_Unchecked( sink, setters, ordinal, value, offset, length );
2716 private static void SetUdt_LengthChecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, object value ) {
2717 if ( ADP.IsNull( value ) ) {
2718 setters.SetDBNull( sink, ordinal );
2719 sink.ProcessMessagesAndThrow();
2722 System.IO.Stream target = new SmiSettersStream( sink, setters, ordinal, metaData );
2723 SerializationHelperSql9.Serialize( target, value );
2728 // Semantics support routines
2731 private static void ThrowIfInvalidSetterAccess( SmiMetaData metaData, ExtendedClrTypeCode setterTypeCode ) {
2732 if ( !CanAccessSetterDirectly( metaData, setterTypeCode ) ) {
2733 throw ADP.InvalidCast();
2737 private static void ThrowIfITypedGettersIsNull( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
2738 if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
2739 throw SQL.SqlNullValue();
2743 private static bool CanAccessGetterDirectly( SmiMetaData metaData, ExtendedClrTypeCode setterTypeCode ) {
2744 // Make sure no-one adds new ExtendedType, nor SqlDbType without updating this file!
2745 Debug.Assert( ExtendedClrTypeCode.First == 0 && (int)ExtendedClrTypeCode.Last == __canAccessGetterDirectly.GetLength(0) - 1, "ExtendedClrTypeCodes does not match with __canAccessGetterDirectly" );
2746 Debug.Assert( SqlDbType.BigInt == 0 && (int)SqlDbType.DateTimeOffset == __canAccessGetterDirectly.GetLength(1) - 1, "SqlDbType does not match with __canAccessGetterDirectly" );
2747 Debug.Assert( ExtendedClrTypeCode.First <= setterTypeCode && ExtendedClrTypeCode.Last >= setterTypeCode );
2748 Debug.Assert( SqlDbType.BigInt <= metaData.SqlDbType && SqlDbType.DateTimeOffset >= metaData.SqlDbType );
2750 bool returnValue = __canAccessGetterDirectly[(int)setterTypeCode, (int)metaData.SqlDbType];
2752 // Additional restrictions to distinguish TVPs and Structured UDTs
2754 (ExtendedClrTypeCode.DataTable == setterTypeCode ||
2755 ExtendedClrTypeCode.DbDataReader == setterTypeCode ||
2756 ExtendedClrTypeCode.IEnumerableOfSqlDataRecord == setterTypeCode)) {
2757 returnValue = metaData.IsMultiValued;
2763 private static bool CanAccessSetterDirectly( SmiMetaData metaData, ExtendedClrTypeCode setterTypeCode ) {
2764 // Make sure no-one adds new ExtendedType, nor SqlDbType without updating this file!
2765 Debug.Assert( ExtendedClrTypeCode.First == 0 && (int)ExtendedClrTypeCode.Last == __canAccessSetterDirectly.GetLength(0) - 1, "ExtendedClrTypeCodes does not match with __canAccessSetterDirectly" );
2766 Debug.Assert( SqlDbType.BigInt == 0 && (int)SqlDbType.DateTimeOffset == __canAccessSetterDirectly.GetLength(1) - 1, "SqlDbType does not match with __canAccessSetterDirectly" );
2767 Debug.Assert( ExtendedClrTypeCode.First <= setterTypeCode && ExtendedClrTypeCode.Last >= setterTypeCode );
2768 Debug.Assert( SqlDbType.BigInt <= metaData.SqlDbType && SqlDbType.DateTimeOffset >= metaData.SqlDbType );
2770 bool returnValue = __canAccessSetterDirectly[(int)setterTypeCode, (int)metaData.SqlDbType];
2772 // Additional restrictions to distinguish TVPs and Structured UDTs
2774 (ExtendedClrTypeCode.DataTable == setterTypeCode ||
2775 ExtendedClrTypeCode.DbDataReader == setterTypeCode ||
2776 ExtendedClrTypeCode.IEnumerableOfSqlDataRecord == setterTypeCode)) {
2777 returnValue = metaData.IsMultiValued;
2783 private static long PositiveMin(long first, long second) {
2792 return Math.Min(first, second);
2795 // Check Get Byte/Chars parameters, throw or adjust invalid values
2796 private static int CheckXetParameters(
2804 if ( 0 > fieldOffset )
2805 throw ADP.NegativeParameter("fieldOffset");
2807 // if negative buffer index, throw
2808 if ( bufferOffset < 0 ) {
2809 throw ADP.InvalidDestinationBufferIndex( bufferLength, bufferOffset, "bufferOffset" );
2812 // skip further length checks for LOB buffer lengths
2813 if(bufferLength < 0){
2814 length = checked((int) PositiveMin(length, PositiveMin(maxLength, actualLength)));
2815 if (length < NoLengthLimit) {
2816 length = NoLengthLimit;
2821 // if bad buffer index, throw
2822 if ( bufferOffset > bufferLength ) {
2823 throw ADP.InvalidDestinationBufferIndex( bufferLength, bufferOffset, "bufferOffset" );
2826 // if there is not enough room in the buffer for data
2827 if ( checked( length + bufferOffset ) > bufferLength )
2828 throw ADP.InvalidBufferSizeOrIndex( length, bufferOffset );
2831 throw ADP.InvalidDataLength( length );
2833 if ( 0 <= actualLength && actualLength <= fieldOffset ) {
2837 // trim length against both bufferLength and actual or max length
2838 // (actual or max < 0 means don't trim against that value)
2839 // Note that parameter UDTs don't know the correct maxlength, so the back end does
2840 // the trimming. Actual length should still be trimmed against here, though.
2841 length = Math.Min( length, bufferLength - bufferOffset );
2843 // special case for variants, since their maxLength is actually a bit bigger than
2844 // the actual data length allowed.
2845 if (SqlDbType.Variant == dbType) {
2846 length = Math.Min( length, TdsEnums.TYPE_SIZE_LIMIT );
2849 Debug.Assert( 0 > maxLength || 0 > actualLength ||
2850 maxLength >= actualLength, "Actual = " + actualLength + ", max = " + maxLength + ", sqldbtype=" + dbType );
2852 if ( 0 <= actualLength ) {
2853 // Length is guaranteed to be >= 0 coming in and actualLength >= fieldOffset, so this operation guarantees result >= 0
2854 length = (int) Math.Min((long)length, actualLength - fieldOffset);
2855 Debug.Assert(length >= 0, "result < 0, actualLength/fieldOffset problem?");
2857 else if ( SqlDbType.Udt != dbType && 0 <= maxLength ) {
2858 length = (int) Math.Min((long)length, maxLength - fieldOffset);
2859 Debug.Assert(length >= 0, "Result < 0, maxlen/fieldoffset problem?");
2871 // These tables are formal encoding of the "unchecked" method access rules for various types
2872 // The tables should only be accessed from the CanAccessXetterDirectly methods.
2875 // A couple of private constants to increase the getter/setter access tables' constrast
2876 private const bool X = true;
2877 private const bool _ = false;
2879 private static bool[,] __canAccessGetterDirectly = {
2880 // SqlDbTypes as columns (abreviated, but in order)
2881 // ExtendedClrTypeCodes as rows
2883 // BI, Bin, Bit, Ch, DT, Dec, Fl, Im, Int, Mny, NCh, NTx, NVC, Rl, UI, SDT, SI, SMn, Txt, TS, TI, VBn, VCh, Var, 24, Xml, 26, 27, 28, Udt, St, Dat, Tm, DT2, DTO
2884 /*Bool*/ { _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Bool*/
2885 /*Byte*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Byte*/
2886 /*Char*/ { _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Char*/
2887 /*DTime*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateTime*/
2888 /*DBNul*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*DBNull*/
2889 /*Decim*/{ _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Decimal*/
2890 /*Doubl*/{ _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Double*/
2891 /*Empty*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Empty*/
2892 /*Int16*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Int16*/
2893 /*Int32*/{ _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Int32*/
2894 /*Int64*/{ X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Int64*/
2895 /*SByte*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SByte*/
2896 /*Singl*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Single*/
2897 /*Strng*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*String*/
2898 /*UIn16*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*UInt16*/
2899 /*UIn32*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*UInt32*/
2900 /*UIn64*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*UInt64*/
2901 /*Objct*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*Object*/
2902 /*BytAr*/{ _ , X , _ , X , _ , _ , _ , X , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , X , _ , X , X , _ , _ , X , _ , _ , _ , X , _, _ , _ , _ , _ , },/*ByteArray*/
2903 /*ChrAr*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*CharArray*/
2904 /*Guid*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Guid*/
2905 /*SBin*/ { _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*SqlBinary*/
2906 /*SBool*/{ _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlBoolean*/
2907 /*SByte*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlByte*/
2908 /*SDTme*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*SqlDateTime*/
2909 /*SDubl*/{ _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlDouble*/
2910 /*SGuid*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlGuid*/
2911 /*SIn16*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlInt16*/
2912 /*SIn32*/{ _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlInt32*/
2913 /*SIn64*/{ X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlInt64*/
2914 /*SMony*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlMoney*/
2915 /*SDeci*/{ _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlDecimal*/
2916 /*SSngl*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlSingle*/
2917 /*SStrn*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlString*/
2918 /*SChrs*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlChars*/
2919 /*SByts*/{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*SqlBytes*/
2920 /*SXml*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlXml*/
2921 /*DTbl*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*DataTable*/
2922 /*Rdr */ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*DbDataReader*/
2923 /*EnSDR*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*IEnurerable<SqlDataRecord>*/
2924 /*TmSpn*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeSpan*/
2925 /*DTOst*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , X , },/*DateTimeOffset*/
2926 /*Strm */{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*Stream*/
2927 /*TxRdr*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/
2928 /*XmlRd*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*XmlReader*/
2929 // BI, Bin, Bit, Ch, DT, Dec, Fl, Im, Int, Mny, NCh, NTx, NVC, Rl, UI, SDT, SI, SMn, Txt, TS, TI, VBn, VCh, Var, 24, Xml, 26, 27, 28, Udt, St, Dat, Tm, DT2, DTO
2932 private static bool[,] __canAccessSetterDirectly = {
2933 // Setters as columns (labels are abreviated from ExtendedClrTypeCode names)
2934 // SqlDbTypes as rows
2935 // BI, Bin, Bit, Ch, DT, Dec, Fl, Im, Int, Mny, NCh, NTx, NVC, Rl, UI, SDT, SI, SMn, Txt, TS, TI, VBn, VCh, Var, 24, Xml, 26, 27, 28, Udt, St, Dat, Tm, DT2, DTO
2936 /*Bool*/ { _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Bool*/
2937 /*Byte*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Byte*/
2938 /*Char*/ { _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Char*/
2939 /*DTime*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateTime*/
2940 /*DBNul*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*DBNull*/
2941 /*Decim*/{ _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Decimal*/
2942 /*Doubl*/{ _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Double*/
2943 /*Empty*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Empty*/
2944 /*Int16*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Int16*/
2945 /*Int32*/{ _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Int32*/
2946 /*Int64*/{ X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Int64*/
2947 /*SByte*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SByte*/
2948 /*Singl*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Single*/
2949 /*Strng*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , X , _ , X , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*String*/
2950 /*UIn16*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*UInt16*/
2951 /*UIn32*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*UInt32*/
2952 /*UIn64*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*UInt64*/
2953 /*Objct*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*Object*/
2954 /*BytAr*/{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , X , _ , X , _ , X , _ , _ , _ , X , _, _ , _ , _ , _ , },/*ByteArray*/
2955 /*ChrAr*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*CharArray*/
2956 /*Guid*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Guid*/
2957 /*SBin*/ { _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , X , _ , X , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*SqlBinary*/
2958 /*SBool*/{ _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlBoolean*/
2959 /*SByte*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlByte*/
2960 /*SDTme*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*SqlDateTime*/
2961 /*SDubl*/{ _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlDouble*/
2962 /*SGuid*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlGuid*/
2963 /*SIn16*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlInt16*/
2964 /*SIn32*/{ _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlInt32*/
2965 /*SIn64*/{ X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlInt64*/
2966 /*SMony*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlMoney*/
2967 /*SDeci*/{ _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlDecimal*/
2968 /*SSngl*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlSingle*/
2969 /*SStrn*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , X , _ , X , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlString*/
2970 /*SChrs*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , X , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlChars*/
2971 /*SByts*/{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , X , _ , X , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*SqlBytes*/
2972 /*SXml*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*SqlXml*/
2973 /*DTbl*/ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*DataTable*/
2974 /*Rdr */ { _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*DbDataReader*/
2975 /*EnSDR*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X, _ , _ , _ , _ , },/*IEnurerable<SqlDataRecord>*/
2976 /*TmSpn*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeSpan*/
2977 /*DTOst*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , X , },/*DateTimeOffset*/
2978 /*Strm */{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Stream*/
2979 /*TxRdr*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/
2980 /*XmlRd*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*XmlReader*/
2981 // BI, Bin, Bit, Ch, DT, Dec, Fl, Im, Int, Mny, NCh, NTx, NVC, Rl, UI, SDT, SI, SMn, Txt, TS, TI, VBn, VCh, Var, 24, Xml, 26, 27, 28, Udt, St, Dat, Tm, DT2, DTO
2986 // Private implementation of common mappings from a given type to corresponding Smi Getter/Setter
2987 // These classes do type validation, parameter limit validation, nor coercions
2989 private static bool IsDBNull_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
2990 bool result = getters.IsDBNull( sink, ordinal );
2991 sink.ProcessMessagesAndThrow();
2995 private static bool GetBoolean_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
2996 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
2998 bool result = getters.GetBoolean( sink, ordinal );
2999 sink.ProcessMessagesAndThrow();
3003 private static byte GetByte_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3004 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3006 byte result = getters.GetByte( sink, ordinal );
3007 sink.ProcessMessagesAndThrow();
3011 private static byte[] GetByteArray_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3012 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3014 long length = getters.GetBytesLength( sink, ordinal );
3015 sink.ProcessMessagesAndThrow();
3016 int len = checked( (int)length );
3018 byte[] buffer = new byte[len];
3019 getters.GetBytes( sink, ordinal, 0, buffer, 0, len );
3020 sink.ProcessMessagesAndThrow();
3024 internal static int GetBytes_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length ) {
3025 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3026 Debug.Assert(ordinal >= 0, string.Format("Invalid ordinal: {0}", ordinal));
3027 Debug.Assert(sink != null, "Null SmiEventSink");
3028 Debug.Assert(getters != null, "Null getters");
3029 Debug.Assert(fieldOffset >= 0, string.Format("Invalid field offset: {0}", fieldOffset));
3030 Debug.Assert(buffer != null, "Null buffer");
3031 Debug.Assert(bufferOffset >= 0 && length >= 0 && bufferOffset + length <= buffer.Length, string.Format("Bad offset or length. bufferOffset: {0}, length: {1}, buffer.Length{2}", bufferOffset, length, buffer.Length));
3033 int result = getters.GetBytes( sink, ordinal, fieldOffset, buffer, bufferOffset, length );
3034 sink.ProcessMessagesAndThrow();
3038 private static long GetBytesLength_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3039 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3041 long result = getters.GetBytesLength( sink, ordinal );
3042 sink.ProcessMessagesAndThrow();
3047 private static char[] GetCharArray_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3048 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3050 long length = getters.GetCharsLength( sink, ordinal );
3051 sink.ProcessMessagesAndThrow();
3052 int len = checked( (int)length );
3054 char[] buffer = new char[len];
3055 getters.GetChars( sink, ordinal, 0, buffer, 0, len );
3056 sink.ProcessMessagesAndThrow();
3060 internal static int GetChars_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length ) {
3061 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3062 Debug.Assert(ordinal >= 0, string.Format("Invalid ordinal: {0}", ordinal));
3063 Debug.Assert(sink != null, "Null SmiEventSink");
3064 Debug.Assert(getters != null, "Null getters");
3065 Debug.Assert(fieldOffset >= 0, string.Format("Invalid field offset: {0}", fieldOffset));
3066 Debug.Assert(buffer != null, "Null buffer");
3067 Debug.Assert(bufferOffset >= 0 && length >= 0 && bufferOffset + length <= buffer.Length, string.Format("Bad offset or length. bufferOffset: {0}, length: {1}, buffer.Length{2}", bufferOffset, length, buffer.Length));
3069 int result = getters.GetChars( sink, ordinal, fieldOffset, buffer, bufferOffset, length );
3070 sink.ProcessMessagesAndThrow();
3074 private static long GetCharsLength_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3075 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3077 long result = getters.GetCharsLength( sink, ordinal );
3078 sink.ProcessMessagesAndThrow();
3082 private static DateTime GetDateTime_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3083 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3085 DateTime result = getters.GetDateTime( sink, ordinal );
3086 sink.ProcessMessagesAndThrow();
3090 private static DateTimeOffset GetDateTimeOffset_Unchecked(SmiEventSink_Default sink, SmiTypedGetterSetter getters, int ordinal) {
3091 Debug.Assert(!IsDBNull_Unchecked(sink, getters, ordinal));
3093 DateTimeOffset result = getters.GetDateTimeOffset(sink, ordinal);
3094 sink.ProcessMessagesAndThrow();
3098 private static Double GetDouble_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3099 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3101 Double result = getters.GetDouble( sink, ordinal );
3102 sink.ProcessMessagesAndThrow();
3106 private static Guid GetGuid_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3107 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3109 Guid result = getters.GetGuid( sink, ordinal );
3110 sink.ProcessMessagesAndThrow();
3114 private static Int16 GetInt16_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3115 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3117 Int16 result = getters.GetInt16( sink, ordinal );
3118 sink.ProcessMessagesAndThrow();
3122 private static Int32 GetInt32_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3123 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3125 Int32 result = getters.GetInt32( sink, ordinal );
3126 sink.ProcessMessagesAndThrow();
3130 private static Int64 GetInt64_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3131 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3133 Int64 result = getters.GetInt64( sink, ordinal );
3134 sink.ProcessMessagesAndThrow();
3138 private static Single GetSingle_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3139 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3141 Single result = getters.GetSingle( sink, ordinal );
3142 sink.ProcessMessagesAndThrow();
3146 private static SqlBinary GetSqlBinary_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3147 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3149 byte[] buffer = GetByteArray_Unchecked( sink, getters, ordinal );
3150 return new SqlBinary( buffer );
3153 private static SqlDecimal GetSqlDecimal_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3154 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3156 SqlDecimal result = getters.GetSqlDecimal( sink, ordinal );
3157 sink.ProcessMessagesAndThrow();
3161 private static SqlMoney GetSqlMoney_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3162 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3164 Int64 temp = getters.GetInt64( sink, ordinal );
3165 sink.ProcessMessagesAndThrow();
3166 return new SqlMoney( temp, 1 /* ignored */ );
3169 private static SqlXml GetSqlXml_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiContext context ) {
3170 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3172 // allow context to be null so strongly-typed getters can use
3173 // this method without having to pass along the almost-never-used context as a parameter
3174 // Looking the context up like this will be slightly slower, but still correct behavior
3175 // since it's only used to get a scratch stream.
3176 if (null == context && InOutOfProcHelper.InProc) {
3177 context = SmiContextFactory.Instance.GetCurrentContext(); // In the future we need to push the context checking to a higher level
3180 // Note: must make a copy of getter stream, since it will be used beyond
3181 // this method (valid lifetime of getters is limited).
3182 Stream s = new SmiGettersStream( sink, getters, ordinal, SmiMetaData.DefaultXml );
3183 Stream copy = ValueUtilsSmi.CopyIntoNewSmiScratchStream( s, sink, context );
3184 SqlXml result = new SqlXml( copy );
3188 private static String GetString_Unchecked( SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal ) {
3189 Debug.Assert( !IsDBNull_Unchecked( sink, getters, ordinal ) );
3191 // Note: depending on different getters, the result string maybed truncated, e.g. for
3192 // Inproc process, the getter is InProcRecordBuffer (implemented in SqlAcess), string will be
3193 // truncated to 4000 (if length is more than 4000). If MemoryRecordBuffer getter is used, data
3194 // is not truncated. Please refer VSDD 479655 for more detailed information regarding the string length.
3195 String result = getters.GetString( sink, ordinal );
3196 sink.ProcessMessagesAndThrow();
3200 private static TimeSpan GetTimeSpan_Unchecked(SmiEventSink_Default sink, SmiTypedGetterSetter getters, int ordinal) {
3201 Debug.Assert(!IsDBNull_Unchecked(sink, getters, ordinal));
3203 TimeSpan result = getters.GetTimeSpan(sink, ordinal);
3204 sink.ProcessMessagesAndThrow();
3208 private static void SetBoolean_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Boolean value ) {
3209 setters.SetBoolean( sink, ordinal, value );
3210 sink.ProcessMessagesAndThrow();
3213 private static void SetByteArray_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, byte[] buffer, int bufferOffset, int length ) {
3215 setters.SetBytes( sink, ordinal, 0, buffer, bufferOffset, length );
3216 sink.ProcessMessagesAndThrow();
3218 setters.SetBytesLength( sink, ordinal, length );
3219 sink.ProcessMessagesAndThrow();
3222 private static void SetStream_Unchecked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metadata, StreamDataFeed feed) {
3223 long len = metadata.MaxLength;
3224 byte[] buff = new byte[constBinBufferSize];
3228 int readSize = constBinBufferSize;
3229 if (len > 0 && nWritten + readSize > len) {
3230 readSize = (int)(len - nWritten);
3233 Debug.Assert(readSize >= 0);
3235 nRead = feed._source.Read(buff, 0, readSize);
3241 setters.SetBytes(sink, ordinal, nWritten, buff, 0, nRead);
3242 sink.ProcessMessagesAndThrow();
3245 } while (len <= 0 || nWritten < len);
3247 setters.SetBytesLength(sink, ordinal, nWritten);
3248 sink.ProcessMessagesAndThrow();
3251 private static void SetTextReader_Unchecked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metadata, TextDataFeed feed) {
3252 long len = metadata.MaxLength;
3253 char[] buff = new char[constTextBufferSize];
3257 int readSize = constTextBufferSize;
3258 if (len > 0 && nWritten + readSize > len) {
3259 readSize = (int)(len - nWritten);
3262 Debug.Assert(readSize >= 0);
3264 nRead = feed._source.Read(buff, 0, readSize);
3270 setters.SetChars(sink, ordinal, nWritten, buff, 0, nRead);
3271 sink.ProcessMessagesAndThrow();
3274 } while (len <= 0 || nWritten < len);
3276 setters.SetCharsLength(sink, ordinal, nWritten);
3277 sink.ProcessMessagesAndThrow();
3280 private static void SetByte_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Byte value ) {
3281 setters.SetByte( sink, ordinal, value );
3282 sink.ProcessMessagesAndThrow();
3285 private static int SetBytes_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length ) {
3286 int result = setters.SetBytes( sink, ordinal, fieldOffset, buffer, bufferOffset, length );
3287 sink.ProcessMessagesAndThrow();
3291 private static void SetCharArray_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, char[] buffer, int bufferOffset, int length ) {
3293 setters.SetChars( sink, ordinal, 0, buffer, bufferOffset, length );
3294 sink.ProcessMessagesAndThrow();
3296 setters.SetCharsLength( sink, ordinal, length );
3297 sink.ProcessMessagesAndThrow();
3300 private static int SetChars_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length ) {
3301 int result = setters.SetChars( sink, ordinal, fieldOffset, buffer, bufferOffset, length );
3302 sink.ProcessMessagesAndThrow();
3306 private static void SetDBNull_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal ) {
3307 setters.SetDBNull( sink, ordinal );
3308 sink.ProcessMessagesAndThrow();
3311 private static void SetDecimal_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Decimal value ) {
3312 setters.SetSqlDecimal( sink, ordinal, new SqlDecimal( value ) );
3313 sink.ProcessMessagesAndThrow();
3316 private static void SetDateTime_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, DateTime value ) {
3317 setters.SetDateTime( sink, ordinal, value );
3318 sink.ProcessMessagesAndThrow();
3321 private static void SetDateTime2_Unchecked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTime value)
3323 Debug.Assert(SqlDbType.Variant == metaData.SqlDbType, "Invalid type. This should be called only when the type is variant.");
3324 setters.SetVariantMetaData(sink, ordinal, SmiMetaData.DefaultDateTime2);
3325 setters.SetDateTime(sink, ordinal, value);
3326 sink.ProcessMessagesAndThrow();
3329 private static void SetDate_Unchecked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DateTime value)
3331 Debug.Assert(SqlDbType.Variant == metaData.SqlDbType, "Invalid type. This should be called only when the type is variant.");
3332 setters.SetVariantMetaData(sink, ordinal, SmiMetaData.DefaultDate);
3333 setters.SetDateTime(sink, ordinal, value);
3334 sink.ProcessMessagesAndThrow();
3337 private static void SetTimeSpan_Unchecked(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, TimeSpan value) {
3338 setters.SetTimeSpan(sink, ordinal, value);
3339 sink.ProcessMessagesAndThrow();
3342 private static void SetDateTimeOffset_Unchecked(SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, DateTimeOffset value) {
3343 setters.SetDateTimeOffset(sink, ordinal, value);
3344 sink.ProcessMessagesAndThrow();
3347 private static void SetDouble_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Double value ) {
3348 setters.SetDouble( sink, ordinal, value );
3349 sink.ProcessMessagesAndThrow();
3352 private static void SetGuid_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Guid value ) {
3353 setters.SetGuid( sink, ordinal, value );
3354 sink.ProcessMessagesAndThrow();
3357 private static void SetInt16_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Int16 value ) {
3358 setters.SetInt16( sink, ordinal, value );
3359 sink.ProcessMessagesAndThrow();
3362 private static void SetInt32_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Int32 value ) {
3363 setters.SetInt32( sink, ordinal, value );
3364 sink.ProcessMessagesAndThrow();
3367 private static void SetInt64_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Int64 value ) {
3368 setters.SetInt64( sink, ordinal, value );
3369 sink.ProcessMessagesAndThrow();
3372 private static void SetSingle_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, Single value ) {
3373 setters.SetSingle( sink, ordinal, value );
3374 sink.ProcessMessagesAndThrow();
3377 private static void SetSqlBinary_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlBinary value, int offset, int length ) {
3378 if ( value.IsNull ) {
3379 setters.SetDBNull( sink, ordinal );
3382 SetByteArray_Unchecked( sink, setters, ordinal, value.Value, offset, length );
3384 sink.ProcessMessagesAndThrow();
3387 private static void SetSqlBoolean_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlBoolean value ) {
3388 if ( value.IsNull ) {
3389 setters.SetDBNull( sink, ordinal );
3392 setters.SetBoolean( sink, ordinal, value.Value );
3394 sink.ProcessMessagesAndThrow();
3397 private static void SetSqlByte_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlByte value ) {
3398 if ( value.IsNull ) {
3399 setters.SetDBNull( sink, ordinal );
3402 setters.SetByte( sink, ordinal, value.Value );
3404 sink.ProcessMessagesAndThrow();
3407 // note: length < 0 indicates write everything
3408 private static void SetSqlBytes_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlBytes value, int offset, long length ) {
3409 if ( value.IsNull ) {
3410 setters.SetDBNull( sink, ordinal );
3411 sink.ProcessMessagesAndThrow();
3415 if ( length > __maxByteChunkSize || length < 0 ) {
3416 chunkSize = __maxByteChunkSize;
3419 chunkSize = checked( (int)length );
3422 byte[] buffer = new byte[ chunkSize ];
3424 long bytesWritten = 1; // prime value to get into write loop
3425 long currentOffset = offset;
3426 long lengthWritten = 0;
3428 while ( (length < 0 || lengthWritten < length) &&
3429 0 != ( bytesRead = value.Read( currentOffset, buffer, 0, chunkSize ) ) &&
3430 0 != bytesWritten ) {
3431 bytesWritten = setters.SetBytes( sink, ordinal, currentOffset, buffer, 0, checked( (int) bytesRead ) );
3432 sink.ProcessMessagesAndThrow();
3433 checked{ currentOffset += bytesWritten; }
3434 checked{ lengthWritten += bytesWritten; }
3437 // Make sure to trim any left-over data
3438 setters.SetBytesLength( sink, ordinal, currentOffset );
3439 sink.ProcessMessagesAndThrow();
3443 private static void SetSqlChars_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlChars value, int offset, int length ) {
3444 if ( value.IsNull ) {
3445 setters.SetDBNull( sink, ordinal );
3446 sink.ProcessMessagesAndThrow();
3450 if ( length > __maxCharChunkSize || length < 0 ) {
3451 chunkSize = __maxCharChunkSize;
3454 chunkSize = checked( (int)length );
3457 char[] buffer = new char[ chunkSize ];
3459 long charsWritten = 1; // prime value to get into write loop
3460 long currentOffset = offset;
3461 long lengthWritten = 0;
3463 while ( (length < 0 || lengthWritten < length) &&
3464 0 != ( charsRead = value.Read( currentOffset, buffer, 0, chunkSize ) ) &&
3465 0 != charsWritten ) {
3466 charsWritten = setters.SetChars( sink, ordinal, currentOffset, buffer, 0, checked( (int) charsRead ) );
3467 sink.ProcessMessagesAndThrow();
3468 checked{ currentOffset += charsWritten; }
3469 checked{ lengthWritten += charsWritten;}
3472 // Make sure to trim any left-over data
3473 setters.SetCharsLength( sink, ordinal, currentOffset );
3474 sink.ProcessMessagesAndThrow();
3478 private static void SetSqlDateTime_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlDateTime value ) {
3479 if ( value.IsNull ) {
3480 setters.SetDBNull( sink, ordinal );
3483 setters.SetDateTime( sink, ordinal, value.Value );
3485 sink.ProcessMessagesAndThrow();
3488 private static void SetSqlDecimal_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlDecimal value ) {
3489 if ( value.IsNull ) {
3490 setters.SetDBNull( sink, ordinal );
3493 setters.SetSqlDecimal( sink, ordinal, value );
3495 sink.ProcessMessagesAndThrow();
3498 private static void SetSqlDouble_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlDouble value ) {
3499 if ( value.IsNull ) {
3500 setters.SetDBNull( sink, ordinal );
3503 setters.SetDouble( sink, ordinal, value.Value );
3505 sink.ProcessMessagesAndThrow();
3508 private static void SetSqlGuid_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlGuid value ) {
3509 if ( value.IsNull ) {
3510 setters.SetDBNull( sink, ordinal );
3513 setters.SetGuid( sink, ordinal, value.Value );
3515 sink.ProcessMessagesAndThrow();
3518 private static void SetSqlInt16_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlInt16 value ) {
3519 if ( value.IsNull ) {
3520 setters.SetDBNull( sink, ordinal );
3523 setters.SetInt16( sink, ordinal, value.Value );
3525 sink.ProcessMessagesAndThrow();
3528 private static void SetSqlInt32_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlInt32 value ) {
3529 if ( value.IsNull ) {
3530 setters.SetDBNull( sink, ordinal );
3533 setters.SetInt32( sink, ordinal, value.Value );
3535 sink.ProcessMessagesAndThrow();
3538 private static void SetSqlInt64_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlInt64 value ) {
3539 if ( value.IsNull ) {
3540 setters.SetDBNull( sink, ordinal );
3543 setters.SetInt64( sink, ordinal, value.Value );
3545 sink.ProcessMessagesAndThrow();
3548 private static void SetSqlMoney_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlMoney value ) {
3549 if ( value.IsNull ) {
3550 setters.SetDBNull( sink, ordinal );
3553 if ( SqlDbType.Variant == metaData.SqlDbType ) {
3554 setters.SetVariantMetaData( sink, ordinal, SmiMetaData.DefaultMoney );
3555 sink.ProcessMessagesAndThrow();
3558 setters.SetInt64( sink, ordinal, value.ToSqlInternalRepresentation() );
3560 sink.ProcessMessagesAndThrow();
3563 private static void SetSqlSingle_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlSingle value ) {
3564 if ( value.IsNull ) {
3565 setters.SetDBNull( sink, ordinal );
3568 setters.SetSingle( sink, ordinal, value.Value );
3570 sink.ProcessMessagesAndThrow();
3573 private static void SetSqlString_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlString value, int offset, int length ) {
3574 if ( value.IsNull ) {
3575 setters.SetDBNull( sink, ordinal );
3576 sink.ProcessMessagesAndThrow();
3579 if (SqlDbType.Variant == metaData.SqlDbType) {
3580 // Set up a NVarChar metadata with correct LCID/Collation
3581 metaData = new SmiMetaData(
3583 SmiMetaData.MaxUnicodeCharacters,
3587 value.SqlCompareOptions,
3589 setters.SetVariantMetaData( sink, ordinal, metaData );
3590 sink.ProcessMessagesAndThrow();
3592 SetString_Unchecked( sink, setters, ordinal, value.Value, offset, length );
3596 private static void SetSqlXml_Unchecked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SqlXml value) {
3598 setters.SetDBNull(sink, ordinal);
3599 sink.ProcessMessagesAndThrow();
3602 SetXmlReader_Unchecked(sink, setters, ordinal, value.CreateReader());
3606 private static void SetXmlReader_Unchecked(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, XmlReader xmlReader) {
3608 XmlWriterSettings WriterSettings = new XmlWriterSettings();
3609 WriterSettings.CloseOutput = false; // don't close the memory stream
3610 WriterSettings.ConformanceLevel = ConformanceLevel.Fragment;
3611 WriterSettings.Encoding = System.Text.Encoding.Unicode;
3612 WriterSettings.OmitXmlDeclaration = true;
3614 System.IO.Stream target = new SmiSettersStream(sink, setters, ordinal, SmiMetaData.DefaultXml);
3616 XmlWriter xmlWriter = XmlWriter.Create(target, WriterSettings);
3618 // now spool the data into the writer (WriteNode will call Read())
3620 while (!xmlReader.EOF) {
3621 xmlWriter.WriteNode(xmlReader, true);
3624 sink.ProcessMessagesAndThrow();
3627 private static void SetString_Unchecked( SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, String value, int offset, int length ) {
3628 setters.SetString( sink, ordinal, value, offset, length );
3629 sink.ProcessMessagesAndThrow();
3632 private static void SetDataTable_Unchecked(
3633 SmiEventSink_Default sink,
3634 SmiTypedGetterSetter setters,
3636 SmiMetaData metaData,
3639 // Get the target gettersetter
3640 setters = setters.GetTypedGetterSetter(sink, ordinal);
3641 sink.ProcessMessagesAndThrow();
3643 // iterate over all records
3644 // if first record was obtained earlier, use it prior to pulling more
3645 ExtendedClrTypeCode[] cellTypes = new ExtendedClrTypeCode[metaData.FieldMetaData.Count];
3646 for(int i=0; i<metaData.FieldMetaData.Count; i++) {
3647 cellTypes[i] = ExtendedClrTypeCode.Invalid;
3649 foreach(DataRow row in value.Rows) {
3650 setters.NewElement(sink);
3651 sink.ProcessMessagesAndThrow();
3653 // Set all columns in the record
3654 for(int i=0; i<metaData.FieldMetaData.Count; i++) {
3655 SmiMetaData fieldMetaData = metaData.FieldMetaData[i];
3656 if (row.IsNull(i)) {
3657 SetDBNull_Unchecked(sink, setters, i);
3660 object cellValue = row[i];
3662 // Only determine cell types for first row, to save expensive
3663 if (ExtendedClrTypeCode.Invalid == cellTypes[i]) {
3664 cellTypes[i] = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType(
3665 fieldMetaData.SqlDbType, fieldMetaData.IsMultiValued, cellValue, fieldMetaData.Type,
3668 SmiContextFactory.KatmaiVersion
3671 SetCompatibleValueV200(sink, setters, i, fieldMetaData, cellValue, cellTypes[i], 0, NoLengthLimit, null);
3676 setters.EndElements(sink);
3677 sink.ProcessMessagesAndThrow();
3680 // Set a DbDataReader to a Structured+MultiValued setter (table type)
3681 // Assumes metaData correctly describes the reader's shape, and consumes only the current resultset
3682 private static void SetDbDataReader_Unchecked(
3683 SmiEventSink_Default sink,
3684 SmiTypedGetterSetter setters,
3686 SmiMetaData metaData,
3689 // Get the target gettersetter
3690 setters = setters.GetTypedGetterSetter(sink, ordinal);
3691 sink.ProcessMessagesAndThrow();
3693 // Iterate over all rows in the current set of results
3694 while (value.Read()) {
3695 setters.NewElement(sink);
3696 sink.ProcessMessagesAndThrow();
3698 FillCompatibleSettersFromReader(sink, setters, metaData.FieldMetaData, value);
3701 setters.EndElements(sink);
3702 sink.ProcessMessagesAndThrow();
3705 private static void SetIEnumerableOfSqlDataRecord_Unchecked(
3706 SmiEventSink_Default sink,
3707 SmiTypedGetterSetter setters,
3709 SmiMetaData metaData,
3710 IEnumerable<SqlDataRecord> value,
3711 ParameterPeekAheadValue peekAhead
3713 // Get target gettersetter
3714 setters = setters.GetTypedGetterSetter(sink, ordinal);
3715 sink.ProcessMessagesAndThrow();
3717 IEnumerator<SqlDataRecord> enumerator = null;
3719 // Need to copy field metadata to an array to call FillCompatibleITypeSettersFromRecord
3720 SmiExtendedMetaData[] mdFields = new SmiExtendedMetaData[metaData.FieldMetaData.Count];
3721 metaData.FieldMetaData.CopyTo(mdFields, 0);
3723 SmiDefaultFieldsProperty defaults = (SmiDefaultFieldsProperty) metaData.ExtendedProperties[SmiPropertySelector.DefaultFields];
3725 int recordNumber = 1; // used only for reporting position when there are errors.
3727 // obtain enumerator and handle any peekahead values
3728 if (null != peekAhead && null != peekAhead.FirstRecord) {
3729 // hook up to enumerator
3730 enumerator = peekAhead.Enumerator;
3732 // send the first record that was obtained earlier
3733 setters.NewElement(sink);
3734 sink.ProcessMessagesAndThrow();
3735 FillCompatibleSettersFromRecord(sink, setters, mdFields, peekAhead.FirstRecord, defaults);
3739 enumerator = value.GetEnumerator();
3742 using (enumerator) {
3743 while(enumerator.MoveNext()) {
3744 setters.NewElement(sink);
3745 sink.ProcessMessagesAndThrow();
3747 SqlDataRecord record = enumerator.Current;
3749 if (record.FieldCount != mdFields.Length) {
3750 throw SQL.EnumeratedRecordFieldCountChanged(recordNumber);
3753 for(int i=0; i<record.FieldCount; i++) {
3754 if (!MetaDataUtilsSmi.IsCompatible(metaData.FieldMetaData[i], record.GetSqlMetaData(i))) {
3755 throw SQL.EnumeratedRecordMetaDataChanged(record.GetName(i), recordNumber);
3759 FillCompatibleSettersFromRecord(sink, setters, mdFields, record, defaults);
3763 setters.EndElements(sink);
3764 sink.ProcessMessagesAndThrow();
3769 IDisposable disposable = enumerator as IDisposable;
3770 if (null != disposable) {
3771 disposable.Dispose();