diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs index b74253784340ba..efaed2c39d2311 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs @@ -703,6 +703,18 @@ public override unsafe void WriteRaw(string data) _textPos = _bufPos; } + internal override unsafe void WriteRaw(ReadOnlySpan value) + { + if (_trackTextContent && _inTextContent) { ChangeTextContentMark(false); } + + fixed (char* pSrcBegin = value) + { + WriteRawWithCharChecking(pSrcBegin, pSrcBegin + value.Length); + } + + _textPos = _bufPos; + } + // Flush all bytes in the buffer to output and close the output stream or writer. public override void Close() { @@ -2125,6 +2137,12 @@ public override void WriteRaw(string data) base.WriteRaw(data); } + internal override void WriteRaw(ReadOnlySpan value) + { + _mixedContent = true; + base.WriteRaw(value); + } + public override void WriteBase64(byte[] buffer, int index, int count) { _mixedContent = true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude index 3c0837cbc6dcdb..639112dfc68b38 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude @@ -730,6 +730,18 @@ namespace System.Xml _textPos = _bufPos; } + internal override unsafe void WriteRaw(ReadOnlySpan value) + {<# +#><#= SetTextContentMark(3, false) #> + + fixed (char* pSrcBegin = value) + { + WriteRawWithCharChecking(pSrcBegin, pSrcBegin + value.Length); + } + + _textPos = _bufPos; + } + // Flush all bytes in the buffer to output and close the output stream or writer. public override void Close() { @@ -2181,6 +2193,12 @@ namespace System.Xml base.WriteRaw(data); } + internal override void WriteRaw(ReadOnlySpan value) + { + _mixedContent = true; + base.WriteRaw(value); + } + public override void WriteBase64(byte[] buffer, int index, int count) { _mixedContent = true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs index 5f53bb2dd75f35..516e6409b4f763 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs @@ -179,6 +179,12 @@ public override void WriteRaw(string data) WriteString(data); } + // Forward call to WriteString(string). + internal virtual void WriteRaw(ReadOnlySpan value) + { + WriteString(value.ToString()); + } + // Override in order to handle Xml simple typed values and to pass resolver for QName values public override void WriteValue(object value) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs index d5d3c300c99f1f..d0e7a1c49a03d0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs @@ -612,6 +612,16 @@ public override unsafe void WriteRaw(string data) _textPos = _bufPos; } + internal override unsafe void WriteRaw(ReadOnlySpan value) + { + fixed (char* pSrcBegin = value) + { + WriteRawWithCharChecking(pSrcBegin, pSrcBegin + value.Length); + } + + _textPos = _bufPos; + } + // Flush all bytes in the buffer to output and close the output stream or writer. public override void Close() { @@ -1985,6 +1995,12 @@ public override void WriteRaw(string data) base.WriteRaw(data); } + internal override void WriteRaw(ReadOnlySpan value) + { + _mixedContent = true; + base.WriteRaw(value); + } + public override void WriteBase64(byte[] buffer, int index, int count) { _mixedContent = true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs index ce2c6690ea3e73..5901d6e1111bce 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs @@ -1131,6 +1131,31 @@ public override void WriteRaw(string data) } } + internal void WriteRaw(ReadOnlySpan data) + { + try + { + AdvanceState(Token.RawData); + if (SaveAttrValue) + { + _attrValueCache!.WriteRaw(data.ToString()); + } + else if (_rawWriter is not null) + { + _rawWriter.WriteRaw(data); + } + else + { + _writer.WriteRaw(data.ToString()); + } + } + catch + { + _currentState = State.Error; + throw; + } + } + public override void WriteBase64(byte[] buffer, int index, int count) { try diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs index befc8d8b4b2cd3..6e51aa30652aab 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs @@ -463,7 +463,14 @@ protected void WriteTypedPrimitive(string? name, string? ns, object o, bool xsiT Debug.Assert(!span.Slice(0, charsWritten).ContainsAny(escapeChars), "Primitive value contains illegal xml char."); #endif //all the primitive types except string and XmlQualifiedName writes to the buffer - _w.WriteRaw(_primitivesBuffer, 0, charsWritten); + if (_w is XmlWellFormedWriter wellFormedWriter) + { + wellFormedWriter.WriteRaw(_primitivesBuffer.AsSpan(0, charsWritten)); + } + else + { + _w.WriteRaw(_primitivesBuffer, 0, charsWritten); + } } else { diff --git a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs index 5e57f747f5ce65..f7ae5fc82098e7 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs @@ -126,6 +126,21 @@ public static void Xml_DecimalAsRoot() } } + [Fact] + public static void Xml_DecimalArrayAsRoot() + { + decimal[] values = new decimal[] { (decimal)-1.2, (decimal)0, (decimal)2.3, decimal.MinValue, decimal.MaxValue }; + string serialized = Serialize(values, string.Empty, skipStringCompare: true); + + Assert.Contains("-1.2", serialized); + Assert.Contains("0", serialized); + Assert.Contains("2.3", serialized); + Assert.Contains($"{decimal.MinValue.ToString(CultureInfo.InvariantCulture)}", serialized); + Assert.Contains($"{decimal.MaxValue.ToString(CultureInfo.InvariantCulture)}", serialized); + + Assert.Equal(values, SerializeAndDeserialize(values, string.Empty, skipStringCompare: true)); + } + [Fact] public static void Xml_DoubleAsRoot() {