-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Add char[] buffer to XmlRawWriter. #75411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
bb7581c
2b2aaca
613cc41
297bb20
5ee4f9b
ecc9969
47d4def
5681aa0
0efd293
66ff29e
851a749
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |||||||||||||||||||||||||||||||||||
| using System.Xml.XPath; | ||||||||||||||||||||||||||||||||||||
| using System.Xml.Schema; | ||||||||||||||||||||||||||||||||||||
| using System.Collections; | ||||||||||||||||||||||||||||||||||||
| using System.Xml.Serialization; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| namespace System.Xml | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
|
|
@@ -47,6 +48,9 @@ internal abstract partial class XmlRawWriter : XmlWriter | |||||||||||||||||||||||||||||||||||
| // namespace resolver | ||||||||||||||||||||||||||||||||||||
| protected IXmlNamespaceResolver? _resolver; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| private char[] _primitivesBuffer = new char[36]; | ||||||||||||||||||||||||||||||||||||
| private static readonly TypeScope s_typeScope = new TypeScope(); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||
| // XmlWriter implementation | ||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||
|
|
@@ -143,17 +147,19 @@ public override void WriteCData(string? text) | |||||||||||||||||||||||||||||||||||
| WriteString(text); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Forward call to WriteString(string). | ||||||||||||||||||||||||||||||||||||
| // Forward call to WriteChars. | ||||||||||||||||||||||||||||||||||||
| public override void WriteCharEntity(char ch) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteString(char.ToString(ch)); | ||||||||||||||||||||||||||||||||||||
| _primitivesBuffer[0] = ch; | ||||||||||||||||||||||||||||||||||||
|
TrayanZapryanov marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||||
| WriteChars(_primitivesBuffer, 0, 1); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Forward call to WriteString(string). | ||||||||||||||||||||||||||||||||||||
| // Forward call to WriteChars. | ||||||||||||||||||||||||||||||||||||
| public override void WriteSurrogateCharEntity(char lowChar, char highChar) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| ReadOnlySpan<char> entity = stackalloc char[] { lowChar, highChar }; | ||||||||||||||||||||||||||||||||||||
| WriteString(new string(entity)); | ||||||||||||||||||||||||||||||||||||
| _primitivesBuffer[0] = lowChar; | ||||||||||||||||||||||||||||||||||||
| _primitivesBuffer[1] = highChar; | ||||||||||||||||||||||||||||||||||||
| WriteChars(_primitivesBuffer, 0, 2); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Forward call to WriteString(string). | ||||||||||||||||||||||||||||||||||||
|
|
@@ -162,16 +168,10 @@ public override void WriteWhitespace(string? ws) | |||||||||||||||||||||||||||||||||||
| WriteString(ws); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Forward call to WriteString(string). | ||||||||||||||||||||||||||||||||||||
| // Forward call to WriteRaw(char[]). | ||||||||||||||||||||||||||||||||||||
| public override void WriteChars(char[] buffer, int index, int count) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteString(new string(buffer, index, count)); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Forward call to WriteString(string). | ||||||||||||||||||||||||||||||||||||
| public override void WriteRaw(char[] buffer, int index, int count) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteString(new string(buffer, index, count)); | ||||||||||||||||||||||||||||||||||||
| WriteRaw(buffer, index, count); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Forward call to WriteString(string). | ||||||||||||||||||||||||||||||||||||
|
|
@@ -185,7 +185,74 @@ public override void WriteValue(object value) | |||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| ArgumentNullException.ThrowIfNull(value); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| WriteString(XmlUntypedConverter.Untyped.ToString(value, _resolver)); | ||||||||||||||||||||||||||||||||||||
| Type sourceType = value.GetType(); | ||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be adding a lot of branching where it previously didn't exist. Could this be done differently? I'm not super familiar with this code, but one thought might be to expose a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code in XmlUntypedConverter.ToString(object) is already similar: |
||||||||||||||||||||||||||||||||||||
| if (!TypeScope.IsKnownType(sourceType)) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteString(XmlUntypedConverter.Untyped.ToString(value, _resolver)); | ||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| #pragma warning disable IL2026 | ||||||||||||||||||||||||||||||||||||
|
TrayanZapryanov marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||||
| TypeDesc typeDesc = s_typeScope.GetTypeDesc(sourceType); | ||||||||||||||||||||||||||||||||||||
| #pragma warning restore IL2026 | ||||||||||||||||||||||||||||||||||||
| switch (typeDesc.FormatterName) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| case "Boolean": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((bool)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Int32": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((int)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Int16": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((short)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Int64": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((long)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Single": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((float)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Double": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((double)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Decimal": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((decimal)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "Byte": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((byte)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "SByte": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((sbyte)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "UInt16": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((ushort)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "UInt32": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((uint)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "UInt64": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((ulong)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| //Guid is not supported in XmlUntypedConverter.Untyped and throws exception | ||||||||||||||||||||||||||||||||||||
|
TrayanZapryanov marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||||
| //case "Guid": | ||||||||||||||||||||||||||||||||||||
| // WriteWithBuffer((Guid)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| // break; | ||||||||||||||||||||||||||||||||||||
| case "Char": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((char)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "TimeSpan": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((TimeSpan)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "DateTime": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((DateTime)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| case "DateTimeOffset": | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer((DateTimeOffset)value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||
| WriteString(XmlUntypedConverter.Untyped.ToString(value, _resolver)); | ||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Override in order to handle Xml simple typed values and to pass resolver for QName values | ||||||||||||||||||||||||||||||||||||
|
|
@@ -198,7 +265,7 @@ public override void WriteValue(DateTimeOffset value) | |||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| // For compatibility with custom writers, XmlWriter writes DateTimeOffset as DateTime. | ||||||||||||||||||||||||||||||||||||
| // Our internal writers should use the DateTimeOffset-String conversion from XmlConvert. | ||||||||||||||||||||||||||||||||||||
| WriteString(XmlConvert.ToString(value)); | ||||||||||||||||||||||||||||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment seems not relevant as even now it is using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it is connected with base code ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @krwq Do you know if somebody is changing this Mode ? runtime/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Xmlcustomformatter.cs Lines 20 to 34 in 4486805
I saw similar code in XmlSerializers and the only way to change is with Reflection and directly manipulating fiedl. |
||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Copying to XmlRawWriter is not currently supported. | ||||||||||||||||||||||||||||||||||||
|
|
@@ -217,6 +284,41 @@ public override void WriteNode(System.Xml.XPath.XPathNavigator navigator, bool d | |||||||||||||||||||||||||||||||||||
| throw new InvalidOperationException(SR.Xml_InvalidOperation); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(bool value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(int value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(long value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(double value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(float value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(decimal value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public override void WriteValue(DateTime value) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteWithBuffer(value, XmlConvert.TryFormat); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||
| // XmlRawWriter methods and properties | ||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||
|
|
@@ -315,5 +417,25 @@ internal virtual void Close(WriteState currentState) | |||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| Close(); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| private delegate bool GrowPrimitiveBufferDelegate<in T>(T value, Span<char> destination, out int charsWritten); | ||||||||||||||||||||||||||||||||||||
| private void WriteWithBuffer<T>(T value, GrowPrimitiveBufferDelegate<T> checkFunc) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| ArgumentNullException.ThrowIfNull(value); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| //fast path without loop | ||||||||||||||||||||||||||||||||||||
| if (checkFunc(value, _primitivesBuffer, out int charsWritten)) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| WriteChars(_primitivesBuffer, 0, charsWritten); | ||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| while (!checkFunc(value, _primitivesBuffer, out charsWritten)) | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| _primitivesBuffer = new char[_primitivesBuffer.Length * 2]; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| WriteChars(_primitivesBuffer, 0, charsWritten); | ||||||||||||||||||||||||||||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw that there is difference between runtime/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs Line 560 in abb5c34
and runtime/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs Line 582 in abb5c34
Which one should be used ? |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.