Modernize XmlUTF8TextWriter with u8/inline out's. (#75812)
authorJoseph Lennox <jlennox@gmail.com>
Mon, 27 Mar 2023 18:14:52 +0000 (11:14 -0700)
committerGitHub <noreply@github.com>
Mon, 27 Mar 2023 18:14:52 +0000 (11:14 -0700)
* Modernize XmlUTF8TextWriter with u8/inline out's.

* PR feedback

---------

Co-authored-by: Steve Molloy <smolloy@microsoft.com>
src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlStreamNodeWriter.cs
src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextWriter.cs

index b144c75..5d420a0 100644 (file)
@@ -263,22 +263,6 @@ namespace System.Xml
             }
         }
 
-        protected void WriteUTF8Chars(byte[] chars, int charOffset, int charCount)
-        {
-            if (charCount < bufferLength)
-            {
-                int offset;
-                byte[] buffer = GetBuffer(charCount, out offset);
-                Buffer.BlockCopy(chars, charOffset, buffer, offset, charCount);
-                Advance(charCount);
-            }
-            else
-            {
-                FlushBuffer();
-                OutputStream.Write(chars, charOffset, charCount);
-            }
-        }
-
         protected unsafe void WriteUTF8Chars(string value)
         {
             int count = value.Length;
@@ -291,6 +275,21 @@ namespace System.Xml
             }
         }
 
+        protected void WriteUTF8Bytes(ReadOnlySpan<byte> value)
+        {
+            if (value.Length < bufferLength)
+            {
+                byte[] buffer = GetBuffer(value.Length, out int offset);
+                value.CopyTo(buffer.AsSpan(offset));
+                Advance(value.Length);
+            }
+            else
+            {
+                FlushBuffer();
+                OutputStream.Write(value);
+            }
+        }
+
         protected unsafe void UnsafeWriteUTF8Chars(char* chars, int charCount)
         {
             const int charChunkSize = bufferLength / maxBytesPerChar;
index 2d2677b..495a098 100644 (file)
@@ -58,10 +58,6 @@ namespace System.Xml
         private Encoding? _encoding;
         private char[]? _chars;
 
-        private static readonly byte[] s_startDecl = "<?xml version=\"1.0\" encoding=\""u8.ToArray();
-        private static readonly byte[] s_endDecl = "\"?>"u8.ToArray();
-        private static readonly byte[] s_utf8Decl = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"u8.ToArray();
-
         private static ReadOnlySpan<byte> Digits => "0123456789ABCDEF"u8;
 
         private static readonly bool[] s_defaultIsEscapedAttributeChar = new bool[]
@@ -127,64 +123,34 @@ namespace System.Xml
         {
             if (_encoding == null)
             {
-                WriteUTF8Chars(s_utf8Decl, 0, s_utf8Decl.Length);
+                WriteUTF8Bytes("<?xml version=\"1.0\" encoding=\"utf-8\"?>"u8);
             }
             else
             {
-                WriteUTF8Chars(s_startDecl, 0, s_startDecl.Length);
+                WriteUTF8Bytes("<?xml version=\"1.0\" encoding=\""u8);
                 if (_encoding.WebName == Encoding.BigEndianUnicode.WebName)
-                    WriteUTF8Chars("utf-16BE");
+                    WriteUTF8Bytes("utf-16BE"u8);
                 else
                     WriteUTF8Chars(_encoding.WebName);
-                WriteUTF8Chars(s_endDecl, 0, s_endDecl.Length);
+                WriteUTF8Bytes("\"?>"u8);
             }
         }
 
         public override void WriteCData(string text)
         {
-            byte[] buffer;
-            int offset;
-
-            buffer = GetBuffer(9, out offset);
-            buffer[offset + 0] = (byte)'<';
-            buffer[offset + 1] = (byte)'!';
-            buffer[offset + 2] = (byte)'[';
-            buffer[offset + 3] = (byte)'C';
-            buffer[offset + 4] = (byte)'D';
-            buffer[offset + 5] = (byte)'A';
-            buffer[offset + 6] = (byte)'T';
-            buffer[offset + 7] = (byte)'A';
-            buffer[offset + 8] = (byte)'[';
-            Advance(9);
-
+            WriteUTF8Bytes("<![CDATA["u8);
             WriteUTF8Chars(text);
-
-            buffer = GetBuffer(3, out offset);
-            buffer[offset + 0] = (byte)']';
-            buffer[offset + 1] = (byte)']';
-            buffer[offset + 2] = (byte)'>';
-            Advance(3);
+            WriteUTF8Bytes("]]>"u8);
         }
 
         private void WriteStartComment()
         {
-            int offset;
-            byte[] buffer = GetBuffer(4, out offset);
-            buffer[offset + 0] = (byte)'<';
-            buffer[offset + 1] = (byte)'!';
-            buffer[offset + 2] = (byte)'-';
-            buffer[offset + 3] = (byte)'-';
-            Advance(4);
+            WriteUTF8Bytes("<!--"u8);
         }
 
         private void WriteEndComment()
         {
-            int offset;
-            byte[] buffer = GetBuffer(3, out offset);
-            buffer[offset + 0] = (byte)'-';
-            buffer[offset + 1] = (byte)'-';
-            buffer[offset + 2] = (byte)'>';
-            Advance(3);
+            WriteUTF8Bytes("-->"u8);
         }
 
         public override void WriteComment(string text)
@@ -297,15 +263,7 @@ namespace System.Xml
 
         private void WriteStartXmlnsAttribute()
         {
-            int offset;
-            byte[] buffer = GetBuffer(6, out offset);
-            buffer[offset + 0] = (byte)' ';
-            buffer[offset + 1] = (byte)'x';
-            buffer[offset + 2] = (byte)'m';
-            buffer[offset + 3] = (byte)'l';
-            buffer[offset + 4] = (byte)'n';
-            buffer[offset + 5] = (byte)'s';
-            Advance(6);
+            WriteUTF8Bytes(" xmlns"u8);
             _inAttribute = true;
         }
 
@@ -403,7 +361,7 @@ namespace System.Xml
             }
             else
             {
-                WriteUTF8Chars(prefixBuffer, prefixOffset, prefixLength);
+                WriteUTF8Bytes(prefixBuffer.AsSpan(prefixOffset, prefixLength));
             }
         }
 
