private async Task WriteXmlFeed(XmlDataFeed feed, TdsParserStateObject stateObj, bool needBom, Encoding encoding, int size) { byte[] preambleToSkip = null; if (!needBom) { preambleToSkip = encoding.GetPreamble(); } ConstrainedTextWriter writer = new ConstrainedTextWriter(new StreamWriter(new TdsOutputStream(this, stateObj, preambleToSkip), encoding), size); XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.CloseOutput = false; // don't close the memory stream writerSettings.ConformanceLevel = ConformanceLevel.Fragment; if (_asyncWrite) { writerSettings.Async = true; } XmlWriter ww = XmlWriter.Create(writer, writerSettings); if (feed._source.ReadState == ReadState.Initial) { feed._source.Read(); } while (!feed._source.EOF && !writer.IsComplete) { // We are copying nodes from a reader to a writer. This will cause the // XmlDeclaration to be emitted despite ConformanceLevel.Fragment above. // Therefore, we filter out the XmlDeclaration while copying. if (feed._source.NodeType == XmlNodeType.XmlDeclaration) { feed._source.Read(); continue; } if (_asyncWrite) { await ww.WriteNodeAsync(feed._source, true).ConfigureAwait(false); } else { ww.WriteNode(feed._source, true); } } if (_asyncWrite) { await ww.FlushAsync().ConfigureAwait(false); } else { ww.Flush(); } }
// Coerced Value is also used in SqlBulkCopy.ConvertValue(object value, _SqlMetaData metadata) internal static object CoerceValue(object value, MetaType destinationType, out bool coercedToDataFeed, out bool typeChanged, bool allowStreaming = true) { Debug.Assert(!(value is DataFeed), "Value provided should not already be a data feed"); Debug.Assert(!ADP.IsNull(value), "Value provided should not be null"); Debug.Assert(null != destinationType, "null destinationType"); coercedToDataFeed = false; typeChanged = false; Type currentType = value.GetType(); if ((typeof(object) != destinationType.ClassType) && (currentType != destinationType.ClassType) && ((currentType != destinationType.SqlType) || (SqlDbType.Xml == destinationType.SqlDbType))) { // Special case for Xml types (since we need to convert SqlXml into a string) try { // Assume that the type changed typeChanged = true; if ((typeof(string) == destinationType.ClassType)) { // For Xml data, destination Type is always string if (typeof(SqlXml) == currentType) { value = MetaType.GetStringFromXml((XmlReader)(((SqlXml)value).CreateReader())); } else if (typeof(SqlString) == currentType) { typeChanged = false; // Do nothing } else if (typeof(XmlReader).IsAssignableFrom(currentType)) { if (allowStreaming) { coercedToDataFeed = true; value = new XmlDataFeed((XmlReader)value); } else { value = MetaType.GetStringFromXml((XmlReader)value); } } else if (typeof(char[]) == currentType) { value = new string((char[])value); } else if (typeof(SqlChars) == currentType) { value = new string(((SqlChars)value).Value); } else if (value is TextReader && allowStreaming) { coercedToDataFeed = true; value = new TextDataFeed((TextReader)value); } else { value = Convert.ChangeType(value, destinationType.ClassType, (IFormatProvider)null); } } else if ((DbType.Currency == destinationType.DbType) && (typeof(string) == currentType)) { value = Decimal.Parse((string)value, NumberStyles.Currency, (IFormatProvider)null); // WebData 99376 } else if ((typeof(SqlBytes) == currentType) && (typeof(byte[]) == destinationType.ClassType)) { typeChanged = false; // Do nothing } else if ((typeof(string) == currentType) && (SqlDbType.Time == destinationType.SqlDbType)) { value = TimeSpan.Parse((string)value); } else if ((typeof(string) == currentType) && (SqlDbType.DateTimeOffset == destinationType.SqlDbType)) { value = DateTimeOffset.Parse((string)value, (IFormatProvider)null); } else if ((typeof(DateTime) == currentType) && (SqlDbType.DateTimeOffset == destinationType.SqlDbType)) { value = new DateTimeOffset((DateTime)value); } else if (TdsEnums.SQLTABLE == destinationType.TDSType && ( value is DbDataReader || value is System.Collections.Generic.IEnumerable<SqlDataRecord>)) { // no conversion for TVPs. typeChanged = false; } else if (destinationType.ClassType == typeof(byte[]) && value is Stream && allowStreaming) { coercedToDataFeed = true; value = new StreamDataFeed((Stream)value); } else { value = Convert.ChangeType(value, destinationType.ClassType, (IFormatProvider)null); } } catch (Exception e) { if (!ADP.IsCatchableExceptionType(e)) { throw; } throw ADP.ParameterConversionFailed(value, destinationType.ClassType, e); // WebData 75433 } } Debug.Assert(allowStreaming || !coercedToDataFeed, "Streaming is not allowed, but type was coerced into a data feed"); Debug.Assert(value.GetType() == currentType ^ typeChanged, "Incorrect value for typeChanged"); return value; }