@@ -414,7 +372,7 @@ namespace System.Xml
 
         private void WriteLocalName(byte[] localNameBuffer, int localNameOffset, int localNameLength)
         {
-            WriteUTF8Chars(localNameBuffer, localNameOffset, localNameLength);
+            WriteUTF8Bytes(localNameBuffer.AsSpan(localNameOffset, localNameLength));
         }
 
         public override void WriteEscapedText(XmlDictionaryString s)
@@ -473,7 +431,7 @@ namespace System.Xml
                 byte ch = chars[offset + j];
                 if (ch < isEscapedCharLength && isEscapedChar[ch])
                 {
-                    WriteUTF8Chars(chars, offset + i, j - i);
+                    WriteUTF8Bytes(chars.AsSpan(offset + i, j - i));
                     WriteCharEntity(ch);
                     i = j + 1;
                 }
@@ -486,13 +444,13 @@ namespace System.Xml
                     byte ch3 = chars[offset + j + 2];
                     if (ch2 == 191 && (ch3 == 190 || ch3 == 191))
                     {
-                        WriteUTF8Chars(chars, offset + i, j - i);
+                        WriteUTF8Bytes(chars.AsSpan(offset + i, j - i));
                         WriteCharEntity(ch3 == 190 ? (char)0xFFFE : (char)0xFFFF);
                         i = j + 3;
                     }
                 }
             }
-            WriteUTF8Chars(chars, offset + i, count - i);
+            WriteUTF8Bytes(chars.AsSpan(offset + i, count - i));
         }
 
         public void WriteText(int ch)
@@ -502,7 +460,7 @@ namespace System.Xml
 
         public override void WriteText(byte[] chars, int offset, int count)
         {
-            WriteUTF8Chars(chars, offset, count);
+            WriteUTF8Bytes(chars.AsSpan(offset, count));
         }
 
         public override unsafe void WriteText(char[] chars, int offset, int count)
@@ -528,62 +486,27 @@ namespace System.Xml
 
         public void WriteLessThanCharEntity()
         {
-            int offset;
-            byte[] buffer = GetBuffer(4, out offset);
-            buffer[offset + 0] = (byte)'&';
-            buffer[offset + 1] = (byte)'l';
-            buffer[offset + 2] = (byte)'t';
-            buffer[offset + 3] = (byte)';';
-            Advance(4);
+            WriteUTF8Bytes("&lt;"u8);
         }
 
         public void WriteGreaterThanCharEntity()
         {
-            int offset;
-            byte[] buffer = GetBuffer(4, out offset);
-            buffer[offset + 0] = (byte)'&';
-            buffer[offset + 1] = (byte)'g';
-            buffer[offset + 2] = (byte)'t';
-            buffer[offset + 3] = (byte)';';
-            Advance(4);
+            WriteUTF8Bytes("&gt;"u8);
         }
 
         public void WriteAmpersandCharEntity()
         {
-            int offset;
-            byte[] buffer = GetBuffer(5, out offset);
-            buffer[offset + 0] = (byte)'&';
-            buffer[offset + 1] = (byte)'a';
-            buffer[offset + 2] = (byte)'m';
-            buffer[offset + 3] = (byte)'p';
-            buffer[offset + 4] = (byte)';';
-            Advance(5);
+            WriteUTF8Bytes("&amp;"u8);
         }
 
         public void WriteApostropheCharEntity()
         {
-            int offset;
-            byte[] buffer = GetBuffer(6, out offset);
-            buffer[offset + 0] = (byte)'&';
-            buffer[offset + 1] = (byte)'a';
-            buffer[offset + 2] = (byte)'p';
-            buffer[offset + 3] = (byte)'o';
-            buffer[offset + 4] = (byte)'s';
-            buffer[offset + 5] = (byte)';';
-            Advance(6);
+            WriteUTF8Bytes("&apos;"u8);
         }
 
         public void WriteQuoteCharEntity()
         {
-            int offset;
-            byte[] buffer = GetBuffer(6, out offset);
-            buffer[offset + 0] = (byte)'&';
-            buffer[offset + 1] = (byte)'q';
-            buffer[offset + 2] = (byte)'u';
-            buffer[offset + 3] = (byte)'o';
-            buffer[offset + 4] = (byte)'t';
-            buffer[offset + 5] = (byte)';';
-            Advance(6);
+            WriteUTF8Bytes("&quot;"u8);
         }
 
         private void WriteHexCharEntity(int ch)
@@ -595,7 +518,7 @@ namespace System.Xml
             chars[--offset] = (byte)'x';
             chars[--offset] = (byte)'#';
             chars[--offset] = (byte)'&';
-            WriteUTF8Chars(chars, offset, maxEntityLength - offset);
+            WriteUTF8Bytes(chars.AsSpan(offset, maxEntityLength - offset));
         }
 
         public override void WriteCharEntity(int ch)
@@ -638,36 +561,31 @@ namespace System.Xml
 
         public override void WriteBoolText(bool value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxBoolChars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxBoolChars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
         public override void WriteDecimalText(decimal value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxDecimalChars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxDecimalChars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
         public override void WriteDoubleText(double value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxDoubleChars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxDoubleChars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
         public override void WriteFloatText(float value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxFloatChars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxFloatChars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
         public override void WriteDateTimeText(DateTime value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxDateTimeChars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxDateTimeChars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
@@ -688,22 +606,19 @@ namespace System.Xml
 
         public override void WriteInt32Text(int value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxInt32Chars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxInt32Chars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
         public override void WriteInt64Text(long value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxInt64Chars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxInt64Chars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
         public override void WriteUInt64Text(ulong value)
         {
-            int offset;
-            byte[] buffer = GetBuffer(XmlConverter.MaxUInt64Chars, out offset);
+            byte[] buffer = GetBuffer(XmlConverter.MaxUInt64Chars, out int offset);
             Advance(XmlConverter.ToChars(value, buffer, offset));
         }
 
@@ -738,16 +653,14 @@ namespace System.Xml
             {
                 int byteCount = Math.Min(bufferLength / 4 * 3, count - count % 3);
                 int charCount = byteCount / 3 * 4;
-                int charOffset;
-                byte[] chars = GetBuffer(charCount, out charOffset);
+                byte[] chars = GetBuffer(charCount, out int charOffset);
                 Advance(encoding.GetChars(buffer, offset, byteCount, chars, charOffset));
                 offset += byteCount;
                 count -= byteCount;
             }
             if (count > 0)
             {
-                int charOffset;
-                byte[] chars = GetBuffer(4, out charOffset);
+                byte[] chars = GetBuffer(4, out int charOffset);
                 Advance(encoding.GetChars(buffer, offset, count, chars, charOffset));
             }
         }