dotnet/corefxdotnet/corefx#34200 Bring `XmlRawTextWriterGenerator.cxx` up to date...
authorJoseph Lennox <jlennox@gmail.com>
Mon, 7 Jan 2019 19:34:23 +0000 (11:34 -0800)
committerbuyaa-n <buyankhishig.namnan@microsoft.com>
Mon, 7 Jan 2019 19:34:23 +0000 (11:34 -0800)
* dotnet/corefxdotnet/corefx#34200 Bring `XmlRawTextWriterGenerator.cxx` up to date.

* dotnet/corefxdotnet/corefx#34200 Convert `XmlRawTextWriterGenerator.cxx` to t4.

* dotnet/corefxdotnet/corefx#34200 Normalize the inconsistent use of `this`

* dotnet/corefxdotnet/corefx#34200 Make XmlRawTextWriterGenerator run at compile time.

* dotnet/corefxdotnet/corefx#34200 Generate Xml*RawTextWriterAsync.cs files.

These files appear to of never been from a generation process but are
near identical.

* dotnet/corefxdotnet/corefx#34200 Normalize `this` in XmlRawTextWriterGeneratorAsync

* dotnet/corefxdotnet/corefx#34200 Convert Html*RawTextWriter.cs to t4 template.

* dotnet/corefxdotnet/corefx#34200 Convert Text*RawTextWriter.cs to t4 template.

* dotnet/corefxdotnet/corefx#34200 Normalize use of `this` in Html*RawTextWriter.

* dotnet/corefxdotnet/corefx#34200 Fix leading whitespace/bug #

* dotnet/corefxdotnet/corefx#34200 Add warning to generate files about modifying them.

Also fix the oversight that XmlRawTextWriterGeneratorAsync.ttinclude didn't
use the newer RawTextWriter.ttinclude abstraction.

* dotnet/corefxdotnet/corefx#34200 Make code generation produce better formatted code.

Commit migrated from https://github.com/dotnet/corefx/commit/a0e5f73d0c0876840bc4f3745e1ca8385a91cfcf

31 files changed:
src/libraries/System.Private.Xml/src/System.Private.Xml.csproj
src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateCoreWriters_sd.bat [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateCoreWriters_tfs.bat [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateWriters_sd.bat [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateWriters_tfs.bat [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.cxx [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriter.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterUtf8.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/TextRawTextWriterGenerator.cxx [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/TextRawTextWriterGenerator.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.cxx [deleted file]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.tt [new file with mode: 0644]
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs
src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.tt [new file with mode: 0644]

index dabe192..1ffd334 100644 (file)
     <Compile Include="System\Xml\Bits.cs" />
     <Compile Include="System\Xml\BitStack.cs" />
     <Compile Include="System\Xml\ByteStack.cs" />
+    <Compile Include="System\Xml\Core\HtmlEncodedRawTextWriter.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>HtmlEncodedRawTextWriter.tt</DependentUpon>
+    </Compile>
+    <Compile Include="System\Xml\Core\HtmlUtf8RawTextWriter.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>HtmlUtf8RawTextWriter.tt</DependentUpon>
+    </Compile>
+    <Compile Include="System\Xml\Core\TextEncodedRawTextWriter.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>TextEncodedRawTextWriter.tt</DependentUpon>
+    </Compile>
+    <Compile Include="System\Xml\Core\TextUtf8RawTextWriter.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>TextUtf8RawTextWriter.tt</DependentUpon>
+    </Compile>
+    <None Include="System\Xml\Core\HtmlEncodedRawTextWriter.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>HtmlEncodedRawTextWriter.cs</LastGenOutput>
+    </None>
+    <None Include="System\Xml\Core\HtmlRawTextWriterGenerator.ttinclude" />
+    <None Include="System\Xml\Core\HtmlUtf8RawTextWriter.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>HtmlUtf8RawTextWriter.cs</LastGenOutput>
+    </None>
+    <None Include="System\Xml\Core\RawTextWriter.ttinclude" />
+    <None Include="System\Xml\Core\TextEncodedRawTextWriter.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>TextEncodedRawTextWriter.cs</LastGenOutput>
+    </None>
+    <None Include="System\Xml\Core\TextRawTextWriterGenerator.ttinclude" />
+    <None Include="System\Xml\Core\TextUtf8RawTextWriter.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>TextUtf8RawTextWriter.cs</LastGenOutput>
+    </None>
+    <None Include="System\Xml\Core\XmlRawTextWriterGeneratorAsync.ttinclude" />
+    <None Include="System\Xml\Core\XmlRawTextWriterGenerator.ttinclude" />
+    <None Include="System\Xml\Core\RawTextWriterEncoded.ttinclude" />
+    <Content Include="System\Xml\Core\XmlEncodedRawTextWriter.tt">
+      <LastGenOutput>XmlEncodedRawTextWriter.cs</LastGenOutput>
+      <Generator>TextTemplatingFileGenerator</Generator>
+    </Content>
+    <Compile Include="System\Xml\Core\XmlEncodedRawTextWriter.cs">
+      <DependentUpon>XmlEncodedRawTextWriter.tt</DependentUpon>
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+    </Compile>
+    <Content Include="System\Xml\Core\XmlEncodedRawTextWriterAsync.tt">
+      <LastGenOutput>XmlEncodedRawTextWriterAsync.cs</LastGenOutput>
+      <Generator>TextTemplatingFileGenerator</Generator>
+    </Content>
+    <Compile Include="System\Xml\Core\XmlEncodedRawTextWriterAsync.cs">
+      <DependentUpon>XmlEncodedRawTextWriterAsync.tt</DependentUpon>
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+    </Compile>
+    <None Include="System\Xml\Core\RawTextWriterUtf8.ttinclude" />
+    <Content Include="System\Xml\Core\XmlUtf8RawTextWriter.tt">
+      <LastGenOutput>XmlUtf8RawTextWriter.cs</LastGenOutput>
+      <Generator>TextTemplatingFileGenerator</Generator>
+    </Content>
+    <Compile Include="System\Xml\Core\XmlUtf8RawTextWriter.cs">
+      <DependentUpon>XmlUtf8RawTextWriter.tt</DependentUpon>
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+    </Compile>
+    <Content Include="System\Xml\Core\XmlUtf8RawTextWriterAsync.tt">
+      <LastGenOutput>XmlUtf8RawTextWriterAsync.cs</LastGenOutput>
+      <Generator>TextTemplatingFileGenerator</Generator>
+    </Content>
+    <Compile Include="System\Xml\Core\XmlUtf8RawTextWriterAsync.cs">
+      <DependentUpon>XmlUtf8RawTextWriterAsync.tt</DependentUpon>
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+    </Compile>
     <Compile Include="System\Xml\DiagnosticsSwitches.cs" />
     <Compile Include="System\Xml\Dom\XmlNamedNodeMap.SmallXmlNodeList.cs" />
     <Compile Include="System\Xml\EmptyEnumerator.cs" />
     <Compile Include="System\Xml\Core\ConformanceLevel.cs" />
     <Compile Include="System\Xml\Core\DtdProcessing.cs" />
     <Compile Include="System\Xml\Core\EntityHandling.cs" />
-    <Compile Include="System\Xml\Core\HtmlEncodedRawTextWriter.cs" />
-    <None Include="System\Xml\Core\HtmlRawTextWriterGenerator.cxx" />
     <Compile Include="System\Xml\Core\HtmlTernaryTree.cs" />
-    <Compile Include="System\Xml\Core\HtmlUtf8RawTextWriter.cs" />
     <Compile Include="System\Xml\Core\IDtdInfo.cs" />
     <Compile Include="System\Xml\Core\IDtdParser.cs" />
     <Compile Include="System\Xml\Core\IDtdParserAsync.cs" />
     <Compile Include="System\Xml\Core\ReadOnlyTernaryTree.cs" />
     <Compile Include="System\Xml\Core\ReadState.cs" />
     <Compile Include="System\Xml\Core\SecureStringHasher.cs" />
-    <Compile Include="System\Xml\Core\TextEncodedRawTextWriter.cs" />
-    <None Include="System\Xml\Core\TextRawTextWriterGenerator.cxx" />
-    <Compile Include="System\Xml\Core\TextUtf8RawTextWriter.cs" />
     <Compile Include="System\Xml\Core\ValidatingReaderNodeData.cs" />
     <Compile Include="System\Xml\Core\ValidationType.cs" />
     <Compile Include="System\Xml\Core\WhitespaceHandling.cs" />
     <Compile Include="System\Xml\Core\XmlCharCheckingReaderAsync.cs" />
     <Compile Include="System\Xml\Core\XmlCharCheckingWriter.cs" />
     <Compile Include="System\Xml\Core\XmlCharCheckingWriterAsync.cs" />
-    <Compile Include="System\Xml\Core\XmlEncodedRawTextWriter.cs" />
-    <Compile Include="System\Xml\Core\XmlEncodedRawTextWriterAsync.cs" />
     <Compile Include="System\Xml\Core\XmlEventCache.cs" />
     <Compile Include="System\Xml\Core\XmlParserContext.cs" />
-    <None Include="System\Xml\Core\XmlRawTextWriterGenerator.cxx" />
     <Compile Include="System\Xml\Core\XmlRawWriter.cs" />
     <Compile Include="System\Xml\Core\XmlRawWriterAsync.cs" />
     <Compile Include="System\Xml\Core\XmlReader.cs" />
     <Compile Include="System\Xml\Core\XmlTextReaderImplHelpers.cs" />
     <Compile Include="System\Xml\Core\XmlTextReaderImplHelpersAsync.cs" />
     <Compile Include="System\Xml\Core\XmlTextWriter.cs" />
-    <Compile Include="System\Xml\Core\XmlUtf8RawTextWriter.cs" />
-    <Compile Include="System\Xml\Core\XmlUtf8RawTextWriterAsync.cs" />
     <Compile Include="System\Xml\Core\XmlValidatingReader.cs" />
     <Compile Include="System\Xml\Core\XmlValidatingReaderImpl.cs" />
     <Compile Include="System\Xml\Core\XmlValidatingReaderImplAsync.cs" />
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateCoreWriters_sd.bat b/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateCoreWriters_sd.bat
deleted file mode 100644 (file)
index d3df799..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-@echo off
-
-pushd %_NTDRIVE%%_NTROOT%\ndp\fx\src\Xml\System\Xml\Core
-echo. 
-echo Checking files out..
-echo.
-
-sd edit XmlUtf8RawTextWriter.cs
-sd edit XmlEncodedRawTextWriter.cs
-sd edit XmlUtf8RawTextWriter_SL.cs
-sd edit XmlEncodedRawTextWriter_SL.cs
-
-rem Make read-only in case user is offline and sd edit fails
-attrib -r XmlUtf8RawTextWriter.cs
-attrib -r XmlEncodedRawTextWriter.cs
-attrib -r XmlUtf8RawTextWriter_SL.cs
-attrib -r XmlEncodedRawTextWriter_SL.cs
-
-
-echo.
-echo Generating writers..
-echo.
-
-cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlUtf8RawTextWriter.cs
-cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlEncodedRawTextWriter.cs
-
-cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER /D SILVERLIGHT XmlRawTextWriterGenerator.cxx > XmlUtf8RawTextWriter_SL.cs
-cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER /D SILVERLIGHT XmlRawTextWriterGenerator.cxx > XmlEncodedRawTextWriter_SL.cs
-
-popd
\ No newline at end of file
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateCoreWriters_tfs.bat b/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateCoreWriters_tfs.bat
deleted file mode 100644 (file)
index 1832a1d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-@echo off
-
-pushd %_NTDRIVE%%_NTROOT%\ndp\fx\src\Xml\System\Xml\Core
-echo. 
-echo Checking files out..
-echo.
-
-call tf edit XmlUtf8RawTextWriter.cs
-call tf edit XmlEncodedRawTextWriter.cs
-call tf edit XmlUtf8RawTextWriter_SL.cs
-call tf edit XmlEncodedRawTextWriter_SL.cs
-
-rem Make read-only in case user is offline and sd edit fails
-attrib -r XmlUtf8RawTextWriter.cs
-attrib -r XmlEncodedRawTextWriter.cs
-attrib -r XmlUtf8RawTextWriter_SL.cs
-attrib -r XmlEncodedRawTextWriter_SL.cs
-
-
-echo.
-echo Generating writers..
-echo.
-
-cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlUtf8RawTextWriter.cs
-cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlEncodedRawTextWriter.cs
-
-cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER /D SILVERLIGHT XmlRawTextWriterGenerator.cxx > XmlUtf8RawTextWriter_SL.cs
-cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER /D SILVERLIGHT XmlRawTextWriterGenerator.cxx > XmlEncodedRawTextWriter_SL.cs
-
-popd
\ No newline at end of file
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateWriters_sd.bat b/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateWriters_sd.bat
deleted file mode 100644 (file)
index ba99aab..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-@echo off
-
-pushd %_NTDRIVE%%_NTROOT%\ndp\fx\src\Xml\System\Xml\Core
-
-call GenerateCoreWriters.bat
-
-echo. 
-echo Checking files out..
-echo.
-
-sd edit HtmlUtf8RawTextWriter.cs
-sd edit HtmlEncodedRawTextWriter.cs
-sd edit TextUtf8RawTextWriter.cs
-sd edit TextEncodedRawTextWriter.cs
-
-rem Make read-only in case user is offline and sd edit fails
-
-attrib -r HtmlUtf8RawTextWriter.cs
-attrib -r HtmlEncodedRawTextWriter.cs
-attrib -r TextUtf8RawTextWriter.cs
-attrib -r TextEncodedRawTextWriter.cs
-
-echo.
-echo Generating writers..
-echo.
-
-cl.exe /C /EP /D _HTML_UTF8_TEXT_WRITER HtmlRawTextWriterGenerator.cxx > HtmlUtf8RawTextWriter.cs
-cl.exe /C /EP /D _HTML_ENCODED_TEXT_WRITER HtmlRawTextWriterGenerator.cxx > HtmlEncodedRawTextWriter.cs
-cl.exe /C /EP /D _UTF8_TEXT_WRITER TextRawTextWriterGenerator.cxx > TextUtf8RawTextWriter.cs
-cl.exe /C /EP /D _ENCODED_TEXT_WRITER TextRawTextWriterGenerator.cxx > TextEncodedRawTextWriter.cs
-
-popd
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateWriters_tfs.bat b/src/libraries/System.Private.Xml/src/System/Xml/Core/GenerateWriters_tfs.bat
deleted file mode 100644 (file)
index 163cc27..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-@echo off
-
-pushd %_NTDRIVE%%_NTROOT%\ndp\fx\src\Xml\System\Xml\Core
-
-call GenerateCoreWriters.bat
-
-echo. 
-echo Checking files out..
-echo.
-
-call tf edit HtmlUtf8RawTextWriter.cs
-call tf edit HtmlEncodedRawTextWriter.cs
-call tf edit TextUtf8RawTextWriter.cs
-call tf edit TextEncodedRawTextWriter.cs
-
-rem Make read-only in case user is offline and sd edit fails
-
-attrib -r HtmlUtf8RawTextWriter.cs
-attrib -r HtmlEncodedRawTextWriter.cs
-attrib -r TextUtf8RawTextWriter.cs
-attrib -r TextEncodedRawTextWriter.cs
-
-echo.
-echo Generating writers..
-echo.
-
-cl.exe /C /EP /D _HTML_UTF8_TEXT_WRITER HtmlRawTextWriterGenerator.cxx > HtmlUtf8RawTextWriter.cs
-cl.exe /C /EP /D _HTML_ENCODED_TEXT_WRITER HtmlRawTextWriterGenerator.cxx > HtmlEncodedRawTextWriter.cs
-cl.exe /C /EP /D _UTF8_TEXT_WRITER TextRawTextWriterGenerator.cxx > TextUtf8RawTextWriter.cs
-cl.exe /C /EP /D _ENCODED_TEXT_WRITER TextRawTextWriterGenerator.cxx > TextEncodedRawTextWriter.cs
-
-popd
index 2e099a1..beea8b6 100644 (file)
@@ -1,17 +1,9 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// Following comment might not be valid anymore as this code is fairly old and a lot happened since it was written...
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify XmlTextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER HtmlTextWriterGenerator.cxx > HtmlUtf8TextWriter.cs
-//   cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER HtmlTextWriterGenerator.cxx > HtmlEncodedTextWriter.cs
-//
-// Because these two implementations of XmlTextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify HtmlRawTextWriterGenerator.ttinclude
 
 using System;
 using System.IO;
@@ -45,7 +37,6 @@ namespace System.Xml
             Init(settings);
         }
 
-
         public HtmlEncodedRawTextWriter(Stream stream, XmlWriterSettings settings) : base(stream, settings)
         {
             Init(settings);
@@ -105,7 +96,7 @@ namespace System.Xml
                 bufChars[bufPos++] = (char)']';
             }
 
-            bufChars[this.bufPos++] = (char)'>';
+            bufChars[bufPos++] = (char)'>';
         }
 
         // For the HTML element, it should call this method with ns and prefix as String.Empty
@@ -120,6 +111,7 @@ namespace System.Xml
                 Debug.Assert(prefix.Length == 0);
 
                 if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
+
                 currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName);
                 base.bufChars[bufPos++] = (char)'<';
                 base.RawText(localName);
@@ -140,7 +132,7 @@ namespace System.Xml
             base.bufChars[base.bufPos++] = (char)'>';
 
             // Detect whether content is output
-            this.contentPos = this.bufPos;
+            contentPos = bufPos;
 
             if ((currentElementProperties & ElementProperties.HEAD) != 0)
             {
@@ -306,6 +298,7 @@ namespace System.Xml
             if (ns.Length == 0)
             {
                 Debug.Assert(prefix.Length == 0);
+
                 if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
 
                 if (base.attrEndPos == bufPos)
@@ -568,7 +561,7 @@ namespace System.Xml
 
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
 
                 char ch = (char)0;
                 for (;;)
@@ -611,7 +604,7 @@ namespace System.Xml
                             }
                             else if (pSrc[1] != '{')
                             {
-                                pDst = XmlEncodedRawTextWriter.AmpEntity(pDst);
+                                pDst = AmpEntity(pDst);
                                 break;
                             }
                             *pDst++ = (char)ch;
@@ -656,7 +649,7 @@ namespace System.Xml
 
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
 
                 char ch = (char)0;
                 for (;;)
@@ -699,7 +692,7 @@ namespace System.Xml
                             }
                             else if (pSrc[1] != '{')
                             {
-                                pDst = XmlEncodedRawTextWriter.AmpEntity(pDst);
+                                pDst = AmpEntity(pDst);
                                 break;
                             }
                             *pDst++ = (char)ch;
@@ -723,6 +716,7 @@ namespace System.Xml
                             break;
                         default:
                             const string hexDigits = "0123456789ABCDEF";
+                            Debug.Assert(_uriEscapingBuffer?.Length > 0);
                             fixed (byte* pUriEscapingBuffer = _uriEscapingBuffer)
                             {
                                 byte* pByte = pUriEscapingBuffer;
@@ -756,7 +750,6 @@ namespace System.Xml
         }
     }
 
-
     //
     // Indentation HtmlWriter only indent <BLOCK><BLOCK> situations
     //
@@ -812,13 +805,11 @@ namespace System.Xml
         // Constructors
         //
 
-
         public HtmlEncodedRawTextWriterIndent(TextWriter writer, XmlWriterSettings settings) : base(writer, settings)
         {
             Init(settings);
         }
 
-
         public HtmlEncodedRawTextWriterIndent(Stream stream, XmlWriterSettings settings) : base(stream, settings)
         {
             Init(settings);
@@ -985,4 +976,3 @@ namespace System.Xml
     }
 }
 
-
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.tt
new file mode 100644 (file)
index 0000000..133372f
--- /dev/null
@@ -0,0 +1,11 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterEncoded.ttinclude" #>
+<#
+    ClassName = "HtmlEncodedRawTextWriter";
+    ClassNameIndent = "HtmlEncodedRawTextWriterIndent";
+    BaseClassName = "XmlEncodedRawTextWriter";
+#>
+<#@ include file="HtmlRawTextWriterGenerator.ttinclude" #>
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.cxx b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.cxx
deleted file mode 100644 (file)
index 6cce1c5..0000000
+++ /dev/null
@@ -1,923 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify XmlTextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER HtmlTextWriterGenerator.cxx > HtmlUtf8TextWriter.cs
-//   cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER HtmlTextWriterGenerator.cxx > HtmlEncodedTextWriter.cs
-//
-// Because these two implementations of XmlTextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-#ifdef _HTML_UTF8_TEXT_WRITER
-#define _CLASS_NAME HtmlUtf8RawTextWriter
-#define _BASE_CLASS_NAME XmlUtf8RawTextWriter
-#define _CLASS_NAME_INDENT HtmlUtf8RawTextWriterIndent
-#define _BUFFER bufBytes
-#define _BUFFER_TYPE byte
-#define _SET_TEXT_CONTENT_MARK(value) 
-#endif
-
-#ifdef _HTML_ENCODED_TEXT_WRITER
-#define _CLASS_NAME HtmlEncodedRawTextWriter
-#define _BASE_CLASS_NAME XmlEncodedRawTextWriter
-#define _CLASS_NAME_INDENT HtmlEncodedRawTextWriterIndent
-#define _BUFFER bufChars
-#define _BUFFER_TYPE char
-#define _SET_TEXT_CONTENT_MARK(value) \
-    if ( trackTextContent && inTextContent != value ) { \
-        ChangeTextContentMark( value );  \
-    }
-#endif
-
-#define XMLCHARTYPE_TEST(ch, flag)              ( ( xmlCharType.charProperties[ch] & XmlCharType.##flag ) != 0 )
-#define XMLCHARTYPE_ISATTRIBUTEVALUECHAR(ch)    XMLCHARTYPE_TEST(ch, fAttrValue)
-
-using System;
-using System.IO;
-using System.Text;
-using System.Xml;
-using System.Xml.Schema;
-//using System.Xml.Query;
-using System.Diagnostics;
-using MS.Internal.Xml;
-
-namespace System.Xml {
-
-    internal class _CLASS_NAME : _BASE_CLASS_NAME {
-//
-// Fields
-//
-        protected ByteStack         elementScope;
-        protected ElementProperties currentElementProperties;
-        private AttributeProperties currentAttributeProperties;
-
-        private bool    endsWithAmpersand;
-        private byte [] uriEscapingBuffer;
-
-        // settings
-        private string  mediaType;
-        private bool doNotEscapeUriAttributes;
-
-//
-// Static fields
-//
-        protected static TernaryTreeReadOnly elementPropertySearch;
-        protected static TernaryTreeReadOnly attributePropertySearch;
-
-//
-// Constants
-//
-        private const int StackIncrement = 10;
-
-//
-// Constructors
-//
-
-#ifdef _HTML_ENCODED_TEXT_WRITER
-
-        public _CLASS_NAME( TextWriter writer, XmlWriterSettings settings ) : base( writer, settings ) {
-            Init( settings );
-        }
-#endif
-
-        public _CLASS_NAME( Stream stream, XmlWriterSettings settings ) : base( stream, settings ) {
-            Init( settings );
-        }
-
-//
-// XmlRawWriter implementation
-//
-        internal override void WriteXmlDeclaration( XmlStandalone standalone ) {
-            // Ignore xml declaration
-        }
-
-        internal override void WriteXmlDeclaration( string xmldecl ) {
-            // Ignore xml declaration
-        }
-
-        /// Html rules allow public ID without system ID and always output "html"
-        public override void WriteDocType( string name, string pubid, string sysid, string subset ) {
-            Debug.Assert( name != null && name.Length > 0 );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            RawText( "<!DOCTYPE ");
-
-            // Bug 114337: Always output "html" or "HTML" in doc-type, even if "name" is something else
-            if ( name == "HTML" )
-                RawText( "HTML" );
-            else
-                RawText( "html" );
-
-            if ( pubid != null ) {
-                RawText( " PUBLIC \"" );
-                RawText( pubid );
-                if ( sysid != null ) {
-                    RawText( "\" \"" );
-                    RawText( sysid );
-                }
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            }
-            else if ( sysid != null ) {
-                RawText( " SYSTEM \"" );
-                RawText( sysid );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            }
-            else {
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ' ';
-            }
-
-            if ( subset != null ) {
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '[';
-                RawText( subset );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ']';
-            }
-
-            _BUFFER[this.bufPos++] = (_BUFFER_TYPE) '>';
-        }
-
-        // For the HTML element, it should call this method with ns and prefix as String.Empty
-        public override void WriteStartElement( string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length != 0 && prefix != null && ns != null );
-
-            elementScope.Push( (byte)currentElementProperties );
-
-            if ( ns.Length == 0 ) {
-                Debug.Assert( prefix.Length == 0 );
-
-                _SET_TEXT_CONTENT_MARK(false)
-                currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString( localName );
-                base._BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-                base.RawText( localName );
-                base.attrEndPos = bufPos;
-            }
-            else {
-                // Since the HAS_NS has no impact to the ElementTextBlock behavior,
-                // we don't need to push it into the stack.
-                currentElementProperties = ElementProperties.HAS_NS;
-                base.WriteStartElement( prefix, localName, ns );
-            }
-        }
-
-        // Output >. For HTML needs to output META info
-        internal override void StartElementContent() {
-            base._BUFFER[base.bufPos++] = (_BUFFER_TYPE) '>';
-
-            // Detect whether content is output
-            this.contentPos = this.bufPos;
-
-            if ( ( currentElementProperties & ElementProperties.HEAD ) != 0 ) {
-                WriteMetaElement();
-            }
-        }
-
-        // end element with />
-        // for HTML(ns.Length == 0)
-        //    not an empty tag <h1></h1>
-        //    empty tag <basefont>
-        internal override void WriteEndElement( string prefix, string localName, string ns ) {
-            if ( ns.Length == 0 ) {
-                Debug.Assert( prefix.Length == 0 );
-
-                _SET_TEXT_CONTENT_MARK(false)
-
-                if ( ( currentElementProperties & ElementProperties.EMPTY ) == 0 ) {
-                    _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '<'; 
-                    _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '/'; 
-                    base.RawText( localName ); 
-                    _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '>';
-                }
-            }
-            else {
-                //xml content
-                base.WriteEndElement( prefix, localName, ns );
-            }
-
-            currentElementProperties = (ElementProperties)elementScope.Pop();
-       }
-
-        internal override void WriteFullEndElement( string prefix, string localName, string ns ) {
-            if ( ns.Length == 0 ) {
-                Debug.Assert( prefix.Length == 0 );
-
-                _SET_TEXT_CONTENT_MARK(false)
-
-                if ( ( currentElementProperties & ElementProperties.EMPTY ) == 0 ) {
-                    _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '<'; 
-                    _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '/'; 
-                    base.RawText( localName ); 
-                    _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '>';
-                }
-            }
-            else {
-                //xml content
-                base.WriteFullEndElement( prefix, localName, ns );
-            }
-
-            currentElementProperties = (ElementProperties)elementScope.Pop();
-        }
-
-        // 1. How the outputBooleanAttribute(fBOOL) and outputHtmlUriText(fURI) being set?
-        // When SA is called.
-        //
-        //             BOOL_PARENT   URI_PARENT   Others
-        //  fURI
-        //  URI att       false         true       false
-        //
-        //  fBOOL
-        //  BOOL att      true          false      false
-        //
-        //  How they change the attribute output behaviors?
-        //
-        //  1)       fURI=true             fURI=false
-        //  SA         a="                      a="
-        //  AT       HtmlURIText             HtmlText
-        //  EA          "                       "
-        //
-        //  2)      fBOOL=true             fBOOL=false
-        //  SA         a                       a="
-        //  AT      HtmlText                output nothing
-        //  EA     output nothing               "
-        //
-        // When they get reset?
-        //  At the end of attribute.
-
-        // 2. How the outputXmlTextElementScoped(fENs) and outputXmlTextattributeScoped(fANs) are set?
-        //  fANs is in the scope of the fENs.
-        //
-        //          SE(localName)    SE(ns, pre, localName)  SA(localName)  SA(ns, pre, localName)
-        //  fENs      false(default)      true(action)
-        //  fANs      false(default)     false(default)      false(default)      true(action)
-
-        // how they get reset?
-        //
-        //          EE(localName)  EE(ns, pre, localName) EENC(ns, pre, localName) EA(localName)  EA(ns, pre, localName)
-        //  fENs                      false(action)
-        //  fANs                                                                                        false(action)
-
-        // How they change the TextOutput?
-        //
-        //         fENs | fANs              Else
-        //  AT      XmlText                  HtmlText
-        //
-        //
-        // 3. Flags for processing &{ split situations
-        //
-        // When the flag is set?
-        //
-        //  AT     src[lastchar]='&' flag&{ = true;
-        //
-        // when it get result?
-        //
-        //  AT method.
-        //
-        // How it changes the behaviors?
-        //
-        //         flag&{=true
-        //
-        //  AT     if (src[0] == '{') {
-        //             output "&{"
-        //         }
-        //         else {
-        //             output &amp;
-        //         }
-        //
-        //  EA     output amp;
-        //
-
-        //  SA  if (flagBOOL == false) { output =";}
-        //
-        //  AT  if (flagBOOL) { return};
-        //      if (flagNS) {XmlText;} {
-        //      }
-        //      else if (flagURI) {
-        //          HtmlURIText;
-        //      }
-        //      else {
-        //          HtmlText;
-        //      }
-        //
-
-        //  AT  if (flagNS) {XmlText;} {
-        //      }
-        //      else if (flagURI) {
-        //          HtmlURIText;
-        //      }
-        //      else if (!flagBOOL) {
-        //          HtmlText; //flag&{ handling
-        //      }
-        //
-        //
-        //  EA if (flagBOOL == false) { output "
-        //     }
-        //     else if (flag&{) {
-        //          output amp;
-        //     }
-        //
-        public override void WriteStartAttribute( string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length != 0 && prefix != null  && ns != null );
-
-            if ( ns.Length == 0 ) {
-                Debug.Assert( prefix.Length == 0 );
-                _SET_TEXT_CONTENT_MARK(false)
-
-                if ( base.attrEndPos == bufPos ) {
-                    base._BUFFER[bufPos++] = (_BUFFER_TYPE) ' ';
-                }
-                base.RawText( localName );
-
-                if ( ( currentElementProperties & ( ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT ) ) != 0 ) {
-                    currentAttributeProperties = (AttributeProperties)attributePropertySearch.FindCaseInsensitiveString( localName ) &
-                                                 (AttributeProperties)currentElementProperties;
-
-                    if ( ( currentAttributeProperties & AttributeProperties.BOOLEAN ) != 0 ) {
-                        base.inAttributeValue = true;
-                        return;
-                    }
-                }
-                else {
-                    currentAttributeProperties = AttributeProperties.DEFAULT;
-                }
-
-                base._BUFFER[bufPos++] = (_BUFFER_TYPE) '=';
-                base._BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            }
-            else {
-                base.WriteStartAttribute( prefix, localName, ns );
-                currentAttributeProperties = AttributeProperties.DEFAULT;
-            }
-
-            base.inAttributeValue = true;
-        }
-
-        // Output the amp; at end of EndAttribute
-        public override void WriteEndAttribute() {
-
-            if ( ( currentAttributeProperties & AttributeProperties.BOOLEAN ) != 0 ) {
-                base.attrEndPos = bufPos;
-            }
-            else {
-                if ( endsWithAmpersand ) {
-                    OutputRestAmps();
-                    endsWithAmpersand = false;
-                }
-
-                _SET_TEXT_CONTENT_MARK(false)
-
-                base._BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            }
-            base.inAttributeValue = false;
-            base.attrEndPos = bufPos;
-        }
-
-        // HTML PI's use ">" to terminate rather than "?>".
-        public override void WriteProcessingInstruction( string target, string text ) {
-            Debug.Assert( target != null && target.Length != 0 && text != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '<';
-            _BUFFER[base.bufPos++] = (_BUFFER_TYPE) '?';
-            base.RawText( target );
-            _BUFFER[base.bufPos++] = (_BUFFER_TYPE) ' ';
-
-            base.WriteCommentOrPi( text, '?' );
-
-            base._BUFFER[base.bufPos++] = (_BUFFER_TYPE) '>';
-
-            if ( base.bufPos > base.bufLen ) {
-                FlushBuffer();
-            }
-        }
-
-        // Serialize either attribute or element text using HTML rules.
-        public override unsafe void WriteString( string text ) {
-            Debug.Assert( text != null );
-
-            _SET_TEXT_CONTENT_MARK(true)
-
-            fixed ( char * pSrc = text ) {
-                char * pSrcEnd = pSrc + text.Length;
-                if ( base.inAttributeValue) {
-                    WriteHtmlAttributeTextBlock( pSrc, pSrcEnd );
-                }
-                else {
-                    WriteHtmlElementTextBlock( pSrc, pSrcEnd );
-                }
-            }
-        }
-
-        public override void WriteEntityRef( string name ) {
-            throw new InvalidOperationException( string.Format( SR.Xml_InvalidOperation ) );
-        }
-
-        public override void WriteCharEntity( char ch ) {
-            throw new InvalidOperationException( string.Format( SR.Xml_InvalidOperation ) );
-        }
-
-        public override void WriteSurrogateCharEntity( char lowChar, char highChar ) {
-            throw new InvalidOperationException( string.Format( SR.Xml_InvalidOperation ) );
-        }
-
-        public override unsafe void WriteChars( char[] buffer, int index, int count ) {
-            Debug.Assert( buffer != null );
-            Debug.Assert( index >= 0 );
-            Debug.Assert( count >= 0 && index + count <= buffer.Length );
-
-            _SET_TEXT_CONTENT_MARK(true)
-
-            fixed ( char * pSrcBegin = &buffer[index] ) {
-                if ( inAttributeValue ) {
-                    WriteAttributeTextBlock( pSrcBegin, pSrcBegin + count );
-                }
-                else {
-                    WriteElementTextBlock( pSrcBegin, pSrcBegin + count );
-                }
-            }
-        }
-
-//
-// Private methods
-//
-
-        private void Init( XmlWriterSettings settings ) {
-            Debug.Assert( (int)ElementProperties.URI_PARENT == (int)AttributeProperties.URI );
-            Debug.Assert( (int)ElementProperties.BOOL_PARENT == (int)AttributeProperties.BOOLEAN );
-            Debug.Assert( (int)ElementProperties.NAME_PARENT == (int)AttributeProperties.NAME );
-
-            if ( elementPropertySearch == null ) {
-                //elementPropertySearch should be init last for the mutli thread safe situation.
-                attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes );
-                elementPropertySearch = new TernaryTreeReadOnly( HtmlTernaryTree.htmlElements );
-            }
-
-            elementScope = new ByteStack( StackIncrement );
-            uriEscapingBuffer = new byte[5];
-            currentElementProperties = ElementProperties.DEFAULT;
-
-            mediaType = settings.MediaType;
-            doNotEscapeUriAttributes = settings.DoNotEscapeUriAttributes;
-        }
-
-        protected void WriteMetaElement() {
-            base.RawText("<META http-equiv=\"Content-Type\"");
-
-            if ( mediaType == null ) {
-                mediaType = "text/html";
-            }
-
-            base.RawText( " content=\"" );
-            base.RawText( mediaType );
-            base.RawText( "; charset=" );
-            base.RawText( base.encoding.WebName );
-            base.RawText( "\">" );
-        }
-
-        // Justify the stack usage:
-        //
-        // Nested elements has following possible position combinations
-        // 1. <E1>Content1<E2>Content2</E2></E1>
-        // 2. <E1><E2>Content2</E2>Content1</E1>
-        // 3. <E1>Content<E2>Cotent2</E2>Content1</E1>
-        //
-        // In the situation 2 and 3, the stored currentElementProrperties will be E2's,
-        // only the top of the stack is the real E1 element properties.
-        protected unsafe void WriteHtmlElementTextBlock( char * pSrc, char * pSrcEnd ) {
-            if ( ( currentElementProperties & ElementProperties.NO_ENTITIES ) != 0 ) {
-                base.RawText( pSrc, pSrcEnd );
-            } else {
-                base.WriteElementTextBlock( pSrc, pSrcEnd );
-            }
-
-        }
-
-        protected unsafe void WriteHtmlAttributeTextBlock( char * pSrc, char * pSrcEnd ) {
-            if ( ( currentAttributeProperties & ( AttributeProperties.BOOLEAN | AttributeProperties.URI | AttributeProperties.NAME ) ) != 0 ) {
-                if ( ( currentAttributeProperties & AttributeProperties.BOOLEAN ) != 0 ) {
-                    //if output boolean attribute, ignore this call.
-                    return;
-                }
-
-                if ( ( currentAttributeProperties & ( AttributeProperties.URI | AttributeProperties.NAME ) ) != 0 && !doNotEscapeUriAttributes ) {
-                    WriteUriAttributeText( pSrc, pSrcEnd );
-                }
-                else {
-                    WriteHtmlAttributeText( pSrc, pSrcEnd );
-                }
-            }
-            else if ( ( currentElementProperties & ElementProperties.HAS_NS ) != 0 ) {
-                base.WriteAttributeTextBlock( pSrc, pSrcEnd );
-            }
-            else {
-                WriteHtmlAttributeText( pSrc, pSrcEnd );
-            }
-        }
-
-        //
-        // &{ split cases
-        // 1). HtmlAttributeText("a&");
-        //     HtmlAttributeText("{b}");
-        //
-        // 2). HtmlAttributeText("a&");
-        //     EndAttribute();
-
-        // 3).split with Flush by the user
-        //     HtmlAttributeText("a&");
-        //     FlushBuffer();
-        //     HtmlAttributeText("{b}");
-
-        //
-        // Solutions:
-        // case 1)hold the &amp; output as &
-        //      if the next income character is {, output {
-        //      else output amp;
-        //
-
-        private unsafe void WriteHtmlAttributeText( char * pSrc, char *pSrcEnd ) {
-            if ( endsWithAmpersand ) {
-                if ( pSrcEnd - pSrc > 0 && pSrc[0] != '{' ) {
-                    OutputRestAmps();
-                }
-                endsWithAmpersand = false;
-            }
-
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                _BUFFER_TYPE * pDst = pDstBegin + this.bufPos;
-
-                char ch = (char)0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-#if _HTML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) ) ) {
-#endif
-                        *pDst++ = (_BUFFER_TYPE)ch;
-                        pSrc++;
-                    }
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // some character needs to be escaped
-                    switch ( ch ) {
-                        case '&':
-                            if ( pSrc + 1 == pSrcEnd ) {
-                                endsWithAmpersand = true;
-                            }
-                            else if ( pSrc[1] != '{' ) {
-                                pDst = _BASE_CLASS_NAME.AmpEntity(pDst);
-                                break;
-                            }
-                            *pDst++ = (_BUFFER_TYPE)ch;
-                            break;
-                        case '"':
-                            pDst = QuoteEntity( pDst );
-                            break;
-                        case '<':
-                        case '>':
-                        case '\'':
-                        case (char)0x9:
-                            *pDst++ = (_BUFFER_TYPE)ch;
-                            break;
-                        case (char)0xD:
-                            // do not normalize new lines in attributes - just escape them
-                            pDst = CarriageReturnEntity( pDst );
-                            break;
-                        case (char)0xA:
-                            // do not normalize new lines in attributes - just escape them
-                            pDst = LineFeedEntity( pDst );
-                            break;
-                        default:
-                            EncodeChar( ref pSrc, pSrcEnd, ref pDst);
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-        private unsafe void WriteUriAttributeText( char * pSrc, char * pSrcEnd ) {
-            if ( endsWithAmpersand ) {
-                if ( pSrcEnd - pSrc > 0 && pSrc[0] != '{' ) {
-                    OutputRestAmps();
-                }
-                this.endsWithAmpersand = false;
-            }
-
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                _BUFFER_TYPE * pDst = pDstBegin + this.bufPos;
-
-                char ch = (char)0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch < 0x80 ) ) {
-                        *pDst++ = (_BUFFER_TYPE)ch;
-                        pSrc++;
-                    }
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // some character needs to be escaped
-                    switch ( ch ) {
-                        case '&':
-                            if ( pSrc + 1 == pSrcEnd ) {
-                                endsWithAmpersand = true;
-                            }
-                            else if ( pSrc[1] != '{' ) {
-                                pDst = _BASE_CLASS_NAME.AmpEntity(pDst);
-                                break;
-                            }
-                            *pDst++ = (_BUFFER_TYPE)ch;
-                            break;
-                        case '"':
-                            pDst = QuoteEntity( pDst );
-                            break;
-                        case '<':
-                        case '>':
-                        case '\'':
-                        case (char)0x9:
-                            *pDst++ = (_BUFFER_TYPE)ch;
-                            break;
-                        case (char)0xD:
-                            // do not normalize new lines in attributes - just escape them
-                            pDst = CarriageReturnEntity( pDst );
-                            break;
-                        case (char)0xA:
-                            // do not normalize new lines in attributes - just escape them
-                            pDst = LineFeedEntity( pDst );
-                            break;
-                        default:
-                            const string hexDigits = "0123456789ABCDEF";
-                            fixed ( byte * pUriEscapingBuffer = uriEscapingBuffer ) {
-                                byte * pByte = pUriEscapingBuffer;
-                                byte * pEnd = pByte;
-
-                                XmlUtf8RawTextWriter.CharToUTF8( ref pSrc, pSrcEnd, ref pEnd );
-
-                                while ( pByte < pEnd ) {
-                                    *pDst++ = (_BUFFER_TYPE) '%'; 
-                                    *pDst++ = (_BUFFER_TYPE) hexDigits[*pByte >> 4];
-                                    *pDst++ = (_BUFFER_TYPE) hexDigits[*pByte & 0xF];
-                                    pByte++;
-                                }
-                            }
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-        // For handling &{ in Html text field. If & is not followed by {, it still needs to be escaped.
-        private void OutputRestAmps() {
-            base._BUFFER[bufPos++] = (_BUFFER_TYPE)'a';
-            base._BUFFER[bufPos++] = (_BUFFER_TYPE)'m';
-            base._BUFFER[bufPos++] = (_BUFFER_TYPE)'p';
-            base._BUFFER[bufPos++] = (_BUFFER_TYPE)';';
-        }
-    }
-
-
-    //
-    // Indentation HtmlWriter only indent <BLOCK><BLOCK> situations
-    //
-    // Here are all the cases:
-    //       ELEMENT1     actions          ELEMENT2          actions                                 SC              EE
-    // 1).    SE SC   store SE blockPro       SE           a). check ELEMENT1 blockPro                  <A>           </A>
-    //        EE     if SE, EE are blocks                  b). true: check ELEMENT2 blockPro                <B>            <B>
-    //                                                     c). detect ELEMENT is SE, SC
-    //                                                     d). increase the indexlevel
-    //
-    // 2).    SE SC,  Store EE blockPro       EE            a). check stored blockPro                    <A></A>            </A>
-    //         EE    if SE, EE are blocks                  b). true:  indexLevel same                                  </B>
-    //
-
-
-    //
-    // This is an alternative way to make the output looks better
-    //
-    // Indentation HtmlWriter only indent <BLOCK><BLOCK> situations
-    //
-    // Here are all the cases:
-    //       ELEMENT1     actions           ELEMENT2          actions                                 Samples
-    // 1).    SE SC   store SE blockPro       SE            a). check ELEMENT1 blockPro                  <A>(blockPos)
-    //                                                     b). true: check ELEMENT2 blockPro                <B>
-    //                                                     c). detect ELEMENT is SE, SC
-    //                                                     d). increase the indentLevel
-    //
-    // 2).     EE     Store EE blockPro       SE            a). check stored blockPro                    </A>
-    //                                                     b). true:  indentLevel same                   <B>
-    //                                                     c). output block2
-    //
-    // 3).     EE      same as above          EE            a). check stored blockPro                          </A>
-    //                                                     b). true:  --indentLevel                        </B>
-    //                                                     c). output block2
-    //
-    // 4).    SE SC    same as above          EE            a). check stored blockPro                      <A></A>
-    //                                                     b). true:  indentLevel no change
-    internal class _CLASS_NAME_INDENT : _CLASS_NAME {
-//
-// Fields
-//
-        int indentLevel;
-
-        // for detecting SE SC situation
-        int endBlockPos;
-
-        // settings
-        string  indentChars;
-        bool    newLineOnAttributes;
-
-//
-// Constructors
-//
-#ifdef _HTML_ENCODED_TEXT_WRITER
-
-        public _CLASS_NAME_INDENT( TextWriter writer, XmlWriterSettings settings ) : base( writer, settings ) {
-            Init( settings );
-        }
-#endif
-
-        public _CLASS_NAME_INDENT( Stream stream, XmlWriterSettings settings ) : base( stream, settings ) {
-            Init( settings );
-        }
-
-//
-// XmlRawWriter overrides
-//
-        /// <summary>
-        /// Serialize the document type declaration.
-        /// </summary>
-        public override void WriteDocType( string name, string pubid, string sysid, string subset ) {
-            base.WriteDocType( name, pubid, sysid, subset );
-
-            // Allow indentation after DocTypeDecl
-            endBlockPos = base.bufPos;
-        }
-
-        public override void WriteStartElement(string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length != 0 && prefix != null && ns != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            base.elementScope.Push( (byte)base.currentElementProperties );
-
-            if ( ns.Length == 0 ) {
-                Debug.Assert( prefix.Length == 0 );
-
-                base.currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString( localName );
-
-                if ( endBlockPos == base.bufPos && ( base.currentElementProperties & ElementProperties.BLOCK_WS ) != 0 ) {
-                    WriteIndent();
-                }
-                indentLevel++;
-
-                base._BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-            }
-            else {
-                base.currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS;
-
-                if ( endBlockPos == base.bufPos ) {
-                    WriteIndent();
-                }
-                indentLevel++;
-
-                base._BUFFER[base.bufPos++] = (_BUFFER_TYPE) '<';
-                if ( prefix.Length != 0 ) {
-                    base.RawText( prefix );
-                    base._BUFFER[base.bufPos++] = (_BUFFER_TYPE) ':';
-                }
-            }
-            base.RawText( localName );
-            base.attrEndPos = bufPos;
-        }
-
-        internal override void StartElementContent() {
-            base._BUFFER[base.bufPos++] = (_BUFFER_TYPE) '>';
-
-            // Detect whether content is output
-            base.contentPos = base.bufPos;
-
-            if ( ( currentElementProperties & ElementProperties.HEAD ) != 0) {
-                WriteIndent();
-                WriteMetaElement();
-                endBlockPos = base.bufPos;
-            }
-            else if ( ( base.currentElementProperties & ElementProperties.BLOCK_WS ) != 0 ) {
-                // store the element block position
-                endBlockPos = base.bufPos;
-            }
-        }
-
-        internal override void WriteEndElement( string prefix, string localName, string ns ) {
-            bool isBlockWs;
-            Debug.Assert( localName != null && localName.Length != 0 && prefix != null && ns != null );
-
-            indentLevel--;
-
-            // If this element has block whitespace properties,
-            isBlockWs = ( base.currentElementProperties & ElementProperties.BLOCK_WS ) != 0;
-            if ( isBlockWs ) {
-                // And if the last node to be output had block whitespace properties,
-                // And if content was output within this element,
-                if ( endBlockPos == base.bufPos && base.contentPos != base.bufPos ) {
-                    // Then indent
-                    WriteIndent();
-                }
-            }
-
-            base.WriteEndElement(prefix, localName, ns);
-
-            // Reset contentPos in case of empty elements
-            base.contentPos = 0;
-
-            // Mark end of element in buffer for element's with block whitespace properties
-            if ( isBlockWs ) {
-                endBlockPos = base.bufPos;
-            }
-        }
-
-        public override void WriteStartAttribute( string prefix, string localName, string ns ) {
-            if ( newLineOnAttributes ) {
-                RawText( base.newLineChars );
-                indentLevel++;
-                WriteIndent();
-                indentLevel--;
-            }
-            base.WriteStartAttribute( prefix, localName, ns );
-        }
-
-        protected override void FlushBuffer() {
-            // Make sure the buffer will reset the block position
-            endBlockPos = ( endBlockPos == base.bufPos ) ? 1 : 0;
-            base.FlushBuffer();
-        }
-
-//
-// Private methods
-//
-        private void Init( XmlWriterSettings settings ) {
-            indentLevel = 0;
-            indentChars = settings.IndentChars;
-            newLineOnAttributes = settings.NewLineOnAttributes;
-        }
-
-        private void WriteIndent() {
-            // <block><inline>  -- suppress ws betw <block> and <inline>
-            // <block><block>   -- don't suppress ws betw <block> and <block>
-            // <block>text      -- suppress ws betw <block> and text (handled by wcharText method)
-            // <block><?PI?>    -- suppress ws betw <block> and PI
-            // <block><!-- -->  -- suppress ws betw <block> and comment
-
-            // <inline><block>  -- suppress ws betw <inline> and <block>
-            // <inline><inline> -- suppress ws betw <inline> and <inline>
-            // <inline>text     -- suppress ws betw <inline> and text (handled by wcharText method)
-            // <inline><?PI?>   -- suppress ws betw <inline> and PI
-            // <inline><!-- --> -- suppress ws betw <inline> and comment
-
-            RawText( base.newLineChars );
-            for ( int i = indentLevel; i > 0; i-- ) {
-                RawText( indentChars );
-            }
-        }
-    }
-}
-
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude
new file mode 100644 (file)
index 0000000..d9e8428
--- /dev/null
@@ -0,0 +1,987 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriter.ttinclude" #>// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify HtmlRawTextWriterGenerator.ttinclude
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.Schema;
+using System.Diagnostics;
+using MS.Internal.Xml;
+
+namespace System.Xml
+{
+    internal class <#= ClassName #> : <#= BaseClassName #>
+    {
+        protected ByteStack elementScope;
+        protected ElementProperties currentElementProperties;
+        private AttributeProperties _currentAttributeProperties;
+
+        private bool _endsWithAmpersand;
+        private byte[] _uriEscapingBuffer;
+
+        private string _mediaType;
+        private bool _doNotEscapeUriAttributes;
+
+        protected static TernaryTreeReadOnly elementPropertySearch;
+        protected static TernaryTreeReadOnly attributePropertySearch;
+
+        private const int StackIncrement = 10;
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+
+        public <#= ClassName #>(TextWriter writer, XmlWriterSettings settings) : base(writer, settings)
+        {
+            Init(settings);
+        }
+<# } #>
+
+        public <#= ClassName #>(Stream stream, XmlWriterSettings settings) : base(stream, settings)
+        {
+            Init(settings);
+        }
+
+        internal override void WriteXmlDeclaration(XmlStandalone standalone)
+        {
+            // Ignore xml declaration
+        }
+
+        internal override void WriteXmlDeclaration(string xmldecl)
+        {
+            // Ignore xml declaration
+        }
+
+        /// Html rules allow public ID without system ID and always output "html"
+        public override void WriteDocType(string name, string pubid, string sysid, string subset)
+        {
+            Debug.Assert(name != null && name.Length > 0);<#
+/* Code block is to squash extra line. */
+#><#= SetTextContentMark(3, false) #>
+
+            RawText("<!DOCTYPE ");
+
+            // Bug: Always output "html" or "HTML" in doc-type, even if "name" is something else
+            if (name == "HTML")
+                RawText("HTML");
+            else
+                RawText("html");
+
+            if (pubid != null)
+            {
+                RawText(" PUBLIC \"");
+                RawText(pubid);
+                if (sysid != null)
+                {
+                    RawText("\" \"");
+                    RawText(sysid);
+                }
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else if (sysid != null)
+            {
+                RawText(" SYSTEM \"");
+                RawText(sysid);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+            }
+
+            if (subset != null)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+                RawText(subset);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            }
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // For the HTML element, it should call this method with ns and prefix as String.Empty
+        public override void WriteStartElement(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);
+
+            elementScope.Push((byte)currentElementProperties);
+
+            if (ns.Length == 0)
+            {
+                Debug.Assert(prefix.Length == 0);<#
+
+#><#= SetTextContentMark(4, false) #>
+
+                currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName);
+                base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+                base.RawText(localName);
+                base.attrEndPos = bufPos;
+            }
+            else
+            {
+                // Since the HAS_NS has no impact to the ElementTextBlock behavior,
+                // we don't need to push it into the stack.
+                currentElementProperties = ElementProperties.HAS_NS;
+                base.WriteStartElement(prefix, localName, ns);
+            }
+        }
+
+        // Output >. For HTML needs to output META info
+        internal override void StartElementContent()
+        {
+            base.<#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'>';
+
+            // Detect whether content is output
+            contentPos = bufPos;
+
+            if ((currentElementProperties & ElementProperties.HEAD) != 0)
+            {
+                WriteMetaElement();
+            }
+        }
+
+        // end element with />
+        // for HTML(ns.Length == 0)
+        //    not an empty tag <h1></h1>
+        //    empty tag <basefont>
+        internal override void WriteEndElement(string prefix, string localName, string ns)
+        {
+            if (ns.Length == 0)
+            {
+                Debug.Assert(prefix.Length == 0);<#
+
+#><#= SetTextContentMark(4, false) #>
+
+                if ((currentElementProperties & ElementProperties.EMPTY) == 0)
+                {
+                    <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'<';
+                    <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'/';
+                    base.RawText(localName);
+                    <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'>';
+                }
+            }
+            else
+            {
+                //xml content
+                base.WriteEndElement(prefix, localName, ns);
+            }
+
+            currentElementProperties = (ElementProperties)elementScope.Pop();
+        }
+
+        internal override void WriteFullEndElement(string prefix, string localName, string ns)
+        {
+            if (ns.Length == 0)
+            {
+                Debug.Assert(prefix.Length == 0);<#
+
+#><#= SetTextContentMark(4, false) #>
+
+                if ((currentElementProperties & ElementProperties.EMPTY) == 0)
+                {
+                    <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'<';
+                    <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'/';
+                    base.RawText(localName);
+                    <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'>';
+                }
+            }
+            else
+            {
+                //xml content
+                base.WriteFullEndElement(prefix, localName, ns);
+            }
+
+            currentElementProperties = (ElementProperties)elementScope.Pop();
+        }
+
+        // 1. How the outputBooleanAttribute(fBOOL) and outputHtmlUriText(fURI) being set?
+        // When SA is called.
+        //
+        //             BOOL_PARENT   URI_PARENT   Others
+        //  fURI
+        //  URI att       false         true       false
+        //
+        //  fBOOL
+        //  BOOL att      true          false      false
+        //
+        //  How they change the attribute output behaviors?
+        //
+        //  1)       fURI=true             fURI=false
+        //  SA         a="                      a="
+        //  AT       HtmlURIText             HtmlText
+        //  EA          "                       "
+        //
+        //  2)      fBOOL=true             fBOOL=false
+        //  SA         a                       a="
+        //  AT      HtmlText                output nothing
+        //  EA     output nothing               "
+        //
+        // When they get reset?
+        //  At the end of attribute.
+
+        // 2. How the outputXmlTextElementScoped(fENs) and outputXmlTextattributeScoped(fANs) are set?
+        //  fANs is in the scope of the fENs.
+        //
+        //          SE(localName)    SE(ns, pre, localName)  SA(localName)  SA(ns, pre, localName)
+        //  fENs      false(default)      true(action)
+        //  fANs      false(default)     false(default)      false(default)      true(action)
+
+        // how they get reset?
+        //
+        //          EE(localName)  EE(ns, pre, localName) EENC(ns, pre, localName) EA(localName)  EA(ns, pre, localName)
+        //  fENs                      false(action)
+        //  fANs                                                                                        false(action)
+
+        // How they change the TextOutput?
+        //
+        //         fENs | fANs              Else
+        //  AT      XmlText                  HtmlText
+        //
+        //
+        // 3. Flags for processing &{ split situations
+        //
+        // When the flag is set?
+        //
+        //  AT     src[lastchar]='&' flag&{ = true;
+        //
+        // when it get result?
+        //
+        //  AT method.
+        //
+        // How it changes the behaviors?
+        //
+        //         flag&{=true
+        //
+        //  AT     if (src[0] == '{') {
+        //             output "&{"
+        //         }
+        //         else {
+        //             output &amp;
+        //         }
+        //
+        //  EA     output amp;
+        //
+
+        //  SA  if (flagBOOL == false) { output =";}
+        //
+        //  AT  if (flagBOOL) { return};
+        //      if (flagNS) {XmlText;} {
+        //      }
+        //      else if (flagURI) {
+        //          HtmlURIText;
+        //      }
+        //      else {
+        //          HtmlText;
+        //      }
+        //
+
+        //  AT  if (flagNS) {XmlText;} {
+        //      }
+        //      else if (flagURI) {
+        //          HtmlURIText;
+        //      }
+        //      else if (!flagBOOL) {
+        //          HtmlText; //flag&{ handling
+        //      }
+        //
+        //
+        //  EA if (flagBOOL == false) { output "
+        //     }
+        //     else if (flag&{) {
+        //          output amp;
+        //     }
+        //
+        public override void WriteStartAttribute(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);
+
+            if (ns.Length == 0)
+            {
+                Debug.Assert(prefix.Length == 0);<#
+
+#><#= SetTextContentMark(4, false) #>
+
+                if (base.attrEndPos == bufPos)
+                {
+                    base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+                }
+                base.RawText(localName);
+
+                if ((currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0)
+                {
+                    _currentAttributeProperties = (AttributeProperties)attributePropertySearch.FindCaseInsensitiveString(localName) &
+                                                 (AttributeProperties)currentElementProperties;
+
+                    if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0)
+                    {
+                        base.inAttributeValue = true;
+                        return;
+                    }
+                }
+                else
+                {
+                    _currentAttributeProperties = AttributeProperties.DEFAULT;
+                }
+
+                base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'=';
+                base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else
+            {
+                base.WriteStartAttribute(prefix, localName, ns);
+                _currentAttributeProperties = AttributeProperties.DEFAULT;
+            }
+
+            base.inAttributeValue = true;
+        }
+
+        // Output the amp; at end of EndAttribute
+        public override void WriteEndAttribute()
+        {
+            if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0)
+            {
+                base.attrEndPos = bufPos;
+            }
+            else
+            {
+                if (_endsWithAmpersand)
+                {
+                    OutputRestAmps();
+                    _endsWithAmpersand = false;
+                }<#
+
+#><#= SetTextContentMark(4, false) #>
+
+                base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            base.inAttributeValue = false;
+            base.attrEndPos = bufPos;
+        }
+
+        // HTML PI's use ">" to terminate rather than "?>".
+        public override void WriteProcessingInstruction(string target, string text)
+        {
+            Debug.Assert(target != null && target.Length != 0 && text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'?';
+            base.RawText(target);
+            <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)' ';
+
+            base.WriteCommentOrPi(text, '?');
+
+            base.<#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'>';
+
+            if (base.bufPos > base.bufLen)
+            {
+                FlushBuffer();
+            }
+        }
+
+        // Serialize either attribute or element text using HTML rules.
+        public override unsafe void WriteString(string text)
+        {
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, true) #>
+
+            fixed (char* pSrc = text)
+            {
+                char* pSrcEnd = pSrc + text.Length;
+                if (base.inAttributeValue)
+                {
+                    WriteHtmlAttributeTextBlock(pSrc, pSrcEnd);
+                }
+                else
+                {
+                    WriteHtmlElementTextBlock(pSrc, pSrcEnd);
+                }
+            }
+        }
+
+        public override void WriteEntityRef(string name)
+        {
+            throw new InvalidOperationException(SR.Xml_InvalidOperation);
+        }
+
+        public override void WriteCharEntity(char ch)
+        {
+            throw new InvalidOperationException(SR.Xml_InvalidOperation);
+        }
+
+        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
+        {
+            throw new InvalidOperationException(SR.Xml_InvalidOperation);
+        }
+
+        public override unsafe void WriteChars(char[] buffer, int index, int count)
+        {
+            Debug.Assert(buffer != null);
+            Debug.Assert(index >= 0);
+            Debug.Assert(count >= 0 && index + count <= buffer.Length);<#
+
+#><#= SetTextContentMark(3, true) #>
+
+            fixed (char* pSrcBegin = &buffer[index])
+            {
+                if (inAttributeValue)
+                {
+                    WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count);
+                }
+                else
+                {
+                    WriteElementTextBlock(pSrcBegin, pSrcBegin + count);
+                }
+            }
+        }
+
+        //
+        // Private methods
+        //
+
+        private void Init(XmlWriterSettings settings)
+        {
+            Debug.Assert((int)ElementProperties.URI_PARENT == (int)AttributeProperties.URI);
+            Debug.Assert((int)ElementProperties.BOOL_PARENT == (int)AttributeProperties.BOOLEAN);
+            Debug.Assert((int)ElementProperties.NAME_PARENT == (int)AttributeProperties.NAME);
+
+            if (elementPropertySearch == null)
+            {
+                //elementPropertySearch should be init last for the mutli thread safe situation.
+                attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes);
+                elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements);
+            }
+
+            elementScope = new ByteStack(StackIncrement);
+            _uriEscapingBuffer = new byte[5];
+            currentElementProperties = ElementProperties.DEFAULT;
+
+            _mediaType = settings.MediaType;
+            _doNotEscapeUriAttributes = settings.DoNotEscapeUriAttributes;
+        }
+
+        protected void WriteMetaElement()
+        {
+            base.RawText("<META http-equiv=\"Content-Type\"");
+
+            if (_mediaType == null)
+            {
+                _mediaType = "text/html";
+            }
+
+            base.RawText(" content=\"");
+            base.RawText(_mediaType);
+            base.RawText("; charset=");
+            base.RawText(base.encoding.WebName);
+            base.RawText("\">");
+        }
+
+        // Justify the stack usage:
+        //
+        // Nested elements has following possible position combinations
+        // 1. <E1>Content1<E2>Content2</E2></E1>
+        // 2. <E1><E2>Content2</E2>Content1</E1>
+        // 3. <E1>Content<E2>Cotent2</E2>Content1</E1>
+        //
+        // In the situation 2 and 3, the stored currentElementProrperties will be E2's,
+        // only the top of the stack is the real E1 element properties.
+        protected unsafe void WriteHtmlElementTextBlock(char* pSrc, char* pSrcEnd)
+        {
+            if ((currentElementProperties & ElementProperties.NO_ENTITIES) != 0)
+            {
+                base.RawText(pSrc, pSrcEnd);
+            }
+            else
+            {
+                base.WriteElementTextBlock(pSrc, pSrcEnd);
+            }
+        }
+
+        protected unsafe void WriteHtmlAttributeTextBlock(char* pSrc, char* pSrcEnd)
+        {
+            if ((_currentAttributeProperties & (AttributeProperties.BOOLEAN | AttributeProperties.URI | AttributeProperties.NAME)) != 0)
+            {
+                if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0)
+                {
+                    //if output boolean attribute, ignore this call.
+                    return;
+                }
+
+                if ((_currentAttributeProperties & (AttributeProperties.URI | AttributeProperties.NAME)) != 0 && !_doNotEscapeUriAttributes)
+                {
+                    WriteUriAttributeText(pSrc, pSrcEnd);
+                }
+                else
+                {
+                    WriteHtmlAttributeText(pSrc, pSrcEnd);
+                }
+            }
+            else if ((currentElementProperties & ElementProperties.HAS_NS) != 0)
+            {
+                base.WriteAttributeTextBlock(pSrc, pSrcEnd);
+            }
+            else
+            {
+                WriteHtmlAttributeText(pSrc, pSrcEnd);
+            }
+        }
+
+        //
+        // &{ split cases
+        // 1). HtmlAttributeText("a&");
+        //     HtmlAttributeText("{b}");
+        //
+        // 2). HtmlAttributeText("a&");
+        //     EndAttribute();
+
+        // 3).split with Flush by the user
+        //     HtmlAttributeText("a&");
+        //     FlushBuffer();
+        //     HtmlAttributeText("{b}");
+
+        //
+        // Solutions:
+        // case 1)hold the &amp; output as &
+        //      if the next income character is {, output {
+        //      else output amp;
+        //
+
+        private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd)
+        {
+            if (_endsWithAmpersand)
+            {
+                if (pSrcEnd - pSrc > 0 && pSrc[0] != '{')
+                {
+                    OutputRestAmps();
+                }
+                _endsWithAmpersand = false;
+            }
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                char ch = (char)0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst++ = (<#= BufferType #>)ch;
+                        pSrc++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // some character needs to be escaped
+                    switch (ch)
+                    {
+                        case '&':
+                            if (pSrc + 1 == pSrcEnd)
+                            {
+                                _endsWithAmpersand = true;
+                            }
+                            else if (pSrc[1] != '{')
+                            {
+                                pDst = AmpEntity(pDst);
+                                break;
+                            }
+                            *pDst++ = (<#= BufferType #>)ch;
+                            break;
+                        case '"':
+                            pDst = QuoteEntity(pDst);
+                            break;
+                        case '<':
+                        case '>':
+                        case '\'':
+                        case (char)0x9:
+                            *pDst++ = (<#= BufferType #>)ch;
+                            break;
+                        case (char)0xD:
+                            // do not normalize new lines in attributes - just escape them
+                            pDst = CarriageReturnEntity(pDst);
+                            break;
+                        case (char)0xA:
+                            // do not normalize new lines in attributes - just escape them
+                            pDst = LineFeedEntity(pDst);
+                            break;
+                        default:
+                            EncodeChar(ref pSrc, pSrcEnd, ref pDst);
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+        private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd)
+        {
+            if (_endsWithAmpersand)
+            {
+                if (pSrcEnd - pSrc > 0 && pSrc[0] != '{')
+                {
+                    OutputRestAmps();
+                }
+                _endsWithAmpersand = false;
+            }
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                char ch = (char)0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch < 0x80))
+                    {
+                        *pDst++ = (<#= BufferType #>)ch;
+                        pSrc++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // some character needs to be escaped
+                    switch (ch)
+                    {
+                        case '&':
+                            if (pSrc + 1 == pSrcEnd)
+                            {
+                                _endsWithAmpersand = true;
+                            }
+                            else if (pSrc[1] != '{')
+                            {
+                                pDst = AmpEntity(pDst);
+                                break;
+                            }
+                            *pDst++ = (<#= BufferType #>)ch;
+                            break;
+                        case '"':
+                            pDst = QuoteEntity(pDst);
+                            break;
+                        case '<':
+                        case '>':
+                        case '\'':
+                        case (char)0x9:
+                            *pDst++ = (<#= BufferType #>)ch;
+                            break;
+                        case (char)0xD:
+                            // do not normalize new lines in attributes - just escape them
+                            pDst = CarriageReturnEntity(pDst);
+                            break;
+                        case (char)0xA:
+                            // do not normalize new lines in attributes - just escape them
+                            pDst = LineFeedEntity(pDst);
+                            break;
+                        default:
+                            const string hexDigits = "0123456789ABCDEF";
+                            Debug.Assert(_uriEscapingBuffer?.Length > 0);
+                            fixed (byte* pUriEscapingBuffer = _uriEscapingBuffer)
+                            {
+                                byte* pByte = pUriEscapingBuffer;
+                                byte* pEnd = pByte;
+
+                                XmlUtf8RawTextWriter.CharToUTF8(ref pSrc, pSrcEnd, ref pEnd);
+
+                                while (pByte < pEnd)
+                                {
+                                    *pDst++ = (<#= BufferType #>)'%';
+                                    *pDst++ = (<#= BufferType #>)hexDigits[*pByte >> 4];
+                                    *pDst++ = (<#= BufferType #>)hexDigits[*pByte & 0xF];
+                                    pByte++;
+                                }
+                            }
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+        // For handling &{ in Html text field. If & is not followed by {, it still needs to be escaped.
+        private void OutputRestAmps()
+        {
+            base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'a';
+            base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'m';
+            base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'p';
+            base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+        }
+    }
+
+    //
+    // Indentation HtmlWriter only indent <BLOCK><BLOCK> situations
+    //
+    // Here are all the cases:
+    //       ELEMENT1     actions          ELEMENT2          actions                                 SC              EE
+    // 1).    SE SC   store SE blockPro       SE           a). check ELEMENT1 blockPro                  <A>           </A>
+    //        EE     if SE, EE are blocks                  b). true: check ELEMENT2 blockPro                <B>            <B>
+    //                                                     c). detect ELEMENT is SE, SC
+    //                                                     d). increase the indexlevel
+    //
+    // 2).    SE SC,  Store EE blockPro       EE            a). check stored blockPro                    <A></A>            </A>
+    //         EE    if SE, EE are blocks                  b). true:  indexLevel same                                  </B>
+    //
+
+
+    //
+    // This is an alternative way to make the output looks better
+    //
+    // Indentation HtmlWriter only indent <BLOCK><BLOCK> situations
+    //
+    // Here are all the cases:
+    //       ELEMENT1     actions           ELEMENT2          actions                                 Samples
+    // 1).    SE SC   store SE blockPro       SE            a). check ELEMENT1 blockPro                  <A>(blockPos)
+    //                                                     b). true: check ELEMENT2 blockPro                <B>
+    //                                                     c). detect ELEMENT is SE, SC
+    //                                                     d). increase the indentLevel
+    //
+    // 2).     EE     Store EE blockPro       SE            a). check stored blockPro                    </A>
+    //                                                     b). true:  indentLevel same                   <B>
+    //                                                     c). output block2
+    //
+    // 3).     EE      same as above          EE            a). check stored blockPro                          </A>
+    //                                                     b). true:  --indentLevel                        </B>
+    //                                                     c). output block2
+    //
+    // 4).    SE SC    same as above          EE            a). check stored blockPro                      <A></A>
+    //                                                     b). true:  indentLevel no change
+    internal class <#= ClassNameIndent #> : <#= ClassName #>
+    {
+        //
+        // Fields
+        //
+        private int _indentLevel;
+
+        // for detecting SE SC sitution
+        private int _endBlockPos;
+
+        // settings
+        private string _indentChars;
+        private bool _newLineOnAttributes;
+
+        //
+        // Constructors
+        //
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+
+        public <#= ClassNameIndent #>(TextWriter writer, XmlWriterSettings settings) : base(writer, settings)
+        {
+            Init(settings);
+        }
+<# } #>
+
+        public <#= ClassNameIndent #>(Stream stream, XmlWriterSettings settings) : base(stream, settings)
+        {
+            Init(settings);
+        }
+
+        //
+        // XmlRawWriter overrides
+        //
+        /// <summary>
+        /// Serialize the document type declaration.
+        /// </summary>
+        public override void WriteDocType(string name, string pubid, string sysid, string subset)
+        {
+            base.WriteDocType(name, pubid, sysid, subset);
+
+            // Allow indentation after DocTypeDecl
+            _endBlockPos = base.bufPos;
+        }
+
+        public override void WriteStartElement(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            base.elementScope.Push((byte)base.currentElementProperties);
+
+            if (ns.Length == 0)
+            {
+                Debug.Assert(prefix.Length == 0);
+
+                base.currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName);
+
+                if (_endBlockPos == base.bufPos && (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0)
+                {
+                    WriteIndent();
+                }
+                _indentLevel++;
+
+                base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            }
+            else
+            {
+                base.currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS;
+
+                if (_endBlockPos == base.bufPos)
+                {
+                    WriteIndent();
+                }
+                _indentLevel++;
+
+                base.<#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'<';
+                if (prefix.Length != 0)
+                {
+                    base.RawText(prefix);
+                    base.<#= BufferName #>[base.bufPos++] = (<#= BufferType #>)':';
+                }
+            }
+            base.RawText(localName);
+            base.attrEndPos = bufPos;
+        }
+
+        internal override void StartElementContent()
+        {
+            base.<#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'>';
+
+            // Detect whether content is output
+            base.contentPos = base.bufPos;
+
+            if ((currentElementProperties & ElementProperties.HEAD) != 0)
+            {
+                WriteIndent();
+                WriteMetaElement();
+                _endBlockPos = base.bufPos;
+            }
+            else if ((base.currentElementProperties & ElementProperties.BLOCK_WS) != 0)
+            {
+                // store the element block position
+                _endBlockPos = base.bufPos;
+            }
+        }
+
+        internal override void WriteEndElement(string prefix, string localName, string ns)
+        {
+            bool isBlockWs;
+            Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);
+
+            _indentLevel--;
+
+            // If this element has block whitespace properties,
+            isBlockWs = (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0;
+            if (isBlockWs)
+            {
+                // And if the last node to be output had block whitespace properties,
+                // And if content was output within this element,
+                if (_endBlockPos == base.bufPos && base.contentPos != base.bufPos)
+                {
+                    // Then indent
+                    WriteIndent();
+                }
+            }
+
+            base.WriteEndElement(prefix, localName, ns);
+
+            // Reset contentPos in case of empty elements
+            base.contentPos = 0;
+
+            // Mark end of element in buffer for element's with block whitespace properties
+            if (isBlockWs)
+            {
+                _endBlockPos = base.bufPos;
+            }
+        }
+
+        public override void WriteStartAttribute(string prefix, string localName, string ns)
+        {
+            if (_newLineOnAttributes)
+            {
+                RawText(base.newLineChars);
+                _indentLevel++;
+                WriteIndent();
+                _indentLevel--;
+            }
+            base.WriteStartAttribute(prefix, localName, ns);
+        }
+
+        protected override void FlushBuffer()
+        {
+            // Make sure the buffer will reset the block position
+            _endBlockPos = (_endBlockPos == base.bufPos) ? 1 : 0;
+            base.FlushBuffer();
+        }
+
+        //
+        // Private methods
+        //
+        private void Init(XmlWriterSettings settings)
+        {
+            _indentLevel = 0;
+            _indentChars = settings.IndentChars;
+            _newLineOnAttributes = settings.NewLineOnAttributes;
+        }
+
+        private void WriteIndent()
+        {
+            // <block><inline>  -- suppress ws betw <block> and <inline>
+            // <block><block>   -- don't suppress ws betw <block> and <block>
+            // <block>text      -- suppress ws betw <block> and text (handled by wcharText method)
+            // <block><?PI?>    -- suppress ws betw <block> and PI
+            // <block><!-- -->  -- suppress ws betw <block> and comment
+
+            // <inline><block>  -- suppress ws betw <inline> and <block>
+            // <inline><inline> -- suppress ws betw <inline> and <inline>
+            // <inline>text     -- suppress ws betw <inline> and text (handled by wcharText method)
+            // <inline><?PI?>   -- suppress ws betw <inline> and PI
+            // <inline><!-- --> -- suppress ws betw <inline> and comment
+
+            RawText(base.newLineChars);
+            for (int i = _indentLevel; i > 0; i--)
+            {
+                RawText(_indentChars);
+            }
+        }
+    }
+}
index 59c24f4..28593cc 100644 (file)
@@ -1,17 +1,9 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// Following comment might not be valid anymore as this code is fairly old and a lot happened since it was written...
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify XmlTextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER HtmlTextWriterGenerator.cxx > HtmlUtf8TextWriter.cs
-//   cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER HtmlTextWriterGenerator.cxx > HtmlEncodedTextWriter.cs
-//
-// Because these two implementations of XmlTextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify HtmlRawTextWriterGenerator.ttinclude
 
 using System;
 using System.IO;
@@ -62,7 +54,7 @@ namespace System.Xml
 
             RawText("<!DOCTYPE ");
 
-            // Bug 114337: Always output "html" or "HTML" in doc-type, even if "name" is something else
+            // Bug: Always output "html" or "HTML" in doc-type, even if "name" is something else
             if (name == "HTML")
                 RawText("HTML");
             else
@@ -97,7 +89,7 @@ namespace System.Xml
                 bufBytes[bufPos++] = (byte)']';
             }
 
-            bufBytes[this.bufPos++] = (byte)'>';
+            bufBytes[bufPos++] = (byte)'>';
         }
 
         // For the HTML element, it should call this method with ns and prefix as String.Empty
@@ -111,7 +103,6 @@ namespace System.Xml
             {
                 Debug.Assert(prefix.Length == 0);
 
-
                 currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName);
                 base.bufBytes[bufPos++] = (byte)'<';
                 base.RawText(localName);
@@ -132,7 +123,7 @@ namespace System.Xml
             base.bufBytes[base.bufPos++] = (byte)'>';
 
             // Detect whether content is output
-            this.contentPos = this.bufPos;
+            contentPos = bufPos;
 
             if ((currentElementProperties & ElementProperties.HEAD) != 0)
             {
@@ -150,8 +141,6 @@ namespace System.Xml
             {
                 Debug.Assert(prefix.Length == 0);
 
-
-
                 if ((currentElementProperties & ElementProperties.EMPTY) == 0)
                 {
                     bufBytes[base.bufPos++] = (byte)'<';
@@ -175,8 +164,6 @@ namespace System.Xml
             {
                 Debug.Assert(prefix.Length == 0);
 
-
-
                 if ((currentElementProperties & ElementProperties.EMPTY) == 0)
                 {
                     bufBytes[base.bufPos++] = (byte)'<';
@@ -299,7 +286,6 @@ namespace System.Xml
             {
                 Debug.Assert(prefix.Length == 0);
 
-
                 if (base.attrEndPos == bufPos)
                 {
                     base.bufBytes[bufPos++] = (byte)' ';
@@ -349,8 +335,6 @@ namespace System.Xml
                     _endsWithAmpersand = false;
                 }
 
-
-
                 base.bufBytes[bufPos++] = (byte)'"';
             }
             base.inAttributeValue = false;
@@ -362,8 +346,6 @@ namespace System.Xml
         {
             Debug.Assert(target != null && target.Length != 0 && text != null);
 
-
-
             bufBytes[base.bufPos++] = (byte)'<';
             bufBytes[base.bufPos++] = (byte)'?';
             base.RawText(target);
@@ -384,8 +366,6 @@ namespace System.Xml
         {
             Debug.Assert(text != null);
 
-
-
             fixed (char* pSrc = text)
             {
                 char* pSrcEnd = pSrc + text.Length;
@@ -421,8 +401,6 @@ namespace System.Xml
             Debug.Assert(index >= 0);
             Debug.Assert(count >= 0 && index + count <= buffer.Length);
 
-
-
             fixed (char* pSrcBegin = &buffer[index])
             {
                 if (inAttributeValue)
@@ -436,6 +414,10 @@ namespace System.Xml
             }
         }
 
+        //
+        // Private methods
+        //
+
         private void Init(XmlWriterSettings settings)
         {
             Debug.Assert((int)ElementProperties.URI_PARENT == (int)AttributeProperties.URI);
@@ -556,7 +538,7 @@ namespace System.Xml
 
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
 
                 char ch = (char)0;
                 for (;;)
@@ -599,7 +581,7 @@ namespace System.Xml
                             }
                             else if (pSrc[1] != '{')
                             {
-                                pDst = XmlUtf8RawTextWriter.AmpEntity(pDst);
+                                pDst = AmpEntity(pDst);
                                 break;
                             }
                             *pDst++ = (byte)ch;
@@ -644,7 +626,7 @@ namespace System.Xml
 
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
 
                 char ch = (char)0;
                 for (;;)
@@ -687,7 +669,7 @@ namespace System.Xml
                             }
                             else if (pSrc[1] != '{')
                             {
-                                pDst = XmlUtf8RawTextWriter.AmpEntity(pDst);
+                                pDst = AmpEntity(pDst);
                                 break;
                             }
                             *pDst++ = (byte)ch;
@@ -712,7 +694,7 @@ namespace System.Xml
                         default:
                             const string hexDigits = "0123456789ABCDEF";
                             Debug.Assert(_uriEscapingBuffer?.Length > 0);
-                            fixed (byte* pUriEscapingBuffer = &_uriEscapingBuffer[0])
+                            fixed (byte* pUriEscapingBuffer = _uriEscapingBuffer)
                             {
                                 byte* pByte = pUriEscapingBuffer;
                                 byte* pEnd = pByte;
@@ -745,7 +727,6 @@ namespace System.Xml
         }
     }
 
-
     //
     // Indentation HtmlWriter only indent <BLOCK><BLOCK> situations
     //
@@ -801,12 +782,6 @@ namespace System.Xml
         // Constructors
         //
 
-
-
-
-
-
-
         public HtmlUtf8RawTextWriterIndent(Stream stream, XmlWriterSettings settings) : base(stream, settings)
         {
             Init(settings);
@@ -830,8 +805,6 @@ namespace System.Xml
         {
             Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);
 
-
-
             base.elementScope.Push((byte)base.currentElementProperties);
 
             if (ns.Length == 0)
@@ -973,4 +946,3 @@ namespace System.Xml
     }
 }
 
-
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.tt
new file mode 100644 (file)
index 0000000..d8f6091
--- /dev/null
@@ -0,0 +1,11 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterUtf8.ttinclude" #>
+<#
+    ClassName = "HtmlUtf8RawTextWriter";
+    ClassNameIndent = "HtmlUtf8RawTextWriterIndent";
+    BaseClassName = "XmlUtf8RawTextWriter";
+#>
+<#@ include file="HtmlRawTextWriterGenerator.ttinclude" #>
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriter.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriter.ttinclude
new file mode 100644 (file)
index 0000000..0adf239
--- /dev/null
@@ -0,0 +1,127 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ import namespace="System" #>
+<#@ import namespace="System.Text" #>
+<#
+switch (WriterType)
+{
+    case RawTextWriterType.Utf8:
+    case RawTextWriterType.Encoded:
+        break;
+    default:
+        throw new ArgumentOutOfRangeException(
+            "WriterType", WriterType,
+            "Unknown value for WriterType.");
+}
+#>
+<#+
+    private const string newline = "\r\n";
+
+    public enum RawTextWriterType {
+        Unknown, Utf8, Encoded
+    }
+
+    public RawTextWriterType WriterType;
+    public string ClassName;
+    public string ClassNameIndent;
+    public string BaseClassName;
+    public string BufferName;
+    public string BufferType;
+    public string EncodeCharBody;
+    public string SetTextContentMarkBody;
+
+    public string SetTextContentMark(int indentAmount, bool value)
+    {
+        return SetTextContentMark(indentAmount, 2, value);
+    }
+
+    public string SetTextContentMark(int indentAmount, int linesPrefix, bool value)
+    {
+        string prefixed = LinesPrefix(linesPrefix, SetTextContentMarkBody);
+
+        return ReIndent(indentAmount, prefixed)
+            .Replace("_value_", BoolString(value));
+    }
+
+    public string EncodeChar(int indentAmount, bool entitizeInvalidChars)
+    {
+        return ReIndent(indentAmount, EncodeCharBody)
+            .Replace("_entitizeInvalidChars_", BoolString(entitizeInvalidChars));
+    }
+
+    public static string LinesPrefix(int amount, string code)
+    {
+        if (string.IsNullOrWhiteSpace(code))
+        {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder(code.Length);
+
+        for (int i = 0; i < amount; ++i)
+        {
+            sb.Append(newline);
+        }
+
+        sb.Append(code);
+
+        return sb.ToString();
+    }
+
+    public static string LinesPostfix(int amount, string code)
+    {
+        if (string.IsNullOrWhiteSpace(code))
+        {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder(code);
+
+        for (int i = 0; i < amount; ++i)
+        {
+            sb.Append(newline);
+        }
+
+        return sb.ToString();
+    }
+
+    private static string ReIndent(int indentAmount, string code)
+    {
+        if (string.IsNullOrWhiteSpace(code))
+        {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder(code.Length);
+        string[] lines = code.Split(new string[] { newline }, StringSplitOptions.None);
+        string indentation = new string(' ', indentAmount * 4);
+
+        for (int i = 0; i < lines.Length; ++i)
+        {
+            string line = lines[i];
+
+            // Do not make lines that have "trailing space."
+            if (string.IsNullOrWhiteSpace(line))
+            {
+                sb.Append(newline);
+                continue;
+            }
+
+            bool lastLine = i == lines.Length - 1;
+
+            sb.Append(indentation);
+            sb.Append(line);
+
+            if (!lastLine)
+            {
+                sb.Append(newline);
+            }
+        }
+
+        return sb.ToString();
+    }
+
+    private static string BoolString(bool value)
+    {
+        return value ? "true" : "false";
+    }
+#>
\ No newline at end of file
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude
new file mode 100644 (file)
index 0000000..a3bd4d0
--- /dev/null
@@ -0,0 +1,30 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #><#
+    WriterType = RawTextWriterType.Encoded;
+    ClassName = "XmlEncodedRawTextWriter";
+    ClassNameIndent = "XmlEncodedRawTextWriterIndent";
+    BufferName = "bufChars";
+    BufferType = "char";
+    EncodeCharBody = @"/* Surrogate character */
+if (XmlCharType.IsSurrogate(ch))
+{
+    pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+    pSrc += 2;
+}
+/* Invalid XML character */
+else  if (ch <= 0x7F || ch >= 0xFFFE)
+{
+    pDst = InvalidXmlChar(ch, pDst, _entitizeInvalidChars_);
+    pSrc++;
+}
+/* Other character between SurLowEnd and 0xFFFE */
+else
+{
+    *pDst = (char)ch;
+    pDst++;
+    pSrc++;
+}";
+    SetTextContentMarkBody = @"if (trackTextContent && inTextContent != _value_) { ChangeTextContentMark(_value_); }";
+#>
\ No newline at end of file
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterUtf8.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterUtf8.ttinclude
new file mode 100644 (file)
index 0000000..6e73767
--- /dev/null
@@ -0,0 +1,29 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #><#
+    WriterType = RawTextWriterType.Utf8;
+    ClassName = "XmlUtf8RawTextWriter";
+    ClassNameIndent = "XmlUtf8RawTextWriterIndent";
+    BufferName = "bufBytes";
+    BufferType = "byte";
+    EncodeCharBody = @"/* Surrogate character */
+if (XmlCharType.IsSurrogate(ch))
+{
+    pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+    pSrc += 2;
+}
+/* Invalid XML character */
+else if (ch <= 0x7F || ch >= 0xFFFE)
+{
+    pDst = InvalidXmlChar(ch, pDst, _entitizeInvalidChars_);
+    pSrc++;
+}
+/* Multibyte UTF8 character */
+else
+{
+    pDst = EncodeMultibyteUTF8(ch, pDst);
+    pSrc++;
+}";
+    SetTextContentMarkBody = "";
+#>
\ No newline at end of file
index 8ecaa0f..e5099f5 100644 (file)
@@ -1,31 +1,13 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify TextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _UTF8_TEXT_WRITER TextWriterGenerator.cxx > Utf8TextWriter.cs
-//   cl.exe /C /EP /D _ENCODED_TEXT_WRITER TextWriterGenerator.cxx > EncodedTextWriter.cs
-//
-// Because these two implementations of TextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-
-
-
-
-
-
-
-
-
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify TextRawTextWriterGenerator.ttinclude
 
 using System;
 using System.IO;
 using System.Text;
-//using System.Xml.Query;
 using System.Xml.Schema;
 using System.Diagnostics;
 using System.Globalization;
@@ -44,13 +26,11 @@ namespace System.Xml
         {
         }
 
-
         // Construct an instance of this class that serializes to a Stream interface.
         public TextEncodedRawTextWriter(Stream stream, XmlWriterSettings settings) : base(stream, settings)
         {
         }
 
-
         //
         // XmlRawWriter
         //
@@ -181,3 +161,4 @@ namespace System.Xml
         }
     }
 }
+
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.tt
new file mode 100644 (file)
index 0000000..587c15b
--- /dev/null
@@ -0,0 +1,10 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterEncoded.ttinclude" #>
+<#
+    ClassName = "TextEncodedRawTextWriter";
+    BaseClassName = "XmlEncodedRawTextWriter";
+#>
+<#@ include file="TextRawTextWriterGenerator.ttinclude" #>
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextRawTextWriterGenerator.cxx b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextRawTextWriterGenerator.cxx
deleted file mode 100644 (file)
index 4b93ed8..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify TextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _UTF8_TEXT_WRITER TextWriterGenerator.cxx > Utf8TextWriter.cs
-//   cl.exe /C /EP /D _ENCODED_TEXT_WRITER TextWriterGenerator.cxx > EncodedTextWriter.cs
-//
-// Because these two implementations of TextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-#ifdef _UTF8_TEXT_WRITER
-#define _CLASS_NAME TextUtf8RawTextWriter
-#define _BASE_CLASS_NAME XmlUtf8RawTextWriter
-#endif
-
-#ifdef _ENCODED_TEXT_WRITER
-#define _CLASS_NAME TextEncodedRawTextWriter
-#define _BASE_CLASS_NAME XmlEncodedRawTextWriter
-#endif
-
-using System;
-using System.IO;
-using System.Text;
-//using System.Xml.Query;
-using System.Xml.Schema;
-using System.Diagnostics;
-using System.Globalization;
-
-namespace System.Xml {
-    // Concrete implementation of XmlRawWriter interface that serializes text events as encoded
-    // text.  All other non-text events are ignored.  The general-purpose TextEncodedRawTextWriter uses the
-    // Encoder class to output to any encoding.  The TextUtf8RawTextWriter class combined the encoding
-    // operation with serialization in order to achieve better performance.
-    // </summary>
-    internal class _CLASS_NAME : _BASE_CLASS_NAME {
-
-#ifdef _ENCODED_TEXT_WRITER
-        // Construct an instance of this class that outputs text to the TextWriter interface.
-        public _CLASS_NAME( TextWriter writer, XmlWriterSettings settings ) : base ( writer, settings ) {
-        }
-#endif
-
-        // Construct an instance of this class that serializes to a Stream interface.
-        public _CLASS_NAME( Stream stream, XmlWriterSettings settings ) : base( stream, settings ) {
-        }
-
-
-//
-// XmlRawWriter
-//
-        // Ignore Xml declaration
-        internal override void WriteXmlDeclaration( XmlStandalone standalone ) {
-        }
-        internal override void WriteXmlDeclaration( string xmldecl ) {
-        }
-
-        // Ignore DTD
-        public override void WriteDocType( string name, string pubid, string sysid, string subset ) {
-        }
-
-        // Ignore Elements
-        public override void WriteStartElement( string prefix, string localName, string ns ) {
-        }
-
-        internal override void WriteEndElement( string prefix, string localName, string ns ) {
-        }
-
-        internal override void WriteFullEndElement( string prefix, string localName, string ns ) {
-        }
-
-        internal override void StartElementContent() {
-        }
-
-        // Ignore attributes
-        public override void WriteStartAttribute( string prefix, string localName, string ns ) {
-            base.inAttributeValue = true;
-        }
-
-        public override void WriteEndAttribute() {
-            base.inAttributeValue = false;
-        }
-
-        // Ignore namespace declarations
-        internal override void WriteNamespaceDeclaration( string prefix, string ns ) {
-        }
-
-        internal override bool SupportsNamespaceDeclarationInChunks {
-            get {
-                return false;
-            }
-        }
-
-        // Output content of CDATA sections as plain text without escaping
-        public override void WriteCData( string text ) {
-            base.WriteRaw( text );
-        }
-
-        // Ignore comments
-        public override void WriteComment( string text ) {
-        }
-
-        // Ignore processing instructions
-        public override void WriteProcessingInstruction( string name, string text ) {
-        }
-
-        // Ignore entities
-        public override void WriteEntityRef( string name ) {
-        }
-        public override void WriteCharEntity( char ch ) {
-        }
-        public override void WriteSurrogateCharEntity( char lowChar, char highChar ) {
-        }
-
-        // Output text content without any escaping; ignore attribute values
-        public override void WriteWhitespace( string ws ) {
-            if ( !base.inAttributeValue ) {
-                base.WriteRaw( ws  );
-            }
-        }
-
-        // Output text content without any escaping; ignore attribute values
-        public override void WriteString( string textBlock ) {
-            if ( !base.inAttributeValue ) {
-                base.WriteRaw( textBlock );
-            }
-        }
-
-        // Output text content without any escaping; ignore attribute values
-        public override void WriteChars( char[] buffer, int index, int count ) {
-            if ( !base.inAttributeValue ) {
-                base.WriteRaw( buffer, index, count );
-            }
-        }
-
-        // Output text content without any escaping; ignore attribute values
-        public override void WriteRaw( char[] buffer, int index, int count ) {
-            if ( !base.inAttributeValue ) {
-                base.WriteRaw( buffer, index, count );
-            }
-        }
-
-        // Output text content without any escaping; ignore attribute values
-        public override void WriteRaw( string data ) {
-            if ( !base.inAttributeValue ) {
-                base.WriteRaw( data );
-            }
-        }
-    }
-}
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextRawTextWriterGenerator.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextRawTextWriterGenerator.ttinclude
new file mode 100644 (file)
index 0000000..c5794e5
--- /dev/null
@@ -0,0 +1,167 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriter.ttinclude" #>// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify TextRawTextWriterGenerator.ttinclude
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml.Schema;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace System.Xml
+{
+    // Concrete implementation of XmlRawWriter interface that serializes text events as encoded
+    // text.  All other non-text events are ignored.  The general-purpose TextEncodedRawTextWriter uses the
+    // Encoder class to output to any encoding.  The TextUtf8RawTextWriter class combined the encoding
+    // operation with serialization in order to achieve better performance.
+    // </summary>
+    internal class <#= ClassName #> : <#= BaseClassName #>
+    {
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+        // Construct an instance of this class that outputs text to the TextWriter interface.
+        public <#= ClassName #>(TextWriter writer, XmlWriterSettings settings) : base(writer, settings)
+        {
+        }
+
+<# } #>
+        // Construct an instance of this class that serializes to a Stream interface.
+        public <#= ClassName #>(Stream stream, XmlWriterSettings settings) : base(stream, settings)
+        {
+        }
+
+        //
+        // XmlRawWriter
+        //
+        // Ignore Xml declaration
+        internal override void WriteXmlDeclaration(XmlStandalone standalone)
+        {
+        }
+        internal override void WriteXmlDeclaration(string xmldecl)
+        {
+        }
+
+        // Ignore DTD
+        public override void WriteDocType(string name, string pubid, string sysid, string subset)
+        {
+        }
+
+        // Ignore Elements
+        public override void WriteStartElement(string prefix, string localName, string ns)
+        {
+        }
+
+        internal override void WriteEndElement(string prefix, string localName, string ns)
+        {
+        }
+
+        internal override void WriteFullEndElement(string prefix, string localName, string ns)
+        {
+        }
+
+        internal override void StartElementContent()
+        {
+        }
+
+        // Ignore attributes
+        public override void WriteStartAttribute(string prefix, string localName, string ns)
+        {
+            base.inAttributeValue = true;
+        }
+
+        public override void WriteEndAttribute()
+        {
+            base.inAttributeValue = false;
+        }
+
+        // Ignore namespace declarations
+        internal override void WriteNamespaceDeclaration(string prefix, string ns)
+        {
+        }
+
+        internal override bool SupportsNamespaceDeclarationInChunks
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        // Output content of CDATA sections as plain text without escaping
+        public override void WriteCData(string text)
+        {
+            base.WriteRaw(text);
+        }
+
+        // Ignore comments
+        public override void WriteComment(string text)
+        {
+        }
+
+        // Ignore processing instructions
+        public override void WriteProcessingInstruction(string name, string text)
+        {
+        }
+
+        // Ignore entities
+        public override void WriteEntityRef(string name)
+        {
+        }
+        public override void WriteCharEntity(char ch)
+        {
+        }
+        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
+        {
+        }
+
+        // Output text content without any escaping; ignore attribute values
+        public override void WriteWhitespace(string ws)
+        {
+            if (!base.inAttributeValue)
+            {
+                base.WriteRaw(ws);
+            }
+        }
+
+        // Output text content without any escaping; ignore attribute values
+        public override void WriteString(string textBlock)
+        {
+            if (!base.inAttributeValue)
+            {
+                base.WriteRaw(textBlock);
+            }
+        }
+
+        // Output text content without any escaping; ignore attribute values
+        public override void WriteChars(char[] buffer, int index, int count)
+        {
+            if (!base.inAttributeValue)
+            {
+                base.WriteRaw(buffer, index, count);
+            }
+        }
+
+        // Output text content without any escaping; ignore attribute values
+        public override void WriteRaw(char[] buffer, int index, int count)
+        {
+            if (!base.inAttributeValue)
+            {
+                base.WriteRaw(buffer, index, count);
+            }
+        }
+
+        // Output text content without any escaping; ignore attribute values
+        public override void WriteRaw(string data)
+        {
+            if (!base.inAttributeValue)
+            {
+                base.WriteRaw(data);
+            }
+        }
+    }
+}
index 84e7049..bd3dc46 100644 (file)
@@ -1,31 +1,13 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify TextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _UTF8_TEXT_WRITER TextWriterGenerator.cxx > Utf8TextWriter.cs
-//   cl.exe /C /EP /D _ENCODED_TEXT_WRITER TextWriterGenerator.cxx > EncodedTextWriter.cs
-//
-// Because these two implementations of TextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-
-
-
-
-
-
-
-
-
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify TextRawTextWriterGenerator.ttinclude
 
 using System;
 using System.IO;
 using System.Text;
-//using System.Xml.Query;
 using System.Xml.Schema;
 using System.Diagnostics;
 using System.Globalization;
@@ -44,7 +26,6 @@ namespace System.Xml
         {
         }
 
-
         //
         // XmlRawWriter
         //
@@ -175,3 +156,4 @@ namespace System.Xml
         }
     }
 }
+
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.tt
new file mode 100644 (file)
index 0000000..2031f0a
--- /dev/null
@@ -0,0 +1,10 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterUtf8.ttinclude" #>
+<#
+    ClassName = "TextUtf8RawTextWriter";
+    BaseClassName = "XmlUtf8RawTextWriter";
+#>
+<#@ include file="TextRawTextWriterGenerator.ttinclude" #>
index d0b8a01..ee3b598 100644 (file)
@@ -1,18 +1,10 @@
+
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// Note: Following comment is fairly old - generator might not actually work
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify XmlTextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlUtf8RawTextWriter.cs
-//
-// Because these two implementations of XmlTextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-// Note: This file was generated without #define SILVERLIGHT
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify XmlRawTextWriterGenerator.ttinclude
 
 using System;
 using System.IO;
@@ -40,7 +32,7 @@ namespace System.Xml
         // output stream
         protected Stream stream;
 
-        // encoding of the stream or text writer 
+        // encoding of the stream or text writer
         protected Encoding encoding;
 
         // char type tables
@@ -48,7 +40,7 @@ namespace System.Xml
 
         // buffer positions
         protected int bufPos = 1;     // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
-                                      // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
+                                      // close an empty element or in CDATA section detection of double ]; bufChars[0] will always be 0
         protected int textPos = 1;    // text end position; don't indent first element, pi, or comment
         protected int contentPos;     // element content end position
         protected int cdataPos;       // cdata end position
@@ -74,7 +66,7 @@ namespace System.Xml
         protected bool inTextContent;
         private int _lastMarkPos;
         private int[] _textContentMarks;   // even indices contain text content start positions
-                                           // odd indices contain markup start positions 
+                                           // odd indices contain markup start positions
         private CharEntityEncoderFallback _charEntityFallback;
 
         // writer settings
@@ -158,8 +150,8 @@ namespace System.Xml
             {
                 bufLen = ASYNCBUFSIZE;
             }
-            bufChars = new char[bufLen + OVERFLOW];
 
+            bufChars = new char[bufLen + OVERFLOW];
             bufBytes = new byte[bufChars.Length];
             bufBytesUsed = 0;
 
@@ -174,7 +166,7 @@ namespace System.Xml
 
             // grab bom before possibly changing encoding settings
             ReadOnlySpan<byte> bom = encoding.Preamble;
-            
+
             // the encoding instance this creates can differ from the one passed in
             this.encoding = Encoding.GetEncoding(
                 settings.Encoding.CodePage,
@@ -209,11 +201,11 @@ namespace System.Xml
             {
                 XmlWriterSettings settings = new XmlWriterSettings();
 
-                settings.Encoding = this.encoding;
-                settings.OmitXmlDeclaration = this.omitXmlDeclaration;
-                settings.NewLineHandling = this.newLineHandling;
-                settings.NewLineChars = this.newLineChars;
-                settings.CloseOutput = this.closeOutput;
+                settings.Encoding = encoding;
+                settings.OmitXmlDeclaration = omitXmlDeclaration;
+                settings.NewLineHandling = newLineHandling;
+                settings.NewLineChars = newLineChars;
+                settings.CloseOutput = closeOutput;
                 settings.ConformanceLevel = ConformanceLevel.Auto;
                 settings.CheckCharacters = checkCharacters;
 
@@ -226,7 +218,7 @@ namespace System.Xml
             }
         }
 
-        // Write the xml declaration.  This must be the first call.  
+        // Write the xml declaration.  This must be the first call.
         internal override void WriteXmlDeclaration(XmlStandalone standalone)
         {
             // Output xml declaration only if user allows it and it was not already output
@@ -304,7 +296,7 @@ namespace System.Xml
                 bufChars[bufPos++] = (char)']';
             }
 
-            bufChars[this.bufPos++] = (char)'>';
+            bufChars[bufPos++] = (char)'>';
         }
 
         // Serialize the beginning of an element start tag: "<prefix:localName"
@@ -319,7 +311,7 @@ namespace System.Xml
             if (prefix != null && prefix.Length != 0)
             {
                 RawText(prefix);
-                bufChars[this.bufPos++] = (char)':';
+                bufChars[bufPos++] = (char)':';
             }
 
             RawText(localName);
@@ -420,6 +412,7 @@ namespace System.Xml
         public override void WriteEndAttribute()
         {
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
+
             bufChars[bufPos++] = (char)'"';
             inAttributeValue = false;
             attrEndPos = bufPos;
@@ -429,9 +422,9 @@ namespace System.Xml
         {
             Debug.Assert(prefix != null && namespaceName != null);
 
-            this.WriteStartNamespaceDeclaration(prefix);
-            this.WriteString(namespaceName);
-            this.WriteEndNamespaceDeclaration();
+            WriteStartNamespaceDeclaration(prefix);
+            WriteString(namespaceName);
+            WriteEndNamespaceDeclaration();
         }
 
         internal override bool SupportsNamespaceDeclarationInChunks
@@ -461,6 +454,7 @@ namespace System.Xml
             }
 
             inAttributeValue = true;
+
             if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); }
         }
 
@@ -603,6 +597,7 @@ namespace System.Xml
         public override unsafe void WriteWhitespace(string ws)
         {
             Debug.Assert(ws != null);
+
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
 
             fixed (char* pSrc = ws)
@@ -624,6 +619,7 @@ namespace System.Xml
         public override unsafe void WriteString(string text)
         {
             Debug.Assert(text != null);
+
             if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); }
 
             fixed (char* pSrc = text)
@@ -747,7 +743,6 @@ namespace System.Xml
                         }
                     }
                 }
-
                 else if (writer != null)
                 {
                     try
@@ -777,7 +772,6 @@ namespace System.Xml
         {
             FlushBuffer();
             FlushEncoder();
-
             if (stream != null)
             {
                 stream.Flush();
@@ -847,7 +841,7 @@ namespace System.Xml
                 contentPos = 0;    // Needs to be zero, since overwriting '>' character is no longer possible
                 cdataPos = 0;      // Needs to be zero, since overwriting ']]>' characters is no longer possible
                 bufPos = 1;        // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
-                                   // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
+                                   // close an empty element or in CDATA section detection of double ]; bufChars[0] will always be 0
             }
         }
 
@@ -898,12 +892,11 @@ namespace System.Xml
 
         // Serialize text that is part of an attribute value.  The '&', '<', '>', and '"' characters
         // are entitized.
-
         protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd)
         {
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -993,7 +986,25 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1004,12 +1015,11 @@ namespace System.Xml
 
         // Serialize text that is part of element content.  The '&', '<', and '>' characters
         // are entitized.
-
         protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd)
         {
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -1096,7 +1106,25 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1121,16 +1149,16 @@ namespace System.Xml
         {
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
                 char* pSrc = pSrcBegin;
 
                 int ch = 0;
                 for (;;)
                 {
                     char* pDstEnd = pDst + (pSrcEnd - pSrc);
-                    if (pDstEnd > pDstBegin + this.bufLen)
+                    if (pDstEnd > pDstBegin + bufLen)
                     {
-                        pDstEnd = pDstBegin + this.bufLen;
+                        pDstEnd = pDstBegin + bufLen;
                     }
 
                     while (pDst < pDstEnd && ((ch = *pSrc) < XmlCharType.SurHighStart))
@@ -1156,7 +1184,25 @@ namespace System.Xml
                         continue;
                     }
 
-                    if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                    /* Surrogate character */
+                    if (XmlCharType.IsSurrogate(ch))
+                    {
+                        pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                        pSrc += 2;
+                    }
+                    /* Invalid XML character */
+                    else  if (ch <= 0x7F || ch >= 0xFFFE)
+                    {
+                        pDst = InvalidXmlChar(ch, pDst, false);
+                        pSrc++;
+                    }
+                    /* Other character between SurLowEnd and 0xFFFE */
+                    else
+                    {
+                        *pDst = (char)ch;
+                        pDst++;
+                        pSrc++;
+                    }
                 }
 
                 bufPos = (int)(pDst - pDstBegin);
@@ -1242,7 +1288,25 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1326,7 +1390,7 @@ namespace System.Xml
                             pDst++;
                             if (ch == stopChar)
                             {
-                                // Processing instruction: insert space between adjacent '?' and '>' 
+                                // Processing instruction: insert space between adjacent '?' and '>'
                                 if (pSrc + 1 < pSrcEnd && *(pSrc + 1) == '>')
                                 {
                                     *pDst = (char)' ';
@@ -1373,7 +1437,25 @@ namespace System.Xml
                             pDst++;
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1443,7 +1525,7 @@ namespace System.Xml
                     {
                         case '>':
                             if (hadDoubleBracket && pDst[-1] == (char)']')
-                            {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
+                            {   // pDst[-1] will always correct - there is a padding character at bufChars[0]
                                 // The characters "]]>" were found within the CData text
                                 pDst = RawEndCData(pDst);
                                 pDst = RawStartCData(pDst);
@@ -1453,7 +1535,7 @@ namespace System.Xml
                             break;
                         case ']':
                             if (pDst[-1] == (char)']')
-                            {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
+                            {   // pDst[-1] will always correct - there is a padding character at bufChars[0]
                                 hadDoubleBracket = true;
                             }
                             else
@@ -1500,7 +1582,25 @@ namespace System.Xml
                             pDst++;
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1509,6 +1609,7 @@ namespace System.Xml
             }
         }
 
+
         private static unsafe char* EncodeSurrogate(char* pSrc, char* pSrcEnd, char* pDst)
         {
             Debug.Assert(XmlCharType.IsSurrogate(*pSrc));
@@ -1553,9 +1654,8 @@ namespace System.Xml
                 }
                 else
                 {
-                    *pDst = (char)ch;
-                    pDst++;
-
+                        *pDst = (char)ch;
+                        pDst++;
                     return pDst;
                 }
             }
@@ -1564,9 +1664,28 @@ namespace System.Xml
         internal unsafe void EncodeChar(ref char* pSrc, char* pSrcEnd, ref char* pDst)
         {
             int ch = *pSrc;
-            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+            /* Surrogate character */
+            if (XmlCharType.IsSurrogate(ch))
+            {
+                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                pSrc += 2;
+            }
+            /* Invalid XML character */
+            else  if (ch <= 0x7F || ch >= 0xFFFE)
+            {
+                pDst = InvalidXmlChar(ch, pDst, false);
+                pSrc++;
+            }
+            /* Other character between SurLowEnd and 0xFFFE */
+            else
+            {
+                *pDst = (char)ch;
+                pDst++;
+                pSrc++;
+            }
         }
 
+
         protected void ChangeTextContentMark(bool value)
         {
             Debug.Assert(inTextContent != value);
@@ -1576,7 +1695,7 @@ namespace System.Xml
             {
                 GrowTextContentMarks();
             }
-            _textContentMarks[++_lastMarkPos] = this.bufPos;
+            _textContentMarks[++_lastMarkPos] = bufPos;
         }
 
         private void GrowTextContentMarks()
@@ -1586,9 +1705,7 @@ namespace System.Xml
             Array.Copy(_textContentMarks, newTextContentMarks, _textContentMarks.Length);
             _textContentMarks = newTextContentMarks;
         }
-
         // Write NewLineChars to the specified buffer position and return an updated position.
-
         protected unsafe char* WriteNewLine(char* pDst)
         {
             fixed (char* pDstBegin = bufChars)
@@ -1806,7 +1923,6 @@ namespace System.Xml
         //
         // Constructors
         //
-
         public XmlEncodedRawTextWriterIndent(TextWriter writer, XmlWriterSettings settings) : base(writer, settings)
         {
             Init(settings);
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.tt
new file mode 100644 (file)
index 0000000..6ad8f30
--- /dev/null
@@ -0,0 +1,6 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterEncoded.ttinclude" #>
+<#@ include file="XmlRawTextWriterGenerator.ttinclude" #>
index b89394e..8d47951 100644 (file)
@@ -2,6 +2,9 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify XmlRawTextWriterGeneratorAsync.ttinclude
+
 using System;
 using System.IO;
 using System.Xml;
@@ -27,7 +30,7 @@ namespace System.Xml
             }
         }
 
-        // Write the xml declaration.  This must be the first call.  
+        // Write the xml declaration.  This must be the first call.
         internal override async Task WriteXmlDeclarationAsync(XmlStandalone standalone)
         {
             CheckAsyncCall();
@@ -35,7 +38,6 @@ namespace System.Xml
             if (!omitXmlDeclaration && !autoXmlDeclaration)
             {
                 if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
-
                 await RawTextAsync("<?xml version=\"").ConfigureAwait(false);
 
                 // Version
@@ -110,7 +112,7 @@ namespace System.Xml
                 bufChars[bufPos++] = (char)']';
             }
 
-            bufChars[this.bufPos++] = (char)'>';
+            bufChars[bufPos++] = (char)'>';
         }
 
         // Serialize the beginning of an element start tag: "<prefix:localName"
@@ -121,6 +123,7 @@ namespace System.Xml
             Debug.Assert(prefix != null);
 
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
+
             Task task;
             bufChars[bufPos++] = (char)'<';
             if (prefix != null && prefix.Length != 0)
@@ -233,7 +236,9 @@ namespace System.Xml
         protected internal override Task WriteEndAttributeAsync()
         {
             CheckAsyncCall();
+
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
+
             bufChars[bufPos++] = (char)'"';
             inAttributeValue = false;
             attrEndPos = bufPos;
@@ -246,9 +251,9 @@ namespace System.Xml
             CheckAsyncCall();
             Debug.Assert(prefix != null && namespaceName != null);
 
-            await this.WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
-            await this.WriteStringAsync(namespaceName).ConfigureAwait(false);
-            await this.WriteEndNamespaceDeclarationAsync().ConfigureAwait(false);
+            await WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
+            await WriteStringAsync(namespaceName).ConfigureAwait(false);
+            await WriteEndNamespaceDeclarationAsync().ConfigureAwait(false);
         }
 
         internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
@@ -271,13 +276,16 @@ namespace System.Xml
             }
 
             inAttributeValue = true;
+
             if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); }
         }
 
         internal override Task WriteEndNamespaceDeclarationAsync()
         {
             CheckAsyncCall();
+
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
+
             inAttributeValue = false;
 
             bufChars[bufPos++] = (char)'"';
@@ -422,6 +430,7 @@ namespace System.Xml
         {
             CheckAsyncCall();
             Debug.Assert(ws != null);
+
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
 
             if (inAttributeValue)
@@ -440,6 +449,7 @@ namespace System.Xml
         {
             CheckAsyncCall();
             Debug.Assert(text != null);
+
             if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); }
 
             if (inAttributeValue)
@@ -456,7 +466,9 @@ namespace System.Xml
         public override async Task WriteSurrogateCharEntityAsync(char lowChar, char highChar)
         {
             CheckAsyncCall();
+
             if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); }
+
             int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar);
 
             bufChars[bufPos++] = (char)'&';
@@ -590,6 +602,7 @@ namespace System.Xml
                 // Move last buffer character to the beginning of the buffer (so that previous character can always be determined)
                 bufChars[0] = bufChars[bufPos - 1];
 
+
                 // Reset buffer position
                 textPos = (textPos == bufPos) ? 1 : 0;
                 attrEndPos = (attrEndPos == bufPos) ? 1 : 0;
@@ -599,7 +612,6 @@ namespace System.Xml
                                    // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
             }
         }
-
         private async Task EncodeCharsAsync(int startOffset, int endOffset, bool writeAllToStream)
         {
             // Write encoded text to stream
@@ -655,7 +667,7 @@ namespace System.Xml
 
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -743,7 +755,25 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -816,7 +846,6 @@ namespace System.Xml
             return Task.CompletedTask;
         }
 
-
         private async Task _WriteAttributeTextBlockAsync(string text, int curIndex, int leftCount)
         {
             int writeLen;
@@ -842,7 +871,7 @@ namespace System.Xml
 
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -930,7 +959,25 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1063,16 +1110,16 @@ namespace System.Xml
 
             fixed (char* pDstBegin = bufChars)
             {
-                char* pDst = pDstBegin + this.bufPos;
+                char* pDst = pDstBegin + bufPos;
                 char* pSrc = pSrcBegin;
 
                 int ch = 0;
                 for (;;)
                 {
                     char* pDstEnd = pDst + (pSrcEnd - pSrc);
-                    if (pDstEnd > pDstBegin + this.bufLen)
+                    if (pDstEnd > pDstBegin + bufLen)
                     {
-                        pDstEnd = pDstBegin + this.bufLen;
+                        pDstEnd = pDstBegin + bufLen;
                     }
 
                     while (pDst < pDstEnd && ((ch = *pSrc) < XmlCharType.SurHighStart))
@@ -1096,7 +1143,25 @@ namespace System.Xml
                         return (int)(pSrc - pRaw);
                     }
 
-                    if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                    /* Surrogate character */
+                    if (XmlCharType.IsSurrogate(ch))
+                    {
+                        pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                        pSrc += 2;
+                    }
+                    /* Invalid XML character */
+                    else  if (ch <= 0x7F || ch >= 0xFFFE)
+                    {
+                        pDst = InvalidXmlChar(ch, pDst, false);
+                        pSrc++;
+                    }
+                    /* Other character between SurLowEnd and 0xFFFE */
+                    else
+                    {
+                        *pDst = (char)ch;
+                        pDst++;
+                        pSrc++;
+                    }
                 }
 
                 bufPos = (int)(pDst - pDstBegin);
@@ -1152,7 +1217,7 @@ namespace System.Xml
                 if (writeLen >= 0)
                 {
                     // If we were only able to write out some of the second string,
-                    // write out the remainder and then the other strings, 
+                    // write out the remainder and then the other strings,
                     return _RawTextAsync(text2, writeLen, text2.Length - writeLen, text3, text4);
                 }
             }
@@ -1297,7 +1362,25 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else  if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Other character between SurLowEnd and 0xFFFE */
+                            else
+                            {
+                                *pDst = (char)ch;
+                                pDst++;
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1459,7 +1542,7 @@ namespace System.Xml
                                 pDst++;
                                 if (ch == stopChar)
                                 {
-                                    // Processing instruction: insert space between adjacent '?' and '>' 
+                                    // Processing instruction: insert space between adjacent '?' and '>'
                                     if (pSrc + 1 < pSrcEnd && *(pSrc + 1) == '>')
                                     {
                                         *pDst = (char)' ';
@@ -1510,7 +1593,25 @@ namespace System.Xml
                                 pDst++;
                                 break;
                             default:
-                                if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                                /* Surrogate character */
+                                if (XmlCharType.IsSurrogate(ch))
+                                {
+                                    pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                    pSrc += 2;
+                                }
+                                /* Invalid XML character */
+                                else  if (ch <= 0x7F || ch >= 0xFFFE)
+                                {
+                                    pDst = InvalidXmlChar(ch, pDst, false);
+                                    pSrc++;
+                                }
+                                /* Other character between SurLowEnd and 0xFFFE */
+                                else
+                                {
+                                    *pDst = (char)ch;
+                                    pDst++;
+                                    pSrc++;
+                                }
                                 continue;
                         }
                         pSrc++;
@@ -1676,7 +1777,25 @@ namespace System.Xml
                                 pDst++;
                                 break;
                             default:
-                                if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { *pDst = (char)ch; pDst++; pSrc++; };
+                                /* Surrogate character */
+                                if (XmlCharType.IsSurrogate(ch))
+                                {
+                                    pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                    pSrc += 2;
+                                }
+                                /* Invalid XML character */
+                                else  if (ch <= 0x7F || ch >= 0xFFFE)
+                                {
+                                    pDst = InvalidXmlChar(ch, pDst, false);
+                                    pSrc++;
+                                }
+                                /* Other character between SurLowEnd and 0xFFFE */
+                                else
+                                {
+                                    *pDst = (char)ch;
+                                    pDst++;
+                                    pSrc++;
+                                }
                                 continue;
                         }
                         pSrc++;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.tt
new file mode 100644 (file)
index 0000000..62037e3
--- /dev/null
@@ -0,0 +1,6 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterEncoded.ttinclude" #>
+<#@ include file="XmlRawTextWriterGeneratorAsync.ttinclude" #>
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.cxx b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.cxx
deleted file mode 100644 (file)
index 57b03d3..0000000
+++ /dev/null
@@ -1,1936 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify XmlTextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _XML_UTF8_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlUtf8RawTextWriter.cs
-//   cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlEncodedRawTextWriter.cs
-//
-// Because these two implementations of XmlTextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-// Note: This file was generated without #define SILVERLIGHT
-
-#ifdef _XML_UTF8_TEXT_WRITER
-#define _CLASS_NAME XmlUtf8RawTextWriter
-#define _CLASS_NAME_INDENT XmlUtf8RawTextWriterIndent
-#define _BUFFER bufBytes
-#define _BUFFER_TYPE byte
-#define _ENCODE_CHAR(entitizeInvalidChars) \
-            /* Surrogate character */   \
-            if ( XmlCharType.IsSurrogate( ch ) ) {        \
-                pDst = EncodeSurrogate( pSrc, pSrcEnd, pDst );     \
-                pSrc += 2;      \
-            } \
-            /* Invalid XML character */ \
-            else if ( ch <= 0x7F || ch >= 0xFFFE ) {  \
-                pDst = InvalidXmlChar( ch, pDst, entitizeInvalidChars );  \
-                pSrc++; \
-            }   \
-            /* Multibyte UTF8 character */ \
-            else { \
-                pDst = EncodeMultibyteUTF8( ch, pDst ); \
-                pSrc++; \
-            }   
-
-#define _SET_TEXT_CONTENT_MARK(value) 
-#endif
-
-#ifdef _XML_ENCODED_TEXT_WRITER
-#define _CLASS_NAME XmlEncodedRawTextWriter
-#define _CLASS_NAME_INDENT XmlEncodedRawTextWriterIndent
-#define _BUFFER bufChars
-#define _BUFFER_TYPE char
-#define _ENCODE_CHAR(entitizeInvalidChars)  \
-            /* Surrogate character */   \
-            if ( XmlCharType.IsSurrogate( ch ) ) {        \
-                pDst = EncodeSurrogate( pSrc, pSrcEnd, pDst ); \
-                pSrc += 2;  \
-            }   \
-            /* Invalid XML character */ \
-            else  if ( ch <= 0x7F || ch >= 0xFFFE ) {  \
-                pDst = InvalidXmlChar( ch, pDst, entitizeInvalidChars );  \
-                pSrc++; \
-            }   \
-            /* Other character between SurLowEnd and 0xFFFE */ \
-            else {  \
-                *pDst = (char)ch;  \
-                pDst++; \
-                pSrc++; \
-            }   \
-
-#define _SET_TEXT_CONTENT_MARK(value) \
-    if ( trackTextContent && inTextContent != value ) { \
-        ChangeTextContentMark( value );  \
-    }
-
-#endif
-
-#define XMLCHARTYPE_TEST(ch, flag)              ( ( xmlCharType.charProperties[ch] & XmlCharType.##flag ) != 0 )
-#define XMLCHARTYPE_ISATTRIBUTEVALUECHAR(ch)    XMLCHARTYPE_TEST(ch, fAttrValue)
-#define XMLCHARTYPE_ISTEXT(ch)                  XMLCHARTYPE_TEST(ch, fText)
-
-
-using System;
-using System.IO;
-using System.Xml;
-using System.Text;
-using System.Diagnostics;
-using System.Globalization;
-
-namespace System.Xml {
-
-    // Concrete implementation of XmlWriter abstract class that serializes events as encoded XML
-    // text.  The general-purpose XmlEncodedTextWriter uses the Encoder class to output to any
-    // encoding.  The XmlUtf8TextWriter class combined the encoding operation with serialization
-    // in order to achieve better performance.
-    internal class _CLASS_NAME : XmlRawWriter {
-//
-// Fields
-//
-        // main buffer
-        protected byte[] bufBytes;
-
-        // output stream
-        protected Stream    stream;
-
-        // encoding of the stream or text writer 
-        protected Encoding encoding;
-
-        // char type tables
-        protected XmlCharType xmlCharType = XmlCharType.Instance;
-
-        // buffer positions
-        protected int   bufPos = 1;     // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
-                                        // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
-        protected int   textPos = 1;    // text end position; don't indent first element, pi, or comment
-        protected int   contentPos;     // element content end position
-        protected int   cdataPos;       // cdata end position
-        protected int   attrEndPos;     // end of the last attribute
-        protected int   bufLen = BUFSIZE;
-
-        // flags
-        protected bool  writeToNull;
-        protected bool  hadDoubleBracket;
-        protected bool  inAttributeValue;
-
-#ifdef _XML_ENCODED_TEXT_WRITER
-        protected int    bufBytesUsed;
-        protected char[] bufChars;
-
-        // encoder for encoding chars in specified encoding when writing to stream
-        protected Encoder       encoder;
-
-        // output text writer
-        protected TextWriter    writer;
-
-        // escaping of characters invalid in the output encoding
-        protected bool  trackTextContent;
-        protected bool  inTextContent;
-        private int     lastMarkPos;
-        private int[]   textContentMarks;   // even indices contain text content start positions
-                                            // odd indices contain markup start positions 
-        private CharEntityEncoderFallback charEntityFallback;
-
-#endif
-
-        // writer settings
-        protected NewLineHandling   newLineHandling;
-        protected bool              closeOutput;
-        protected bool              omitXmlDeclaration;
-        protected string            newLineChars;
-        protected bool              checkCharacters;
-        protected XmlStandalone     standalone;
-        protected XmlOutputMethod   outputMethod;
-        protected bool              autoXmlDeclaration;
-        protected bool              mergeCDataSections;
-
-//
-// Constants
-//
-        private const int BUFSIZE = 2048 * 3;       // Should be greater than default FileStream size (4096), otherwise the FileStream will try to cache the data
-        private const int OVERFLOW = 32;            // Allow overflow in order to reduce checks when writing out constant size markup
-        private const int INIT_MARKS_COUNT = 64;
-
-//
-// Constructors
-//
-        // Construct and initialize an instance of this class.
-        protected _CLASS_NAME( XmlWriterSettings settings ) {
-            // copy settings
-            newLineHandling = settings.NewLineHandling;
-            omitXmlDeclaration = settings.OmitXmlDeclaration;
-            newLineChars = settings.NewLineChars;
-            checkCharacters = settings.CheckCharacters;
-            closeOutput = settings.CloseOutput;
-
-            standalone = settings.Standalone;
-            outputMethod = settings.OutputMethod;
-            mergeCDataSections = settings.MergeCDataSections;
-
-            if ( checkCharacters && newLineHandling == NewLineHandling.Replace ) {
-                ValidateContentChars( newLineChars, "NewLineChars", false );
-            }
-        }
-
-#ifdef _XML_ENCODED_TEXT_WRITER
-        // Construct an instance of this class that outputs text to the TextWriter interface.
-        public _CLASS_NAME( TextWriter writer, XmlWriterSettings settings ) : this( settings ) {
-            Debug.Assert( writer != null && settings != null );
-
-            this.writer = writer;
-            this.encoding = writer.Encoding;
-            // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup
-            this.bufChars = new _BUFFER_TYPE[BUFSIZE + OVERFLOW];
-
-            // Write the xml declaration
-            if (settings.AutoXmlDeclaration ) {
-                WriteXmlDeclaration( standalone );
-                autoXmlDeclaration = true;
-            }
-        }
-#endif
-
-        // Construct an instance of this class that serializes to a Stream interface.
-        public _CLASS_NAME( Stream stream, XmlWriterSettings settings ) : this( settings ) {
-            Debug.Assert( stream != null && settings != null );
-
-            this.stream = stream;
-            this.encoding = settings.Encoding;
-
-#ifdef _XML_UTF8_TEXT_WRITER
-            // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup
-            bufBytes = new _BUFFER_TYPE[ BUFSIZE + OVERFLOW ];
-
-            // Output UTF-8 byte order mark if Encoding object wants it
-            if ( !stream.CanSeek || stream.Position == 0 ) {
-                ReadOnlySpan<byte> bom = encoding.Preamble;
-                if ( bom.Length != 0 ) {
-                    bom.CopyTo(new Span<byte>(bufBytes).Slice(1));
-                    bufPos += bom.Length;
-                    textPos += bom.Length;
-                }
-            }
-#else
-            // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup
-            bufChars = new _BUFFER_TYPE[ BUFSIZE + OVERFLOW ];
-            bufBytes = new byte[ bufChars.Length ];
-            bufBytesUsed = 0;
-
-            // Init escaping of characters not fitting into the target encoding
-            trackTextContent = true;
-            inTextContent = false;
-            lastMarkPos = 0;
-            textContentMarks = new int[INIT_MARKS_COUNT];
-            textContentMarks[0] = 1;
-
-            charEntityFallback = new CharEntityEncoderFallback();
-            this.encoding = (Encoding)settings.Encoding.Clone();
-            encoding.EncoderFallback = charEntityFallback;
-
-            encoder = encoding.GetEncoder();
-
-            if ( !stream.CanSeek || stream.Position == 0 ) {
-                ReadOnlySpan<byte> bom = encoding.Preamble;
-                if ( bom.Length != 0 ) {
-                    this.stream.Write( bom );
-                }
-            }
-#endif
-
-            // Write the xml declaration
-            if ( settings.AutoXmlDeclaration ) {
-                WriteXmlDeclaration( standalone );
-                autoXmlDeclaration = true;
-            }
-        }
-
-//
-// XmlWriter implementation
-//
-        // Returns settings the writer currently applies.
-        public override XmlWriterSettings Settings {
-            get {
-                XmlWriterSettings settings = new XmlWriterSettings();
-
-                settings.Encoding = this.encoding;
-                settings.OmitXmlDeclaration = this.omitXmlDeclaration;
-                settings.NewLineHandling = this.newLineHandling;
-                settings.NewLineChars = this.newLineChars;
-                settings.CloseOutput = this.closeOutput;
-                settings.ConformanceLevel = ConformanceLevel.Auto;
-                settings.CheckCharacters = checkCharacters;
-
-                settings.AutoXmlDeclaration = autoXmlDeclaration;
-                settings.Standalone = standalone;
-                settings.OutputMethod = outputMethod;
-                settings.ReadOnly = true;
-                return settings;
-
-            }
-        }
-
-        // Write the xml declaration.  This must be the first call.  
-        internal override void WriteXmlDeclaration( XmlStandalone standalone ) {
-            // Output xml declaration only if user allows it and it was not already output
-            if ( !omitXmlDeclaration && !autoXmlDeclaration ) {
-
-                _SET_TEXT_CONTENT_MARK(false)
-
-                RawText( "<?xml version=\"" );
-
-                // Version
-                RawText( "1.0" );
-
-                // Encoding
-                if ( encoding != null ) {
-                    RawText( "\" encoding=\"" );
-                    RawText( encoding.WebName );
-                }
-
-                // Standalone
-                if ( standalone != XmlStandalone.Omit ) {
-                    RawText( "\" standalone=\"" );
-                    RawText( standalone == XmlStandalone.Yes ? "yes" : "no" );
-                }
-
-                RawText( "\"?>" );
-            }
-        }
-
-        internal override void WriteXmlDeclaration( string xmldecl ) {
-            // Output xml declaration only if user allows it and it was not already output
-            if ( !omitXmlDeclaration && !autoXmlDeclaration ) {
-                WriteProcessingInstruction( "xml", xmldecl );
-            }
-        }
-
-        // Serialize the document type declaration.
-        public override void WriteDocType( string name, string pubid, string sysid, string subset ) {
-            Debug.Assert( name != null && name.Length > 0 );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            RawText( "<!DOCTYPE ");
-            RawText(name);
-            if ( pubid != null ) {
-                RawText( " PUBLIC \"" );
-                RawText( pubid );
-                RawText( "\" \"");
-                if ( sysid != null ) {
-                    RawText( sysid );
-                }
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            }
-            else if ( sysid != null ) {
-                RawText( " SYSTEM \"" );
-                RawText( sysid );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            }
-            else {
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ' ';
-            }
-
-            if ( subset != null ) {
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '[';
-                RawText( subset );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ']';
-            }
-
-            _BUFFER[this.bufPos++] = (_BUFFER_TYPE) '>';
-        }
-
-        // Serialize the beginning of an element start tag: "<prefix:localName"
-        public override void WriteStartElement( string prefix, string localName, string ns) {
-            Debug.Assert( localName != null && localName.Length > 0 );
-            Debug.Assert( prefix != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-            if ( prefix != null && prefix.Length != 0 ) {
-                RawText( prefix );
-                _BUFFER[this.bufPos++] = (_BUFFER_TYPE) ':';
-            }
-
-            RawText( localName );
-
-            attrEndPos = bufPos;
-        }
-
-        // Serialize the end of an element start tag in preparation for content serialization: ">"
-        internal override void StartElementContent() {
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-
-            // StartElementContent is always called; therefore, in order to allow shortcut syntax, we save the
-            // position of the '>' character.  If WriteEndElement is called and no other characters have been
-            // output, then the '>' character can be overwritten with the shortcut syntax " />".
-            contentPos = bufPos;
-        }
-
-        // Serialize an element end tag: "</prefix:localName>", if content was output.  Otherwise, serialize
-        // the shortcut syntax: " />".
-        internal override void WriteEndElement( string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length > 0 );
-            Debug.Assert( prefix != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            if ( contentPos != bufPos ) {
-                // Content has been output, so can't use shortcut syntax
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '/';
-
-                if ( prefix != null && prefix.Length != 0) {
-                    RawText( prefix );
-                    _BUFFER[bufPos++] = (_BUFFER_TYPE) ':';
-                }
-                RawText( localName );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-            }
-            else {
-                // Use shortcut syntax; overwrite the already output '>' character
-                bufPos--;
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ' ';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '/';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-            }
-        }
-
-        // Serialize a full element end tag: "</prefix:localName>"
-        internal override void WriteFullEndElement( string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length > 0 );
-            Debug.Assert( prefix != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '/';
-
-            if ( prefix != null && prefix.Length != 0) {
-                RawText( prefix );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ':';
-            }
-            RawText( localName );
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-        }
-
-        // Serialize an attribute tag using double quotes around the attribute value: 'prefix:localName="'
-        public override void WriteStartAttribute( string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length  > 0 );
-            Debug.Assert( prefix != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            if ( attrEndPos == bufPos ) {
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ' ';
-            }
-
-            if ( prefix != null && prefix.Length > 0 ) {
-                RawText( prefix );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ':';
-            }
-            RawText( localName );
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '=';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-
-            inAttributeValue = true;
-        }
-
-        // Serialize the end of an attribute value using double quotes: '"'
-        public override void WriteEndAttribute() {
-            _SET_TEXT_CONTENT_MARK(false)
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '"';
-            inAttributeValue = false;
-            attrEndPos = bufPos;
-        }
-
-        internal override void WriteNamespaceDeclaration( string prefix, string namespaceName ) {
-            Debug.Assert( prefix != null && namespaceName != null );
-
-            this.WriteStartNamespaceDeclaration( prefix );
-            this.WriteString( namespaceName );
-            this.WriteEndNamespaceDeclaration();
-        }
-
-        internal override bool SupportsNamespaceDeclarationInChunks {
-            get {
-                return true;
-            }
-        }
-
-        internal override void WriteStartNamespaceDeclaration(string prefix) {
-            Debug.Assert( prefix != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            // VSTFDEVDIV bug #583965: Inconsistency between Silverlight 2 and Dev10 in the way a single xmlns attribute is serialized 
-            // Resolved as: Won't fix (breaking change)
-            if ( prefix.Length == 0 ) {
-                RawText( " xmlns=\"" );
-            }
-            else {
-                RawText( " xmlns:" );
-                RawText( prefix );
-                _BUFFER[bufPos++] = (_BUFFER_TYPE)'=';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE)'"';
-            }
-
-            inAttributeValue = true;
-            _SET_TEXT_CONTENT_MARK(true)
-        }
-
-        internal override void WriteEndNamespaceDeclaration() {
-            _SET_TEXT_CONTENT_MARK(false)
-            inAttributeValue = false;
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'"';
-            attrEndPos = bufPos;
-        }
-
-        // Serialize a CData section.  If the "]]>" pattern is found within
-        // the text, replace it with "]]><![CDATA[>".
-        public override void WriteCData( string text ) {
-            Debug.Assert( text != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            if ( mergeCDataSections && bufPos == cdataPos ) {
-                // Merge adjacent cdata sections - overwrite the "]]>" characters
-                Debug.Assert( bufPos >= 4 );
-                bufPos -= 3;
-            }
-            else {
-                // Start a new cdata section
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '!';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '[';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) 'C';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) 'D';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) 'A';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) 'T';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) 'A';
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) '[';
-            }
-
-            WriteCDataSection( text );
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) ']';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) ']';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-
-            textPos = bufPos;
-            cdataPos = bufPos;
-        }
-
-        // Serialize a comment.
-        public override void WriteComment( string text ) {
-            Debug.Assert( text != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '!';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '-';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '-';
-
-            WriteCommentOrPi( text, '-' );
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '-';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '-';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-        }
-
-        // Serialize a processing instruction.
-        public override void WriteProcessingInstruction( string name, string text ) {
-            Debug.Assert( name != null && name.Length > 0 );
-            Debug.Assert( text != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '<';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '?';
-            RawText( name );
-
-            if ( text.Length > 0 ) {
-                _BUFFER[bufPos++] = (_BUFFER_TYPE) ' ';
-                WriteCommentOrPi( text, '?' );
-            }
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '?';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '>';
-        }
-
-        // Serialize an entity reference.
-        public override void WriteEntityRef( string name ) {
-            Debug.Assert( name != null && name.Length > 0 );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) '&';
-            RawText( name );
-            _BUFFER[bufPos++] = (_BUFFER_TYPE) ';';
-
-            if ( bufPos > bufLen ) {
-                FlushBuffer();
-            }
-
-            textPos = bufPos;
-        }
-
-        // Serialize a character entity reference.
-        public override void WriteCharEntity( char ch ) {
-            string strVal = ((int)ch).ToString( "X", NumberFormatInfo.InvariantInfo );
-
-            if ( checkCharacters && !xmlCharType.IsCharData( ch ) ) {
-                // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char
-                throw XmlConvert.CreateInvalidCharException( ch, '\0' );
-            }
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'&';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'#';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'x';
-            RawText( strVal );
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)';';
-
-            if ( bufPos > bufLen ) {
-                FlushBuffer();
-            }
-
-            textPos = bufPos;
-        }
-
-        // Serialize a whitespace node.
-        public override unsafe void WriteWhitespace( string ws ) {
-            Debug.Assert( ws != null );
-            _SET_TEXT_CONTENT_MARK(false)
-
-            fixed ( char * pSrc = ws ) {
-                char * pSrcEnd = pSrc + ws.Length;
-                if ( inAttributeValue) {
-                    WriteAttributeTextBlock( pSrc, pSrcEnd );
-                }
-                else {
-                    WriteElementTextBlock( pSrc, pSrcEnd );
-                }
-            }
-        }
-
-        // Serialize either attribute or element text using XML rules.
-        public override unsafe void WriteString( string text ) {
-            Debug.Assert( text != null );
-            _SET_TEXT_CONTENT_MARK(true)
-
-            fixed ( char * pSrc = text ) {
-                char * pSrcEnd = pSrc + text.Length;
-                if ( inAttributeValue) {
-                    WriteAttributeTextBlock( pSrc, pSrcEnd );
-                }
-                else {
-                    WriteElementTextBlock( pSrc, pSrcEnd );
-                }
-            }
-        }
-
-        // Serialize surrogate character entity.
-        public override void WriteSurrogateCharEntity( char lowChar, char highChar ) {
-            _SET_TEXT_CONTENT_MARK(false)
-            int surrogateChar = XmlCharType.CombineSurrogateChar( lowChar, highChar );
-
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'&';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'#';
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)'x';
-            RawText( surrogateChar.ToString( "X", NumberFormatInfo.InvariantInfo ) );
-            _BUFFER[bufPos++] = (_BUFFER_TYPE)';';
-            textPos = bufPos;
-        }
-
-        // Serialize either attribute or element text using XML rules.
-        // Arguments are validated in the XmlWellformedWriter layer.
-        public override unsafe void WriteChars( char[] buffer, int index, int count ) {
-            Debug.Assert( buffer != null );
-            Debug.Assert( index >= 0 );
-            Debug.Assert( count >= 0 && index + count <= buffer.Length );
-
-            _SET_TEXT_CONTENT_MARK(true)
-
-            fixed ( char * pSrcBegin = &buffer[index] ) {
-                if ( inAttributeValue ) {
-                    WriteAttributeTextBlock( pSrcBegin, pSrcBegin + count );
-                }
-                else {
-                    WriteElementTextBlock( pSrcBegin, pSrcBegin + count );
-                }
-            }
-        }
-
-        // Serialize raw data.
-        // Arguments are validated in the XmlWellformedWriter layer
-        public override unsafe void WriteRaw( char[] buffer, int index, int count ) {
-            Debug.Assert( buffer != null );
-            Debug.Assert( index >= 0 );
-            Debug.Assert( count >= 0 && index + count <= buffer.Length );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            fixed ( char * pSrcBegin = &buffer[index] ) {
-                WriteRawWithCharChecking( pSrcBegin, pSrcBegin + count );
-            }
-            textPos = bufPos;
-        }
-
-        // Serialize raw data.
-        public override unsafe void WriteRaw( string data ) {
-            Debug.Assert( data != null );
-
-            _SET_TEXT_CONTENT_MARK(false)
-
-            fixed ( char * pSrcBegin = data ) {
-                WriteRawWithCharChecking( pSrcBegin, pSrcBegin + data.Length );
-            }
-            textPos = bufPos;
-        }
-
-        // Flush all bytes in the buffer to output and close the output stream or writer.
-        public override void Close() {
-            try {
-                FlushBuffer();
-                FlushEncoder();
-            }
-            finally {
-                // Future calls to Close or Flush shouldn't write to Stream or Writer
-                writeToNull = true;
-
-                if ( stream != null ) {
-                    try {
-                        stream.Flush();
-                    }
-                    finally {
-                        try {
-                            if ( closeOutput ) {
-                                stream.Close();
-                            }
-                        }
-                        finally {
-                            stream = null;
-                        }
-                    }
-                }
-#ifndef _XML_UTF8_TEXT_WRITER
-                else if ( writer != null ) {
-                    try {
-                        writer.Flush();
-                    }
-                    finally {
-                        try {
-                            if ( closeOutput ) {
-                                writer.Close();
-                            }
-                        }
-                        finally {
-                            writer = null;
-                        }
-                    }
-                }
-#endif
-            }
-        }
-
-        // Flush all characters in the buffer to output and call Flush() on the output object.
-        public override void Flush() {
-            FlushBuffer();
-            FlushEncoder();
-#ifdef _XML_UTF8_TEXT_WRITER
-            if ( stream != null ) {
-                stream.Flush();
-            }
-#else
-            if ( stream != null ) {
-                stream.Flush(); 
-            }
-            else if ( writer != null ) {
-                writer.Flush();
-            }
-#endif
-        }
-
-//
-// Implementation methods
-//
-        // Flush all characters in the buffer to output.  Do not flush the output object.
-        protected virtual void FlushBuffer() {
-            try {
-                // Output all characters (except for previous characters stored at beginning of buffer)
-                if ( !writeToNull ) {
-#ifdef _XML_UTF8_TEXT_WRITER
-                    Debug.Assert( stream != null);
-                    stream.Write( bufBytes, 1, bufPos - 1 );
-#else
-                    Debug.Assert( stream != null || writer != null );
-
-                    if ( stream != null ) {
-                        if ( trackTextContent ) {
-                            charEntityFallback.Reset( textContentMarks, lastMarkPos );
-                            // reset text content tracking
-
-                            if ((lastMarkPos & 1) != 0) {
-                                // If the previous buffer ended inside a text content we need to preserve that info
-                                //   which means the next index to which we write has to be even
-                                textContentMarks[1] = 1;
-                                lastMarkPos = 1;
-                            }
-                            else {
-                                lastMarkPos = 0;
-                            }
-                            Debug.Assert( textContentMarks[0] == 1 );
-                        }
-                        EncodeChars( 1, bufPos, true );
-                    }
-                    else {
-                        // Write text to TextWriter
-                        writer.Write( bufChars, 1, bufPos - 1 );
-                    }
-#endif
-                }
-            }
-            catch {
-                // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream
-                writeToNull = true;
-                throw;
-            }
-            finally {
-                // Move last buffer character to the beginning of the buffer (so that previous character can always be determined)
-                _BUFFER[0] = _BUFFER[bufPos - 1];
-
-#ifdef _XML_UTF8_TEXT_WRITER
-                if ( IsSurrogateByte( _BUFFER[0] ) ) {
-                    // Last character was the first byte in a surrogate encoding, so move last three
-                    // bytes of encoding to the beginning of the buffer.
-                    _BUFFER[1] = _BUFFER[bufPos];
-                    _BUFFER[2] = _BUFFER[bufPos + 1];
-                    _BUFFER[3] = _BUFFER[bufPos + 2];
-                }
-#endif
-
-                // Reset buffer position
-                textPos = (textPos == bufPos) ? 1 : 0;
-                attrEndPos = (attrEndPos == bufPos) ? 1 : 0;
-                contentPos = 0;    // Needs to be zero, since overwriting '>' character is no longer possible
-                cdataPos = 0;      // Needs to be zero, since overwriting ']]>' characters is no longer possible
-                bufPos = 1;        // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
-                                   // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
-            }
-        }
-
-#if _XML_UTF8_TEXT_WRITER
-        private void FlushEncoder() {
-            // intentionally empty
-        }
-#else 
-        private void EncodeChars( int startOffset, int endOffset, bool writeAllToStream ) {
-            // Write encoded text to stream
-            int chEnc;
-            int bEnc;
-            bool completed;
-            while ( startOffset < endOffset ) {
-                if ( charEntityFallback != null ) {
-                    charEntityFallback.StartOffset = startOffset;
-                }
-                encoder.Convert( bufChars, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed );
-                startOffset += chEnc;
-                bufBytesUsed += bEnc;
-                if ( bufBytesUsed >= ( bufBytes.Length - 16 ) ) {
-                    stream.Write( bufBytes, 0, bufBytesUsed );
-                    bufBytesUsed = 0;
-                }
-            }
-            if ( writeAllToStream && bufBytesUsed > 0 ) {
-                stream.Write( bufBytes, 0, bufBytesUsed );
-                bufBytesUsed = 0;
-            }
-        }
-
-        private void FlushEncoder() {
-            Debug.Assert( bufPos == 1 );
-            if ( stream != null ) {
-                int chEnc;
-                int bEnc;
-                bool completed;
-                // decode no chars, just flush
-                encoder.Convert( bufChars, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed );
-                if ( bEnc != 0 ) {
-                    stream.Write( bufBytes, 0, bEnc );
-                }
-            }
-        }
-#endif
-
-        // Serialize text that is part of an attribute value.  The '&', '<', '>', and '"' characters
-        // are entitized.
-        protected unsafe void WriteAttributeTextBlock( char *pSrc, char *pSrcEnd ) {
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                _BUFFER_TYPE * pDst = pDstBegin + this.bufPos;
-
-                int ch = 0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-#if _XML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) ) ) {
-#endif
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-                        pSrc++;
-                    }
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // some character needs to be escaped
-                    switch ( ch ) {
-                        case '&':
-                            pDst = AmpEntity( pDst );
-                            break;
-                        case '<':
-                            pDst = LtEntity( pDst );
-                            break;
-                        case '>':
-                            pDst = GtEntity( pDst );
-                            break;
-                        case '"':
-                            pDst = QuoteEntity( pDst );
-                            break;
-                        case '\'':
-                            *pDst = (_BUFFER_TYPE)ch;
-                            pDst++;
-                            break;
-                        case (char)0x9:
-                            if ( newLineHandling == NewLineHandling.None ) {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            else {
-                                // escape tab in attributes
-                                pDst = TabEntity( pDst );
-                            }
-                            break;
-                        case (char)0xD:
-                            if ( newLineHandling == NewLineHandling.None ) {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            else {
-                                // escape new lines in attributes
-                                pDst = CarriageReturnEntity( pDst );
-                            }
-                            break;
-                        case (char)0xA:
-                            if ( newLineHandling == NewLineHandling.None ) {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            else {
-                                // escape new lines in attributes
-                                pDst = LineFeedEntity( pDst );
-                            }
-                            break;
-                        default:
-                           _ENCODE_CHAR(true);
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-        // Serialize text that is part of element content.  The '&', '<', and '>' characters
-        // are entitized.
-        protected unsafe void WriteElementTextBlock( char *pSrc, char *pSrcEnd ) {
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                _BUFFER_TYPE * pDst = pDstBegin + this.bufPos;
-
-                int ch = 0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-#if _XML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) ) ) {
-#endif
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-                        pSrc++;
-                    }
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // some character needs to be escaped
-                    switch ( ch ) {
-                        case '&':
-                            pDst = AmpEntity( pDst );
-                            break;
-                        case '<':
-                            pDst = LtEntity( pDst );
-                            break;
-                        case '>':
-                            pDst = GtEntity( pDst );
-                            break;
-                        case '"':
-                        case '\'':
-                        case (char)0x9:
-                            *pDst = (_BUFFER_TYPE)ch;
-                            pDst++;
-                            break;
-                        case (char)0xA:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        case (char)0xD:
-                            switch ( newLineHandling ) {
-                                case NewLineHandling.Replace:
-                                    // Replace "\r\n", or "\r" with NewLineChars
-                                    if ( pSrc[1] == '\n' ) {
-                                        pSrc++;
-                                    }
-                                    pDst = WriteNewLine( pDst );
-                                    break;
-                                case NewLineHandling.Entitize:
-                                    // Entitize 0xD
-                                    pDst = CarriageReturnEntity( pDst );
-                                    break;
-                                case NewLineHandling.None:
-                                    *pDst = (_BUFFER_TYPE)ch;
-                                    pDst++;
-                                    break;
-                            }
-                            break;
-                        default:
-                            _ENCODE_CHAR(true);
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-                textPos = bufPos;
-                contentPos = 0;
-            }
-        }
-
-        protected unsafe void RawText( string s ) {
-            Debug.Assert( s != null );
-            fixed ( char * pSrcBegin = s ) {
-                RawText( pSrcBegin, pSrcBegin + s.Length );
-            }
-        }
-
-        protected unsafe void RawText( char * pSrcBegin, char * pSrcEnd ) {
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                _BUFFER_TYPE * pDst = pDstBegin + this.bufPos;
-                char * pSrc = pSrcBegin;
-
-                int ch = 0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + this.bufLen ) {
-                        pDstEnd = pDstBegin + this.bufLen;
-                    }
-
-#ifdef _XML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( ( ch = *pSrc ) <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( ( ch = *pSrc ) < XmlCharType.SurHighStart ) ) {
-#endif
-                        pSrc++;
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-                    }
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    _ENCODE_CHAR(false);
-                }
-
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-        protected unsafe void WriteRawWithCharChecking( char * pSrcBegin, char * pSrcEnd ) {
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                char * pSrc = pSrcBegin;
-                _BUFFER_TYPE * pDst = pDstBegin + bufPos;
-
-                int ch = 0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-#ifdef _XML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISTEXT( ( ch = *pSrc ) ) && ch <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISTEXT( ( ch = *pSrc ) ) ) ) {
-#endif
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-                        pSrc++;
-                    }
-
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // handle special characters
-                    switch ( ch ) {
-                        case ']':
-                        case '<':
-                        case '&':
-                        case (char)0x9:
-                            *pDst = (_BUFFER_TYPE)ch;
-                            pDst++;
-                            break;
-                        case (char)0xD:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                // Normalize "\r\n", or "\r" to NewLineChars
-                                if ( pSrc[1] == '\n' ) {
-                                    pSrc++;
-                                }
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        case (char)0xA:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        default:
-                            _ENCODE_CHAR(false);
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-        protected unsafe void WriteCommentOrPi( string text, int stopChar ) {
-            if ( text.Length == 0 ) {
-                if ( bufPos >= bufLen ) {
-                    FlushBuffer();
-                }
-                return;
-            }
-            // write text
-            fixed ( char * pSrcBegin = text )
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                char * pSrc = pSrcBegin;
-                char * pSrcEnd = pSrcBegin + text.Length;
-                _BUFFER_TYPE * pDst = pDstBegin + bufPos;
-
-                int ch = 0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-#ifdef _XML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISTEXT( ( ch = *pSrc ) ) && ch != stopChar && ch <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISTEXT( ( ch = *pSrc ) ) && ch != stopChar ) ) {
-#endif
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-                        pSrc++;
-                    }
-
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // handle special characters
-                    switch ( ch ) {
-                        case '-':
-                            *pDst = (_BUFFER_TYPE) '-';
-                            pDst++;
-                            if ( ch == stopChar ) {
-                                // Insert space between adjacent dashes or before comment's end dashes
-                                if ( pSrc + 1 == pSrcEnd || *(pSrc + 1)== '-' ) {
-                                    *pDst = (_BUFFER_TYPE) ' ';
-                                    pDst++;
-                                }
-                            }
-                            break;
-                        case '?':
-                            *pDst = (_BUFFER_TYPE) '?';
-                            pDst++;
-                            if ( ch == stopChar ) {
-                                // Processing instruction: insert space between adjacent '?' and '>' 
-                                if ( pSrc + 1 < pSrcEnd && *(pSrc + 1)== '>' ) {
-                                    *pDst = (_BUFFER_TYPE) ' ';
-                                    pDst++;
-                                }
-                            }
-                            break;
-                        case ']':
-                            *pDst = (_BUFFER_TYPE) ']';
-                            pDst++;
-                            break;
-                        case (char)0xD:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                // Normalize "\r\n", or "\r" to NewLineChars
-                                if ( pSrc[1] == '\n' ) {
-                                    pSrc++;
-                                }
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        case (char)0xA:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        case '<':
-                        case '&':
-                        case (char)0x9:
-                            *pDst = (_BUFFER_TYPE)ch;
-                            pDst++;
-                            break;
-                        default:
-                            _ENCODE_CHAR(false);
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-        protected unsafe void WriteCDataSection( string text ) {
-            if ( text.Length == 0 ) {
-                if ( bufPos >= bufLen ) {
-                    FlushBuffer();
-                }
-                return;
-            }
-            // write text
-            fixed ( char * pSrcBegin = text )
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                char * pSrc = pSrcBegin;
-                char * pSrcEnd = pSrcBegin + text.Length;
-                _BUFFER_TYPE * pDst = pDstBegin + bufPos;
-
-                int ch = 0;
-                for (;;) {
-                    _BUFFER_TYPE * pDstEnd = pDst + ( pSrcEnd - pSrc );
-                    if ( pDstEnd > pDstBegin + bufLen ) {
-                        pDstEnd = pDstBegin + bufLen;
-                    }
-
-#ifdef _XML_UTF8_TEXT_WRITER
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch != ']' && ch <= 0x7F ) ) {
-#else
-                    while ( pDst < pDstEnd && ( XMLCHARTYPE_ISATTRIBUTEVALUECHAR( ( ch = *pSrc ) ) && ch != ']' ) ) {
-#endif
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-                        pSrc++;
-                    }
-
-                    Debug.Assert( pSrc <= pSrcEnd );
-
-                    // end of value
-                    if ( pSrc >= pSrcEnd ) {
-                        break;
-                    }
-
-                    // end of buffer
-                    if ( pDst >= pDstEnd ) {
-                        bufPos = (int)(pDst - pDstBegin);
-                        FlushBuffer();
-                        pDst = pDstBegin + 1;
-                        continue;
-                    }
-
-                    // handle special characters
-                    switch ( ch ) {
-                        case '>':
-                            if ( hadDoubleBracket && pDst[-1] == (_BUFFER_TYPE) ']') {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
-                                // The characters "]]>" were found within the CData text
-                                pDst = RawEndCData( pDst );
-                                pDst = RawStartCData( pDst );
-                            }
-                            *pDst = (_BUFFER_TYPE) '>';
-                            pDst++;
-                            break;
-                        case ']':
-                            if ( pDst[-1] == (_BUFFER_TYPE)']' ) {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
-                                hadDoubleBracket = true;
-                            }
-                            else {
-                                hadDoubleBracket = false;
-                            }
-                            *pDst = (_BUFFER_TYPE)']';
-                            pDst++;
-                            break;
-                        case (char)0xD:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                // Normalize "\r\n", or "\r" to NewLineChars
-                                if ( pSrc[1] == '\n' ) {
-                                    pSrc++;
-                                }
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        case (char)0xA:
-                            if ( newLineHandling == NewLineHandling.Replace ) {
-                                pDst = WriteNewLine( pDst );
-                            }
-                            else {
-                                *pDst = (_BUFFER_TYPE)ch;
-                                pDst++;
-                            }
-                            break;
-                        case '&':
-                        case '<':
-                        case '"':
-                        case '\'':
-                        case (char)0x9:
-                            *pDst = (_BUFFER_TYPE)ch;
-                            pDst++;
-                            break;
-                        default:
-                            _ENCODE_CHAR(false);
-                            continue;
-                    }
-                    pSrc++;
-                }
-                bufPos = (int)(pDst - pDstBegin);
-            }
-        }
-
-#ifdef _XML_UTF8_TEXT_WRITER
-        // Returns true if UTF8 encoded byte is first of four bytes that encode a surrogate pair.
-        // To do this, detect the bit pattern 11110xxx.
-        private static bool IsSurrogateByte( byte b ) {
-            return (b & 0xF8) == 0xF0;
-        }
-#endif
-
-        private static unsafe _BUFFER_TYPE* EncodeSurrogate( char* pSrc, char* pSrcEnd, _BUFFER_TYPE* pDst ) {
-            Debug.Assert( XmlCharType.IsSurrogate( *pSrc ) );
-
-            int ch = *pSrc;
-            if ( ch <= XmlCharType.SurHighEnd ) {
-                if ( pSrc + 1 < pSrcEnd ) {
-                    int lowChar = pSrc[1];
-                    if ( lowChar >= XmlCharType.SurLowStart ) {
-#ifdef _XML_UTF8_TEXT_WRITER
-                        // Calculate Unicode scalar value for easier manipulations (see section 3.7 in Unicode spec)
-                        // The scalar value repositions surrogate values to start at 0x10000.
-                        
-                        ch = XmlCharType.CombineSurrogateChar( lowChar, ch );
-
-                        pDst[0] = (byte)( 0xF0 | ( ch >> 18 ) );
-                        pDst[1] = (byte)( 0x80 | ( ch >> 12 ) & 0x3F );
-                        pDst[2] = (byte)( 0x80 | ( ch >> 6  ) & 0x3F );
-                        pDst[3] = (byte)( 0x80 | ch & 0x3F);
-                        pDst += 4;
-#else
-                        pDst[0] = (char)ch;
-                        pDst[1] = (char)lowChar;
-                        pDst += 2;
-#endif
-                        return pDst;
-                    }
-                    throw XmlConvert.CreateInvalidSurrogatePairException( (char)lowChar, (char)ch );
-                }
-                throw new ArgumentException( string.Format( SR.Xml_InvalidSurrogateMissingLowChar ) );
-            }
-            throw XmlConvert.CreateInvalidHighSurrogateCharException( (char)ch );
-        }
-
-        private unsafe _BUFFER_TYPE* InvalidXmlChar( int ch, _BUFFER_TYPE* pDst, bool entitize ) {
-            Debug.Assert( !xmlCharType.IsWhiteSpace( (char)ch ) );
-            Debug.Assert( !xmlCharType.IsAttributeValueChar( (char)ch ) );
-
-            if ( checkCharacters ) {
-                // This method will never be called on surrogates, so it is ok to pass in '\0' to the CreateInvalidCharException
-                throw XmlConvert.CreateInvalidCharException( (char)ch, '\0' );
-            }
-            else {
-                if ( entitize ) {
-                    return CharEntity( pDst, (char)ch );
-                }
-                else {
-#ifdef _XML_UTF8_TEXT_WRITER
-                    if ( ch < 0x80 ) {
-#endif
-                        *pDst = (_BUFFER_TYPE)ch;
-                        pDst++;
-#ifdef _XML_UTF8_TEXT_WRITER
-                    }
-                    else {
-                        pDst = EncodeMultibyteUTF8( ch, pDst );
-                    }
-#endif
-                    return pDst;
-                }
-            }
-        }
-
-        internal unsafe void EncodeChar(ref char* pSrc, char*pSrcEnd, ref _BUFFER_TYPE* pDst) {
-            int ch = *pSrc;
-            _ENCODE_CHAR(false);
-        }
-
-#ifdef _XML_UTF8_TEXT_WRITER
-        internal static unsafe byte* EncodeMultibyteUTF8( int ch, byte* pDst ) {
-            Debug.Assert( ch >= 0x80 && !XmlCharType.IsSurrogate( ch ) );
-
-            unchecked {
-                /* UTF8-2: If ch is in 0x80-0x7ff range, then use 2 bytes to encode it */ \
-                if ( ch < 0x800 ) {
-                    *pDst = (byte)( (sbyte)0xC0 | (ch >> 6) );
-                }
-                /* UTF8-3: If ch is anything else, then default to using 3 bytes to encode it. */
-                else {
-                    *pDst = (byte)( (sbyte)0xE0 | ( ch >> 12 ) );
-                    pDst++;
-
-                    *pDst = (byte)( (sbyte)0x80 | ( ch >> 6 ) & 0x3F);
-                }
-            }
-
-            pDst++;
-            *pDst = (byte)( 0x80 | ch & 0x3F );   
-            return pDst + 1;
-        }
-
-        // Encode *pSrc as a sequence of UTF8 bytes.  Write the bytes to pDst and return an updated pointer.
-        internal static unsafe void CharToUTF8( ref char * pSrc, char * pSrcEnd, ref byte * pDst ) {
-            int ch = *pSrc;
-            if ( ch <= 0x7F ) {
-                *pDst = (byte)ch;
-                pDst++;
-                pSrc++;
-            }
-            else if ( XmlCharType.IsSurrogate( ch ) ) { 
-                pDst = EncodeSurrogate( pSrc, pSrcEnd, pDst ); 
-                pSrc += 2; 
-            } 
-            else { 
-                pDst = EncodeMultibyteUTF8( ch, pDst ); 
-                pSrc++; 
-            }
-        }
-
-#endif
-
-#ifdef _XML_ENCODED_TEXT_WRITER
-
-        protected void ChangeTextContentMark( bool value ) {
-            Debug.Assert( inTextContent != value );
-            Debug.Assert( inTextContent || ((lastMarkPos & 1) == 0) );
-            inTextContent = value;
-            if ( lastMarkPos + 1 == textContentMarks.Length ) {
-                GrowTextContentMarks();
-            }
-            textContentMarks[++lastMarkPos] = this.bufPos;
-        }
-
-        private void GrowTextContentMarks() {
-            Debug.Assert( lastMarkPos + 1 == textContentMarks.Length );
-            int[] newTextContentMarks = new int[ textContentMarks.Length * 2 ];
-            Array.Copy( textContentMarks, newTextContentMarks, textContentMarks.Length );
-            textContentMarks = newTextContentMarks;
-        }
-
-#endif
-       
-        // Write NewLineChars to the specified buffer position and return an updated position.
-        protected unsafe _BUFFER_TYPE * WriteNewLine( _BUFFER_TYPE * pDst ) {
-            fixed ( _BUFFER_TYPE * pDstBegin = _BUFFER ) {
-                bufPos = (int) (pDst - pDstBegin);
-                // Let RawText do the real work
-                RawText( newLineChars );
-                return pDstBegin + bufPos;
-            }
-        }
-
-        // Following methods do not check whether pDst is beyond the bufSize because the buffer was allocated with a OVERFLOW to accommodate
-        // for the writes of small constant-length string as below.
-
-        // Entitize '<' as "&lt;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * LtEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'l'; 
-            pDst[2] = (_BUFFER_TYPE)'t'; 
-            pDst[3] = (_BUFFER_TYPE)';';
-            return pDst + 4;
-        }
-
-        // Entitize '>' as "&gt;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * GtEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'g'; 
-            pDst[2] = (_BUFFER_TYPE)'t'; 
-            pDst[3] = (_BUFFER_TYPE)';';
-            return pDst + 4;
-        }
-
-        // Entitize '&' as "&amp;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * AmpEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'a'; 
-            pDst[2] = (_BUFFER_TYPE)'m'; 
-            pDst[3] = (_BUFFER_TYPE)'p'; 
-            pDst[4] = (_BUFFER_TYPE)';';
-            return pDst + 5;
-        }
-
-        // Entitize '"' as "&quot;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * QuoteEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'q'; 
-            pDst[2] = (_BUFFER_TYPE)'u'; 
-            pDst[3] = (_BUFFER_TYPE)'o'; 
-            pDst[4] = (_BUFFER_TYPE)'t'; 
-            pDst[5] = (_BUFFER_TYPE)';';
-            return pDst + 6;
-        }
-
-        // Entitize '\t' as "&#x9;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * TabEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'#'; 
-            pDst[2] = (_BUFFER_TYPE)'x'; 
-            pDst[3] = (_BUFFER_TYPE)'9'; 
-            pDst[4] = (_BUFFER_TYPE)';';
-            return pDst + 5;
-        }
-
-        // Entitize 0xa as "&#xA;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * LineFeedEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'#'; 
-            pDst[2] = (_BUFFER_TYPE)'x'; 
-            pDst[3] = (_BUFFER_TYPE)'A'; 
-            pDst[4] = (_BUFFER_TYPE)';';
-            return pDst + 5;
-        }
-
-        // Entitize 0xd as "&#xD;".  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * CarriageReturnEntity( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'#'; 
-            pDst[2] = (_BUFFER_TYPE)'x'; 
-            pDst[3] = (_BUFFER_TYPE)'D'; 
-            pDst[4] = (_BUFFER_TYPE)';';
-            return pDst + 5;
-        }
-
-        private static unsafe _BUFFER_TYPE * CharEntity( _BUFFER_TYPE * pDst, char ch ) {
-            string s = ((int)ch).ToString( "X",NumberFormatInfo.InvariantInfo );
-            pDst[0] = (_BUFFER_TYPE)'&'; 
-            pDst[1] = (_BUFFER_TYPE)'#'; 
-            pDst[2] = (_BUFFER_TYPE)'x'; 
-            pDst += 3;
-            
-            fixed ( char *pSrc = s ) {
-                char *pS = pSrc;
-                while ( ( *pDst++ = (_BUFFER_TYPE)*pS++ ) != 0 );
-            }
-
-            pDst[-1] = (_BUFFER_TYPE)';';
-            return pDst;
-        }
-
-        // Write "<![CDATA[" to the specified buffer.  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * RawStartCData( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)'<'; 
-            pDst[1] = (_BUFFER_TYPE)'!'; 
-            pDst[2] = (_BUFFER_TYPE)'['; 
-            pDst[3] = (_BUFFER_TYPE)'C'; 
-            pDst[4] = (_BUFFER_TYPE)'D';
-            pDst[5] = (_BUFFER_TYPE)'A'; 
-            pDst[6] = (_BUFFER_TYPE)'T'; 
-            pDst[7] = (_BUFFER_TYPE)'A'; 
-            pDst[8] = (_BUFFER_TYPE)'[';
-            return pDst + 9;
-        }
-
-        // Write "]]>" to the specified buffer.  Return an updated pointer.
-        protected static unsafe _BUFFER_TYPE * RawEndCData( _BUFFER_TYPE * pDst ) {
-            pDst[0] = (_BUFFER_TYPE)']'; 
-            pDst[1] = (_BUFFER_TYPE)']'; 
-            pDst[2] = (_BUFFER_TYPE)'>';
-            return pDst + 3;
-        }
-
-        protected unsafe void ValidateContentChars( string chars, string propertyName, bool allowOnlyWhitespace ) {
-            if ( allowOnlyWhitespace ) {
-                if ( !xmlCharType.IsOnlyWhitespace( chars ) ) {
-                    throw new ArgumentException( string.Format( SR.Xml_IndentCharsNotWhitespace, propertyName ) );
-                }
-            }
-            else {
-                string error = null;
-                for ( int i = 0; i < chars.Length; i++ ) {
-                    if ( !xmlCharType.IsTextChar( chars[i] ) ) {
-                        switch ( chars[i] ) {
-                            case '\n':
-                            case '\r':
-                            case '\t':
-                                continue;
-                            case '<':
-                            case '&':
-                            case ']':
-                                error = string.Format( SR.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs( chars, i ) );
-                                goto Error;
-                            default:
-                                if ( XmlCharType.IsHighSurrogate(chars[i]) ) {
-                                    if ( i + 1 < chars.Length ) {
-                                        if ( XmlCharType.IsLowSurrogate(chars[i + 1])  ) {
-                                            i++;
-                                            continue;
-                                        }
-                                    }
-                                    error = string.Format( SR.Xml_InvalidSurrogateMissingLowChar );
-                                    goto Error;
-                                }
-                                else if ( XmlCharType.IsLowSurrogate(chars[i]) ) {
-                                    error = string.Format( SR.Xml_InvalidSurrogateHighChar, ((uint)chars[i]).ToString( "X", CultureInfo.InvariantCulture ) );
-                                    goto Error;
-                                }
-                                continue;
-                        }
-                    }
-                }
-                return;
-
-            Error:
-                throw new ArgumentException( string.Format( SR.Xml_InvalidCharsInIndent, new string[] { propertyName, error } ) );
-            }
-        }
-    }
-
-    // Same as base text writer class except that elements, attributes, comments, and pi's are indented.
-    internal class _CLASS_NAME_INDENT : _CLASS_NAME {
-//
-// Fields
-//
-        protected int       indentLevel;
-        protected bool      newLineOnAttributes;
-        protected string    indentChars;
-
-        protected bool      mixedContent;
-        private BitStack    mixedContentStack;
-
-        protected ConformanceLevel conformanceLevel = ConformanceLevel.Auto;
-
-//
-// Constructors
-//
-
-#ifdef _XML_ENCODED_TEXT_WRITER
-        public _CLASS_NAME_INDENT( TextWriter writer, XmlWriterSettings settings ) : base( writer, settings ) {
-            Init( settings );
-        }
-#endif
-
-        public _CLASS_NAME_INDENT( Stream stream, XmlWriterSettings settings ) : base( stream, settings ) {
-            Init( settings );
-        }
-
-//
-// XmlWriter methods
-//
-        public override XmlWriterSettings Settings {
-            get {
-                XmlWriterSettings settings = base.Settings;
-
-                settings.ReadOnly = false;
-                settings.Indent = true;
-                settings.IndentChars = indentChars;
-                settings.NewLineOnAttributes = newLineOnAttributes;
-                settings.ReadOnly = true;
-
-                return settings;
-            }
-        }
-
-        public override void WriteDocType( string name, string pubid, string sysid, string subset ) {
-            // Add indentation
-            if ( !mixedContent && base.textPos != base.bufPos) {
-                WriteIndent();
-            }
-            base.WriteDocType( name, pubid, sysid, subset );
-        }
-
-        public override void WriteStartElement( string prefix, string localName, string ns ) {
-            Debug.Assert( localName != null && localName.Length != 0 && prefix != null && ns != null );
-
-            // Add indentation
-            if ( !mixedContent && base.textPos != base.bufPos) {
-                WriteIndent();
-            }
-            indentLevel++;
-            mixedContentStack.PushBit( mixedContent );
-
-            base.WriteStartElement( prefix, localName, ns );
-        }
-
-        internal override void StartElementContent() {
-            // If this is the root element and we're writing a document
-            //   do not inherit the mixedContent flag into the root element.
-            //   This is to allow for whitespace nodes on root level
-            //   without disabling indentation for the whole document.
-            if (indentLevel == 1 && conformanceLevel == ConformanceLevel.Document) {
-                mixedContent = false;
-            }
-            else {
-                mixedContent = mixedContentStack.PeekBit();
-            }
-            base.StartElementContent();
-        }
-
-        internal override void OnRootElement(ConformanceLevel currentConformanceLevel) { 
-            // Just remember the current conformance level
-            conformanceLevel = currentConformanceLevel;
-        }
-
-        internal override void WriteEndElement(string prefix, string localName, string ns) {
-            // Add indentation
-            indentLevel--;
-            if ( !mixedContent && base.contentPos != base.bufPos ) {
-                // There was content, so try to indent
-                if ( base.textPos != base.bufPos ) {
-                    WriteIndent();
-                }
-            }
-            mixedContent = mixedContentStack.PopBit();
-
-            base.WriteEndElement( prefix, localName, ns );
-        }
-
-        internal override void WriteFullEndElement(string prefix, string localName, string ns) {
-            // Add indentation
-            indentLevel--;
-            if ( !mixedContent && base.contentPos != base.bufPos ) {
-                // There was content, so try to indent
-                if ( base.textPos != base.bufPos ) {
-                    WriteIndent();
-                }
-            }
-            mixedContent = mixedContentStack.PopBit();
-
-            base.WriteFullEndElement( prefix, localName, ns );
-        }
-
-        // Same as base class, plus possible indentation.
-        public override void WriteStartAttribute( string prefix, string localName, string ns ) {
-            // Add indentation
-            if ( newLineOnAttributes ) {
-                WriteIndent();
-            }
-
-            base.WriteStartAttribute( prefix, localName, ns );
-        }
-
-        public override void WriteCData( string text ) {
-            mixedContent = true;
-            base.WriteCData( text );
-        }
-    
-        public override void WriteComment( string text ) {
-            if ( !mixedContent && base.textPos != base.bufPos ) {
-                WriteIndent();
-            }
-
-            base.WriteComment( text );
-        }
-
-        public override void WriteProcessingInstruction( string target, string text ) {
-            if ( !mixedContent && base.textPos != base.bufPos ) {
-                WriteIndent();
-            }
-
-            base.WriteProcessingInstruction( target, text );
-        }
-
-        public override void WriteEntityRef( string name ) {
-            mixedContent = true;
-            base.WriteEntityRef( name );
-        }
-
-        public override void WriteCharEntity( char ch ) {
-            mixedContent = true;
-            base.WriteCharEntity( ch );
-        }
-
-        public override void WriteSurrogateCharEntity( char lowChar, char highChar ) {
-            mixedContent = true;
-            base.WriteSurrogateCharEntity( lowChar, highChar );
-        }
-
-        public override void WriteWhitespace( string ws ) {
-            mixedContent = true;
-            base.WriteWhitespace( ws );
-        }
-
-        public override void WriteString( string text ) {
-            mixedContent = true;
-            base.WriteString( text );
-        }
-
-        public override void WriteChars( char[] buffer, int index, int count ) {
-            mixedContent = true;
-            base.WriteChars( buffer, index, count );
-        }
-
-        public override void WriteRaw( char[] buffer, int index, int count ) {
-            mixedContent = true;
-            base.WriteRaw( buffer, index, count );
-        }
-
-        public override void WriteRaw( string data ) {
-            mixedContent = true;
-            base.WriteRaw( data );
-        }
-
-        public override void WriteBase64( byte[] buffer, int index, int count ) {
-            mixedContent = true;
-            base.WriteBase64( buffer, index, count );
-        }
-
-//
-// Private methods
-//
-        private void Init( XmlWriterSettings settings ) {
-            indentLevel = 0;
-            indentChars = settings.IndentChars;
-            newLineOnAttributes = settings.NewLineOnAttributes;
-            mixedContentStack = new BitStack();
-
-            // check indent characters that they are valid XML characters
-            if ( base.checkCharacters ) {
-                if ( newLineOnAttributes ) {
-                    base.ValidateContentChars( indentChars, "IndentChars", true );
-                    base.ValidateContentChars( newLineChars, "NewLineChars", true );
-                }
-                else {
-                    base.ValidateContentChars( indentChars, "IndentChars", false );
-                    if ( base.newLineHandling != NewLineHandling.Replace ) {
-                        base.ValidateContentChars( newLineChars, "NewLineChars", false );
-                    }
-                }
-            }
-        }
-
-        // Add indentation to output.  Write newline and then repeat IndentChars for each indent level.
-        private void WriteIndent() {
-            RawText( base.newLineChars );
-            for ( int i = indentLevel; i > 0; i-- ) {
-                RawText( indentChars );
-            }
-        }
-    }
-}
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
new file mode 100644 (file)
index 0000000..99c9681
--- /dev/null
@@ -0,0 +1,2202 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriter.ttinclude" #>// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify XmlRawTextWriterGenerator.ttinclude
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Text;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace System.Xml
+{
+    // Concrete implementation of XmlWriter abstract class that serializes events as encoded XML
+    // text.  The general-purpose XmlEncodedTextWriter uses the Encoder class to output to any
+    // encoding.  The XmlUtf8TextWriter class combined the encoding operation with serialization
+    // in order to achieve better performance.
+    internal partial class <#= ClassName #> : XmlRawWriter
+    {
+        //
+        // Fields
+        //
+        private readonly bool _useAsync;
+
+        // main buffer
+        protected byte[] bufBytes;
+
+        // output stream
+        protected Stream stream;
+
+        // encoding of the stream or text writer
+        protected Encoding encoding;
+
+        // char type tables
+        protected XmlCharType xmlCharType = XmlCharType.Instance;
+
+        // buffer positions
+        protected int bufPos = 1;     // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
+                                      // close an empty element or in CDATA section detection of double ]; <#= BufferName #>[0] will always be 0
+        protected int textPos = 1;    // text end position; don't indent first element, pi, or comment
+        protected int contentPos;     // element content end position
+        protected int cdataPos;       // cdata end position
+        protected int attrEndPos;     // end of the last attribute
+        protected int bufLen = BUFSIZE;
+
+        // flags
+        protected bool writeToNull;
+        protected bool hadDoubleBracket;
+        protected bool inAttributeValue;
+
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+        protected int bufBytesUsed;
+        protected char[] bufChars;
+
+        // encoder for encoding chars in specified encoding when writing to stream
+        protected Encoder encoder;
+
+        // output text writer
+        protected TextWriter writer;
+
+        // escaping of characters invalid in the output encoding
+        protected bool trackTextContent;
+        protected bool inTextContent;
+        private int _lastMarkPos;
+        private int[] _textContentMarks;   // even indices contain text content start positions
+                                           // odd indices contain markup start positions
+        private CharEntityEncoderFallback _charEntityFallback;
+<# } #>
+
+        // writer settings
+        protected NewLineHandling newLineHandling;
+        protected bool closeOutput;
+        protected bool omitXmlDeclaration;
+        protected string newLineChars;
+        protected bool checkCharacters;
+
+        protected XmlStandalone standalone;
+        protected XmlOutputMethod outputMethod;
+
+        protected bool autoXmlDeclaration;
+        protected bool mergeCDataSections;
+
+        //
+        // Constants
+        //
+        private const int BUFSIZE = 2048 * 3;       // Should be greater than default FileStream size (4096), otherwise the FileStream will try to cache the data
+        private const int ASYNCBUFSIZE = 64 * 1024; // Set async buffer size to 64KB
+        private const int OVERFLOW = 32;            // Allow overflow in order to reduce checks when writing out constant size markup
+        private const int INIT_MARKS_COUNT = 64;
+
+        //
+        // Constructors
+        //
+        // Construct and initialize an instance of this class.
+        protected <#= ClassName #>(XmlWriterSettings settings)
+        {
+            _useAsync = settings.Async;
+
+            // copy settings
+            newLineHandling = settings.NewLineHandling;
+            omitXmlDeclaration = settings.OmitXmlDeclaration;
+            newLineChars = settings.NewLineChars;
+            checkCharacters = settings.CheckCharacters;
+            closeOutput = settings.CloseOutput;
+
+            standalone = settings.Standalone;
+            outputMethod = settings.OutputMethod;
+            mergeCDataSections = settings.MergeCDataSections;
+
+            if (checkCharacters && newLineHandling == NewLineHandling.Replace)
+            {
+                ValidateContentChars(newLineChars, "NewLineChars", false);
+            }
+        }
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+
+        // Construct an instance of this class that outputs text to the TextWriter interface.
+        public <#= ClassName #>(TextWriter writer, XmlWriterSettings settings) : this(settings)
+        {
+            Debug.Assert(writer != null && settings != null);
+
+            this.writer = writer;
+            this.encoding = writer.Encoding;
+            // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup
+            if (settings.Async)
+            {
+                bufLen = ASYNCBUFSIZE;
+            }
+            this.bufChars = new <#= BufferType #>[bufLen + OVERFLOW];
+
+            // Write the xml declaration
+            if (settings.AutoXmlDeclaration)
+            {
+                WriteXmlDeclaration(standalone);
+                autoXmlDeclaration = true;
+            }
+        }
+<# } #>
+
+        // Construct an instance of this class that serializes to a Stream interface.
+        public <#= ClassName #>(Stream stream, XmlWriterSettings settings) : this(settings)
+        {
+            Debug.Assert(stream != null && settings != null);
+
+            this.stream = stream;
+            this.encoding = settings.Encoding;
+
+            // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup
+            if (settings.Async)
+            {
+                bufLen = ASYNCBUFSIZE;
+            }
+
+            <#= BufferName #> = new <#= BufferType #>[bufLen + OVERFLOW];
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+            // Output UTF-8 byte order mark if Encoding object wants it
+            if (!stream.CanSeek || stream.Position == 0)
+            {
+                ReadOnlySpan<byte> bom = encoding.Preamble;
+                if (bom.Length != 0)
+                {
+                    bom.CopyTo(new Span<byte>(bufBytes).Slice(1));
+                    bufPos += bom.Length;
+                    textPos += bom.Length;
+                }
+            }
+<# } else { #>
+            bufBytes = new byte[bufChars.Length];
+            bufBytesUsed = 0;
+
+            // Init escaping of characters not fitting into the target encoding
+            trackTextContent = true;
+            inTextContent = false;
+            _lastMarkPos = 0;
+            _textContentMarks = new int[INIT_MARKS_COUNT];
+            _textContentMarks[0] = 1;
+
+            _charEntityFallback = new CharEntityEncoderFallback();
+
+            // grab bom before possibly changing encoding settings
+            ReadOnlySpan<byte> bom = encoding.Preamble;
+
+            // the encoding instance this creates can differ from the one passed in
+            this.encoding = Encoding.GetEncoding(
+                settings.Encoding.CodePage,
+                _charEntityFallback,
+                settings.Encoding.DecoderFallback);
+
+            encoder = encoding.GetEncoder();
+
+            if (!stream.CanSeek || stream.Position == 0)
+            {
+                if (bom.Length != 0)
+                {
+                    this.stream.Write(bom);
+                }
+            }
+<# } #>
+
+            // Write the xml declaration
+            if (settings.AutoXmlDeclaration)
+            {
+                WriteXmlDeclaration(standalone);
+                autoXmlDeclaration = true;
+            }
+        }
+
+        //
+        // XmlWriter implementation
+        //
+        // Returns settings the writer currently applies.
+        public override XmlWriterSettings Settings
+        {
+            get
+            {
+                XmlWriterSettings settings = new XmlWriterSettings();
+
+                settings.Encoding = encoding;
+                settings.OmitXmlDeclaration = omitXmlDeclaration;
+                settings.NewLineHandling = newLineHandling;
+                settings.NewLineChars = newLineChars;
+                settings.CloseOutput = closeOutput;
+                settings.ConformanceLevel = ConformanceLevel.Auto;
+                settings.CheckCharacters = checkCharacters;
+
+                settings.AutoXmlDeclaration = autoXmlDeclaration;
+                settings.Standalone = standalone;
+                settings.OutputMethod = outputMethod;
+
+                settings.ReadOnly = true;
+                return settings;
+            }
+        }
+
+        // Write the xml declaration.  This must be the first call.
+        internal override void WriteXmlDeclaration(XmlStandalone standalone)
+        {
+            // Output xml declaration only if user allows it and it was not already output
+            if (!omitXmlDeclaration && !autoXmlDeclaration)
+            {<# /* Code block is to squash extra line. */
+#><#= SetTextContentMark(4, 1, false) #>
+                RawText("<?xml version=\"");
+
+                // Version
+                RawText("1.0");
+
+                // Encoding
+                if (encoding != null)
+                {
+                    RawText("\" encoding=\"");
+                    RawText(encoding.WebName);
+                }
+
+                // Standalone
+                if (standalone != XmlStandalone.Omit)
+                {
+                    RawText("\" standalone=\"");
+                    RawText(standalone == XmlStandalone.Yes ? "yes" : "no");
+                }
+
+                RawText("\"?>");
+            }
+        }
+
+        internal override void WriteXmlDeclaration(string xmldecl)
+        {
+            // Output xml declaration only if user allows it and it was not already output
+            if (!omitXmlDeclaration && !autoXmlDeclaration)
+            {
+                WriteProcessingInstruction("xml", xmldecl);
+            }
+        }
+
+        // Serialize the document type declaration.
+        public override void WriteDocType(string name, string pubid, string sysid, string subset)
+        {
+            Debug.Assert(name != null && name.Length > 0);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            RawText("<!DOCTYPE ");
+            RawText(name);
+            if (pubid != null)
+            {
+                RawText(" PUBLIC \"");
+                RawText(pubid);
+                RawText("\" \"");
+                if (sysid != null)
+                {
+                    RawText(sysid);
+                }
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else if (sysid != null)
+            {
+                RawText(" SYSTEM \"");
+                RawText(sysid);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+            }
+
+            if (subset != null)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+                RawText(subset);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            }
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize the beginning of an element start tag: "<prefix:localName"
+        public override void WriteStartElement(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            if (prefix != null && prefix.Length != 0)
+            {
+                RawText(prefix);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)':';
+            }
+
+            RawText(localName);
+
+            attrEndPos = bufPos;
+        }
+
+        // Serialize the end of an element start tag in preparation for content serialization: ">"
+        internal override void StartElementContent()
+        {
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+
+            // StartElementContent is always called; therefore, in order to allow shortcut syntax, we save the
+            // position of the '>' character.  If WriteEndElement is called and no other characters have been
+            // output, then the '>' character can be overwritten with the shortcut syntax " />".
+            contentPos = bufPos;
+        }
+
+        // Serialize an element end tag: "</prefix:localName>", if content was output.  Otherwise, serialize
+        // the shortcut syntax: " />".
+        internal override void WriteEndElement(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (contentPos != bufPos)
+            {
+                // Content has been output, so can't use shortcut syntax
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/';
+
+                if (prefix != null && prefix.Length != 0)
+                {
+                    RawText(prefix);
+                    <#= BufferName #>[bufPos++] = (<#= BufferType #>)':';
+                }
+                RawText(localName);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+            }
+            else
+            {
+                // Use shortcut syntax; overwrite the already output '>' character
+                bufPos--;
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+            }
+        }
+
+        // Serialize a full element end tag: "</prefix:localName>"
+        internal override void WriteFullEndElement(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/';
+
+            if (prefix != null && prefix.Length != 0)
+            {
+                RawText(prefix);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)':';
+            }
+            RawText(localName);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize an attribute tag using double quotes around the attribute value: 'prefix:localName="'
+        public override void WriteStartAttribute(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (attrEndPos == bufPos)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+            }
+
+            if (prefix != null && prefix.Length > 0)
+            {
+                RawText(prefix);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)':';
+            }
+            RawText(localName);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'=';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+
+            inAttributeValue = true;
+        }
+
+        // Serialize the end of an attribute value using double quotes: '"'
+        public override void WriteEndAttribute()
+        {<#
+#><#= SetTextContentMark(3, 1, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            inAttributeValue = false;
+            attrEndPos = bufPos;
+        }
+
+        internal override void WriteNamespaceDeclaration(string prefix, string namespaceName)
+        {
+            Debug.Assert(prefix != null && namespaceName != null);
+
+            WriteStartNamespaceDeclaration(prefix);
+            WriteString(namespaceName);
+            WriteEndNamespaceDeclaration();
+        }
+
+        internal override bool SupportsNamespaceDeclarationInChunks
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        internal override void WriteStartNamespaceDeclaration(string prefix)
+        {
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (prefix.Length == 0)
+            {
+                RawText(" xmlns=\"");
+            }
+            else
+            {
+                RawText(" xmlns:");
+                RawText(prefix);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'=';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+
+            inAttributeValue = true;<#
+#><#= SetTextContentMark(3, true) #>
+        }
+
+        internal override void WriteEndNamespaceDeclaration()
+        {<#
+#><#= SetTextContentMark(3, 1, false) #>
+            inAttributeValue = false;
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            attrEndPos = bufPos;
+        }
+
+        // Serialize a CData section.  If the "]]>" pattern is found within
+        // the text, replace it with "]]><![CDATA[>".
+        public override void WriteCData(string text)
+        {
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (mergeCDataSections && bufPos == cdataPos)
+            {
+                // Merge adjacent cdata sections - overwrite the "]]>" characters
+                Debug.Assert(bufPos >= 4);
+                bufPos -= 3;
+            }
+            else
+            {
+                // Start a new cdata section
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'C';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'D';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'T';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+            }
+
+            WriteCDataSection(text);
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+
+            textPos = bufPos;
+            cdataPos = bufPos;
+        }
+
+        // Serialize a comment.
+        public override void WriteComment(string text)
+        {
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+
+            WriteCommentOrPi(text, '-');
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize a processing instruction.
+        public override void WriteProcessingInstruction(string name, string text)
+        {
+            Debug.Assert(name != null && name.Length > 0);
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?';
+            RawText(name);
+
+            if (text.Length > 0)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+                WriteCommentOrPi(text, '?');
+            }
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize an entity reference.
+        public override void WriteEntityRef(string name)
+        {
+            Debug.Assert(name != null && name.Length > 0);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&';
+            RawText(name);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+
+            if (bufPos > bufLen)
+            {
+                FlushBuffer();
+            }
+
+            textPos = bufPos;
+        }
+
+        // Serialize a character entity reference.
+        public override void WriteCharEntity(char ch)
+        {
+            string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo);
+
+            if (checkCharacters && !xmlCharType.IsCharData(ch))
+            {
+                // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char
+                throw XmlConvert.CreateInvalidCharException(ch, '\0');
+            }<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x';
+            RawText(strVal);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+
+            if (bufPos > bufLen)
+            {
+                FlushBuffer();
+            }
+
+            textPos = bufPos;
+        }
+
+        // Serialize a whitespace node.
+
+        public override unsafe void WriteWhitespace(string ws)
+        {
+            Debug.Assert(ws != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            fixed (char* pSrc = ws)
+            {
+                char* pSrcEnd = pSrc + ws.Length;
+                if (inAttributeValue)
+                {
+                    WriteAttributeTextBlock(pSrc, pSrcEnd);
+                }
+                else
+                {
+                    WriteElementTextBlock(pSrc, pSrcEnd);
+                }
+            }
+        }
+
+        // Serialize either attribute or element text using XML rules.
+
+        public override unsafe void WriteString(string text)
+        {
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, true) #>
+
+            fixed (char* pSrc = text)
+            {
+                char* pSrcEnd = pSrc + text.Length;
+                if (inAttributeValue)
+                {
+                    WriteAttributeTextBlock(pSrc, pSrcEnd);
+                }
+                else
+                {
+                    WriteElementTextBlock(pSrc, pSrcEnd);
+                }
+            }
+        }
+
+        // Serialize surrogate character entity.
+        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
+        {<#
+#><#= SetTextContentMark(3, 1, false) #>
+            int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar);
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x';
+            RawText(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo));
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+            textPos = bufPos;
+        }
+
+        // Serialize either attribute or element text using XML rules.
+        // Arguments are validated in the XmlWellformedWriter layer.
+
+        public override unsafe void WriteChars(char[] buffer, int index, int count)
+        {
+            Debug.Assert(buffer != null);
+            Debug.Assert(index >= 0);
+            Debug.Assert(count >= 0 && index + count <= buffer.Length);<#
+
+#><#= SetTextContentMark(3, true) #>
+
+            fixed (char* pSrcBegin = &buffer[index])
+            {
+                if (inAttributeValue)
+                {
+                    WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count);
+                }
+                else
+                {
+                    WriteElementTextBlock(pSrcBegin, pSrcBegin + count);
+                }
+            }
+        }
+
+        // Serialize raw data.
+        // Arguments are validated in the XmlWellformedWriter layer
+
+        public override unsafe void WriteRaw(char[] buffer, int index, int count)
+        {
+            Debug.Assert(buffer != null);
+            Debug.Assert(index >= 0);
+            Debug.Assert(count >= 0 && index + count <= buffer.Length);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            fixed (char* pSrcBegin = &buffer[index])
+            {
+                WriteRawWithCharChecking(pSrcBegin, pSrcBegin + count);
+            }
+
+            textPos = bufPos;
+        }
+
+        // Serialize raw data.
+
+        public override unsafe void WriteRaw(string data)
+        {
+            Debug.Assert(data != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            fixed (char* pSrcBegin = data)
+            {
+                WriteRawWithCharChecking(pSrcBegin, pSrcBegin + data.Length);
+            }
+
+            textPos = bufPos;
+        }
+
+        // Flush all bytes in the buffer to output and close the output stream or writer.
+        public override void Close()
+        {
+            try
+            {
+                FlushBuffer();
+                FlushEncoder();
+            }
+            finally
+            {
+                // Future calls to Close or Flush shouldn't write to Stream or Writer
+                writeToNull = true;
+
+                if (stream != null)
+                {
+                    try
+                    {
+                        stream.Flush();
+                    }
+                    finally
+                    {
+                        try
+                        {
+                            if (closeOutput)
+                            {
+                                stream.Dispose();
+                            }
+                        }
+                        finally
+                        {
+                            stream = null;
+                        }
+                    }
+                }
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+                else if (writer != null)
+                {
+                    try
+                    {
+                        writer.Flush();
+                    }
+                    finally
+                    {
+                        try
+                        {
+                            if (closeOutput)
+                            {
+                                writer.Dispose();
+                            }
+                        }
+                        finally
+                        {
+                            writer = null;
+                        }
+                    }
+                }
+<# } #>
+            }
+        }
+
+        // Flush all characters in the buffer to output and call Flush() on the output object.
+        public override void Flush()
+        {
+            FlushBuffer();
+            FlushEncoder();
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+            if (stream != null)
+            {
+                stream.Flush();
+            }
+<# } else { #>
+            if (stream != null)
+            {
+                stream.Flush();
+            }
+            else if (writer != null)
+            {
+                writer.Flush();
+            }
+<# } #>
+        }
+
+        //
+        // Implementation methods
+        //
+        // Flush all characters in the buffer to output.  Do not flush the output object.
+        protected virtual void FlushBuffer()
+        {
+            try
+            {
+                // Output all characters (except for previous characters stored at beginning of buffer)
+                if (!writeToNull)
+                {
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    Debug.Assert(stream != null);
+                    stream.Write(<#= BufferName #>, 1, bufPos - 1);
+<# } else { #>
+                    Debug.Assert(stream != null || writer != null);
+
+                    if (stream != null)
+                    {
+                        if (trackTextContent)
+                        {
+                            _charEntityFallback.Reset(_textContentMarks, _lastMarkPos);
+                            // reset text content tracking
+
+                            if ((_lastMarkPos & 1) != 0)
+                            {
+                                // If the previous buffer ended inside a text content we need to preserve that info
+                                //   which means the next index to which we write has to be even
+                                _textContentMarks[1] = 1;
+                                _lastMarkPos = 1;
+                            }
+                            else
+                            {
+                                _lastMarkPos = 0;
+                            }
+                            Debug.Assert(_textContentMarks[0] == 1);
+                        }
+                        EncodeChars(1, bufPos, true);
+                    }
+                    else
+                    {
+                        // Write text to TextWriter
+                        writer.Write(<#= BufferName #>, 1, bufPos - 1);
+                    }
+<# } #>
+                }
+            }
+            catch
+            {
+                // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream
+                writeToNull = true;
+                throw;
+            }
+            finally
+            {
+                // Move last buffer character to the beginning of the buffer (so that previous character can always be determined)
+                <#= BufferName #>[0] = <#= BufferName #>[bufPos - 1];
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                if (IsSurrogateByte(<#= BufferName #>[0]))
+                {
+                    // Last character was the first byte in a surrogate encoding, so move last three
+                    // bytes of encoding to the beginning of the buffer.
+                    <#= BufferName #>[1] = <#= BufferName #>[bufPos];
+                    <#= BufferName #>[2] = <#= BufferName #>[bufPos + 1];
+                    <#= BufferName #>[3] = <#= BufferName #>[bufPos + 2];
+                }
+<# } #>
+
+                // Reset buffer position
+                textPos = (textPos == bufPos) ? 1 : 0;
+                attrEndPos = (attrEndPos == bufPos) ? 1 : 0;
+                contentPos = 0;    // Needs to be zero, since overwriting '>' character is no longer possible
+                cdataPos = 0;      // Needs to be zero, since overwriting ']]>' characters is no longer possible
+                bufPos = 1;        // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
+                                   // close an empty element or in CDATA section detection of double ]; <#= BufferName #>[0] will always be 0
+            }
+        }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+        private void FlushEncoder()
+        {
+            // intentionally empty
+
+        }
+<# } else { #>
+        private void EncodeChars(int startOffset, int endOffset, bool writeAllToStream)
+        {
+            // Write encoded text to stream
+            int chEnc;
+            int bEnc;
+            bool completed;
+            while (startOffset < endOffset)
+            {
+                if (_charEntityFallback != null)
+                {
+                    _charEntityFallback.StartOffset = startOffset;
+                }
+                encoder.Convert(<#= BufferName #>, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed);
+                startOffset += chEnc;
+                bufBytesUsed += bEnc;
+                if (bufBytesUsed >= (bufBytes.Length - 16))
+                {
+                    stream.Write(bufBytes, 0, bufBytesUsed);
+                    bufBytesUsed = 0;
+                }
+            }
+            if (writeAllToStream && bufBytesUsed > 0)
+            {
+                stream.Write(bufBytes, 0, bufBytesUsed);
+                bufBytesUsed = 0;
+            }
+        }
+
+        private void FlushEncoder()
+        {
+            Debug.Assert(bufPos == 1);
+            if (stream != null)
+            {
+                int chEnc;
+                int bEnc;
+                bool completed;
+                // decode no chars, just flush
+                encoder.Convert(<#= BufferName #>, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed);
+                if (bEnc != 0)
+                {
+                    stream.Write(bufBytes, 0, bEnc);
+                }
+            }
+        }
+<# } #>
+
+        // Serialize text that is part of an attribute value.  The '&', '<', '>', and '"' characters
+        // are entitized.
+        protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd)
+        {
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // some character needs to be escaped
+                    switch (ch)
+                    {
+                        case '&':
+                            pDst = AmpEntity(pDst);
+                            break;
+                        case '<':
+                            pDst = LtEntity(pDst);
+                            break;
+                        case '>':
+                            pDst = GtEntity(pDst);
+                            break;
+                        case '"':
+                            pDst = QuoteEntity(pDst);
+                            break;
+                        case '\'':
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        case (char)0x9:
+                            if (newLineHandling == NewLineHandling.None)
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            else
+                            {
+                                // escape tab in attributes
+                                pDst = TabEntity(pDst);
+                            }
+                            break;
+                        case (char)0xD:
+                            if (newLineHandling == NewLineHandling.None)
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            else
+                            {
+                                // escape new lines in attributes
+                                pDst = CarriageReturnEntity(pDst);
+                            }
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.None)
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            else
+                            {
+                                // escape new lines in attributes
+                                pDst = LineFeedEntity(pDst);
+                            }
+                            break;
+                        default:
+<#= EncodeChar(7, true) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+        // Serialize text that is part of element content.  The '&', '<', and '>' characters
+        // are entitized.
+        protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd)
+        {
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // some character needs to be escaped
+                    switch (ch)
+                    {
+                        case '&':
+                            pDst = AmpEntity(pDst);
+                            break;
+                        case '<':
+                            pDst = LtEntity(pDst);
+                            break;
+                        case '>':
+                            pDst = GtEntity(pDst);
+                            break;
+                        case '"':
+                        case '\'':
+                        case (char)0x9:
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case (char)0xD:
+                            switch (newLineHandling)
+                            {
+                                case NewLineHandling.Replace:
+                                    // Replace "\r\n", or "\r" with NewLineChars
+                                    if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                    {
+                                        pSrc++;
+                                    }
+
+                                    pDst = WriteNewLine(pDst);
+                                    break;
+
+                                case NewLineHandling.Entitize:
+                                    // Entitize 0xD
+                                    pDst = CarriageReturnEntity(pDst);
+                                    break;
+                                case NewLineHandling.None:
+                                    *pDst = (<#= BufferType #>)ch;
+                                    pDst++;
+                                    break;
+                            }
+                            break;
+                        default:
+<#= EncodeChar(7, true) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+                textPos = bufPos;
+                contentPos = 0;
+            }
+        }
+
+        protected unsafe void RawText(string s)
+        {
+            Debug.Assert(s != null);
+
+            fixed (char* pSrcBegin = s)
+            {
+                RawText(pSrcBegin, pSrcBegin + s.Length);
+            }
+        }
+
+        protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd)
+        {
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+                char* pSrc = pSrcBegin;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && ((ch = *pSrc) <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && ((ch = *pSrc) < XmlCharType.SurHighStart))
+<# } #>
+                    {
+                        pSrc++;
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+<#= EncodeChar(5, false) #>
+                }
+
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+        protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd)
+        {
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                char* pSrc = pSrcBegin;
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsTextChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // handle special characters
+                    switch (ch)
+                    {
+                        case ']':
+                        case '<':
+                        case '&':
+                        case (char)0x9:
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        case (char)0xD:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                // Normalize "\r\n", or "\r" to NewLineChars
+                                if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                {
+                                    pSrc++;
+                                }
+
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        default:
+<#= EncodeChar(7, false) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+        protected unsafe void WriteCommentOrPi(string text, int stopChar)
+        {
+            if (text.Length == 0)
+            {
+                if (bufPos >= bufLen)
+                {
+                    FlushBuffer();
+                }
+                return;
+            }
+            // write text
+            fixed (char* pSrcBegin = text)
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                char* pSrc = pSrcBegin;
+
+                char* pSrcEnd = pSrcBegin + text.Length;
+
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // handle special characters
+                    switch (ch)
+                    {
+                        case '-':
+                            *pDst = (<#= BufferType #>)'-';
+                            pDst++;
+                            if (ch == stopChar)
+                            {
+                                // Insert space between adjacent dashes or before comment's end dashes
+                                if (pSrc + 1 == pSrcEnd || *(pSrc + 1) == '-')
+                                {
+                                    *pDst = (<#= BufferType #>)' ';
+                                    pDst++;
+                                }
+                            }
+                            break;
+                        case '?':
+                            *pDst = (<#= BufferType #>)'?';
+                            pDst++;
+                            if (ch == stopChar)
+                            {
+                                // Processing instruction: insert space between adjacent '?' and '>'
+                                if (pSrc + 1 < pSrcEnd && *(pSrc + 1) == '>')
+                                {
+                                    *pDst = (<#= BufferType #>)' ';
+                                    pDst++;
+                                }
+                            }
+                            break;
+                        case ']':
+                            *pDst = (<#= BufferType #>)']';
+                            pDst++;
+                            break;
+                        case (char)0xD:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                // Normalize "\r\n", or "\r" to NewLineChars
+                                if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                {
+                                    pSrc++;
+                                }
+
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case '<':
+                        case '&':
+                        case (char)0x9:
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        default:
+<#= EncodeChar(7, false) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+        protected unsafe void WriteCDataSection(string text)
+        {
+            if (text.Length == 0)
+            {
+                if (bufPos >= bufLen)
+                {
+                    FlushBuffer();
+                }
+                return;
+            }
+
+            // write text
+
+            fixed (char* pSrcBegin = text)
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                char* pSrc = pSrcBegin;
+
+                char* pSrcEnd = pSrcBegin + text.Length;
+
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']'))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        FlushBuffer();
+                        pDst = pDstBegin + 1;
+                        continue;
+                    }
+
+                    // handle special characters
+                    switch (ch)
+                    {
+                        case '>':
+                            if (hadDoubleBracket && pDst[-1] == (<#= BufferType #>)']')
+                            {   // pDst[-1] will always correct - there is a padding character at <#= BufferName #>[0]
+                                // The characters "]]>" were found within the CData text
+                                pDst = RawEndCData(pDst);
+                                pDst = RawStartCData(pDst);
+                            }
+                            *pDst = (<#= BufferType #>)'>';
+                            pDst++;
+                            break;
+                        case ']':
+                            if (pDst[-1] == (<#= BufferType #>)']')
+                            {   // pDst[-1] will always correct - there is a padding character at <#= BufferName #>[0]
+                                hadDoubleBracket = true;
+                            }
+                            else
+                            {
+                                hadDoubleBracket = false;
+                            }
+                            *pDst = (<#= BufferType #>)']';
+                            pDst++;
+                            break;
+                        case (char)0xD:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                // Normalize "\r\n", or "\r" to NewLineChars
+                                if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                {
+                                    pSrc++;
+                                }
+
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                pDst = WriteNewLine(pDst);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case '&':
+                        case '<':
+                        case '"':
+                        case '\'':
+                        case (char)0x9:
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        default:
+<#= EncodeChar(7, false) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+        }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+        // Returns true if UTF8 encoded byte is first of four bytes that encode a surrogate pair.
+        // To do this, detect the bit pattern 11110xxx.
+        private static bool IsSurrogateByte(byte b)
+        {
+            return (b & 0xF8) == 0xF0;
+        }
+<# } #>
+
+        private static unsafe <#= BufferType #>* EncodeSurrogate(char* pSrc, char* pSrcEnd, <#= BufferType #>* pDst)
+        {
+            Debug.Assert(XmlCharType.IsSurrogate(*pSrc));
+
+            int ch = *pSrc;
+            if (ch <= XmlCharType.SurHighEnd)
+            {
+                if (pSrc + 1 < pSrcEnd)
+                {
+                    int lowChar = pSrc[1];
+                    if (lowChar >= XmlCharType.SurLowStart &&
+                        (LocalAppContextSwitches.DontThrowOnInvalidSurrogatePairs || lowChar <= XmlCharType.SurLowEnd))
+                    {
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                        // Calculate Unicode scalar value for easier manipulations (see section 3.7 in Unicode spec)
+                        // The scalar value repositions surrogate values to start at 0x10000.
+
+                        ch = XmlCharType.CombineSurrogateChar(lowChar, ch);
+
+                        pDst[0] = (byte)(0xF0 | (ch >> 18));
+                        pDst[1] = (byte)(0x80 | (ch >> 12) & 0x3F);
+                        pDst[2] = (byte)(0x80 | (ch >> 6) & 0x3F);
+                        pDst[3] = (byte)(0x80 | ch & 0x3F);
+                        pDst += 4;
+<# } else { #>
+                        pDst[0] = (<#= BufferType #>)ch;
+                        pDst[1] = (<#= BufferType #>)lowChar;
+                        pDst += 2;
+<# } #>
+
+                        return pDst;
+                    }
+                    throw XmlConvert.CreateInvalidSurrogatePairException((char)lowChar, (char)ch);
+                }
+                throw new ArgumentException(SR.Xml_InvalidSurrogateMissingLowChar);
+            }
+            throw XmlConvert.CreateInvalidHighSurrogateCharException((char)ch);
+        }
+
+        private unsafe <#= BufferType #>* InvalidXmlChar(int ch, <#= BufferType #>* pDst, bool entitize)
+        {
+            Debug.Assert(!xmlCharType.IsWhiteSpace((char)ch));
+            Debug.Assert(!xmlCharType.IsAttributeValueChar((char)ch));
+
+            if (checkCharacters)
+            {
+                // This method will never be called on surrogates, so it is ok to pass in '\0' to the CreateInvalidCharException
+                throw XmlConvert.CreateInvalidCharException((char)ch, '\0');
+            }
+            else
+            {
+                if (entitize)
+                {
+                    return CharEntity(pDst, (char)ch);
+                }
+                else
+                {
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    if (ch < 0x80)
+                    {
+<# } #>
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    }
+                    else
+                    {
+                        pDst = EncodeMultibyteUTF8(ch, pDst);
+                    }
+<# } #>
+                    return pDst;
+                }
+            }
+        }
+
+        internal unsafe void EncodeChar(ref char* pSrc, char* pSrcEnd, ref <#= BufferType #>* pDst)
+        {
+            int ch = *pSrc;
+<#= EncodeChar(3, false) #>
+        }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+        internal static unsafe byte* EncodeMultibyteUTF8(int ch, byte* pDst)
+        {
+            Debug.Assert(ch >= 0x80 && !XmlCharType.IsSurrogate(ch));
+
+            unchecked
+            {
+                /* UTF8-2: If ch is in 0x80-0x7ff range, then use 2 bytes to encode it */
+                if (ch < 0x800)
+                {
+                    *pDst = (byte)((sbyte)0xC0 | (ch >> 6));
+                }
+                /* UTF8-3: If ch is anything else, then default to using 3 bytes to encode it. */
+                else
+                {
+                    *pDst = (byte)((sbyte)0xE0 | (ch >> 12));
+                    pDst++;
+
+                    *pDst = (byte)((sbyte)0x80 | (ch >> 6) & 0x3F);
+                }
+            }
+
+            pDst++;
+            *pDst = (byte)(0x80 | ch & 0x3F);
+            return pDst + 1;
+        }
+
+        // Encode *pSrc as a sequence of UTF8 bytes.  Write the bytes to pDst and return an updated pointer.
+
+        internal static unsafe void CharToUTF8(ref char* pSrc, char* pSrcEnd, ref byte* pDst)
+        {
+            int ch = *pSrc;
+            if (ch <= 0x7F)
+            {
+                *pDst = (byte)ch;
+                pDst++;
+                pSrc++;
+            }
+            else if (XmlCharType.IsSurrogate(ch))
+            {
+                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                pSrc += 2;
+            }
+            else
+            {
+                pDst = EncodeMultibyteUTF8(ch, pDst);
+                pSrc++;
+            }
+        }
+<# } #>
+
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+        protected void ChangeTextContentMark(bool value)
+        {
+            Debug.Assert(inTextContent != value);
+            Debug.Assert(inTextContent || ((_lastMarkPos & 1) == 0));
+            inTextContent = value;
+            if (_lastMarkPos + 1 == _textContentMarks.Length)
+            {
+                GrowTextContentMarks();
+            }
+            _textContentMarks[++_lastMarkPos] = bufPos;
+        }
+
+        private void GrowTextContentMarks()
+        {
+            Debug.Assert(_lastMarkPos + 1 == _textContentMarks.Length);
+            int[] newTextContentMarks = new int[_textContentMarks.Length * 2];
+            Array.Copy(_textContentMarks, newTextContentMarks, _textContentMarks.Length);
+            _textContentMarks = newTextContentMarks;
+        }
+<# } #>
+        // Write NewLineChars to the specified buffer position and return an updated position.
+        protected unsafe <#= BufferType #>* WriteNewLine(<#= BufferType #>* pDst)
+        {
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                bufPos = (int)(pDst - pDstBegin);
+                // Let RawText do the real work
+                RawText(newLineChars);
+                return pDstBegin + bufPos;
+            }
+        }
+
+        // Following methods do not check whether pDst is beyond the bufSize because the buffer was allocated with a OVERFLOW to accommodate
+        // for the writes of small constant-length string as below.
+
+        // Entitize '<' as "&lt;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* LtEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'l';
+            pDst[2] = (<#= BufferType #>)'t';
+            pDst[3] = (<#= BufferType #>)';';
+            return pDst + 4;
+        }
+
+        // Entitize '>' as "&gt;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* GtEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'g';
+            pDst[2] = (<#= BufferType #>)'t';
+            pDst[3] = (<#= BufferType #>)';';
+            return pDst + 4;
+        }
+
+        // Entitize '&' as "&amp;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* AmpEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'a';
+            pDst[2] = (<#= BufferType #>)'m';
+            pDst[3] = (<#= BufferType #>)'p';
+            pDst[4] = (<#= BufferType #>)';';
+            return pDst + 5;
+        }
+
+        // Entitize '"' as "&quot;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* QuoteEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'q';
+            pDst[2] = (<#= BufferType #>)'u';
+            pDst[3] = (<#= BufferType #>)'o';
+            pDst[4] = (<#= BufferType #>)'t';
+            pDst[5] = (<#= BufferType #>)';';
+            return pDst + 6;
+        }
+
+        // Entitize '\t' as "&#x9;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* TabEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'#';
+            pDst[2] = (<#= BufferType #>)'x';
+            pDst[3] = (<#= BufferType #>)'9';
+            pDst[4] = (<#= BufferType #>)';';
+            return pDst + 5;
+        }
+
+        // Entitize 0xa as "&#xA;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* LineFeedEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'#';
+            pDst[2] = (<#= BufferType #>)'x';
+            pDst[3] = (<#= BufferType #>)'A';
+            pDst[4] = (<#= BufferType #>)';';
+            return pDst + 5;
+        }
+
+        // Entitize 0xd as "&#xD;".  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* CarriageReturnEntity(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'#';
+            pDst[2] = (<#= BufferType #>)'x';
+            pDst[3] = (<#= BufferType #>)'D';
+            pDst[4] = (<#= BufferType #>)';';
+            return pDst + 5;
+        }
+
+        private static unsafe <#= BufferType #>* CharEntity(<#= BufferType #>* pDst, char ch)
+        {
+            string s = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo);
+            pDst[0] = (<#= BufferType #>)'&';
+            pDst[1] = (<#= BufferType #>)'#';
+            pDst[2] = (<#= BufferType #>)'x';
+            pDst += 3;
+
+            fixed (char* pSrc = s)
+            {
+                char* pS = pSrc;
+                while ((*pDst++ = (<#= BufferType #>)*pS++) != 0) ;
+            }
+
+            pDst[-1] = (<#= BufferType #>)';';
+            return pDst;
+        }
+
+        // Write "<![CDATA[" to the specified buffer.  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* RawStartCData(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)'<';
+            pDst[1] = (<#= BufferType #>)'!';
+            pDst[2] = (<#= BufferType #>)'[';
+            pDst[3] = (<#= BufferType #>)'C';
+            pDst[4] = (<#= BufferType #>)'D';
+            pDst[5] = (<#= BufferType #>)'A';
+            pDst[6] = (<#= BufferType #>)'T';
+            pDst[7] = (<#= BufferType #>)'A';
+            pDst[8] = (<#= BufferType #>)'[';
+            return pDst + 9;
+        }
+
+        // Write "]]>" to the specified buffer.  Return an updated pointer.
+
+        protected static unsafe <#= BufferType #>* RawEndCData(<#= BufferType #>* pDst)
+        {
+            pDst[0] = (<#= BufferType #>)']';
+            pDst[1] = (<#= BufferType #>)']';
+            pDst[2] = (<#= BufferType #>)'>';
+            return pDst + 3;
+        }
+
+        protected unsafe void ValidateContentChars(string chars, string propertyName, bool allowOnlyWhitespace)
+        {
+            if (allowOnlyWhitespace)
+            {
+                if (!xmlCharType.IsOnlyWhitespace(chars))
+                {
+                    throw new ArgumentException(SR.Format(SR.Xml_IndentCharsNotWhitespace, propertyName));
+                }
+            }
+            else
+            {
+                string error = null;
+                for (int i = 0; i < chars.Length; i++)
+                {
+                    if (!xmlCharType.IsTextChar(chars[i]))
+                    {
+                        switch (chars[i])
+                        {
+                            case '\n':
+                            case '\r':
+                            case '\t':
+                                continue;
+                            case '<':
+                            case '&':
+                            case ']':
+                                error = SR.Format(SR.Xml_InvalidCharacter, XmlException.BuildCharExceptionArgs(chars, i));
+                                goto Error;
+                            default:
+                                if (XmlCharType.IsHighSurrogate(chars[i]))
+                                {
+                                    if (i + 1 < chars.Length)
+                                    {
+                                        if (XmlCharType.IsLowSurrogate(chars[i + 1]))
+                                        {
+                                            i++;
+                                            continue;
+                                        }
+                                    }
+                                    error = SR.Xml_InvalidSurrogateMissingLowChar;
+                                    goto Error;
+                                }
+                                else if (XmlCharType.IsLowSurrogate(chars[i]))
+                                {
+                                    error = SR.Format(SR.Xml_InvalidSurrogateHighChar, ((uint)chars[i]).ToString("X", CultureInfo.InvariantCulture));
+                                    goto Error;
+                                }
+                                continue;
+                        }
+                    }
+                }
+                return;
+
+            Error:
+                throw new ArgumentException(SR.Format(SR.Xml_InvalidCharsInIndent, new string[] { propertyName, error }));
+            }
+        }
+    }
+
+    // Same as base text writer class except that elements, attributes, comments, and pi's are indented.
+    internal partial class <#= ClassNameIndent #> : <#= ClassName #>
+    {
+        //
+        // Fields
+        //
+        protected int indentLevel;
+        protected bool newLineOnAttributes;
+        protected string indentChars;
+
+        protected bool mixedContent;
+        private BitStack _mixedContentStack;
+
+        protected ConformanceLevel conformanceLevel = ConformanceLevel.Auto;
+
+        //
+        // Constructors
+        //
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+
+        public <#= ClassNameIndent #>(TextWriter writer, XmlWriterSettings settings) : base(writer, settings)
+        {
+            Init(settings);
+        }
+<# } #>
+
+        public <#= ClassNameIndent #>(Stream stream, XmlWriterSettings settings) : base(stream, settings)
+        {
+            Init(settings);
+        }
+
+        //
+        // XmlWriter methods
+        //
+        public override XmlWriterSettings Settings
+        {
+            get
+            {
+                XmlWriterSettings settings = base.Settings;
+
+                settings.ReadOnly = false;
+                settings.Indent = true;
+                settings.IndentChars = indentChars;
+                settings.NewLineOnAttributes = newLineOnAttributes;
+                settings.ReadOnly = true;
+
+                return settings;
+            }
+        }
+
+        public override void WriteDocType(string name, string pubid, string sysid, string subset)
+        {
+            // Add indentation
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                WriteIndent();
+            }
+            base.WriteDocType(name, pubid, sysid, subset);
+        }
+
+        public override void WriteStartElement(string prefix, string localName, string ns)
+        {
+            Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);
+
+            // Add indentation
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                WriteIndent();
+            }
+            indentLevel++;
+            _mixedContentStack.PushBit(mixedContent);
+
+            base.WriteStartElement(prefix, localName, ns);
+        }
+
+        internal override void StartElementContent()
+        {
+            // If this is the root element and we're writing a document
+            //   do not inherit the mixedContent flag into the root element.
+            //   This is to allow for whitespace nodes on root level
+            //   without disabling indentation for the whole document.
+            if (indentLevel == 1 && conformanceLevel == ConformanceLevel.Document)
+            {
+                mixedContent = false;
+            }
+            else
+            {
+                mixedContent = _mixedContentStack.PeekBit();
+            }
+            base.StartElementContent();
+        }
+
+        internal override void OnRootElement(ConformanceLevel currentConformanceLevel)
+        {
+            // Just remember the current conformance level
+            conformanceLevel = currentConformanceLevel;
+        }
+
+        internal override void WriteEndElement(string prefix, string localName, string ns)
+        {
+            // Add indentation
+            indentLevel--;
+            if (!mixedContent && base.contentPos != base.bufPos)
+            {
+                // There was content, so try to indent
+                if (base.textPos != base.bufPos)
+                {
+                    WriteIndent();
+                }
+            }
+            mixedContent = _mixedContentStack.PopBit();
+
+            base.WriteEndElement(prefix, localName, ns);
+        }
+
+        internal override void WriteFullEndElement(string prefix, string localName, string ns)
+        {
+            // Add indentation
+            indentLevel--;
+            if (!mixedContent && base.contentPos != base.bufPos)
+            {
+                // There was content, so try to indent
+                if (base.textPos != base.bufPos)
+                {
+                    WriteIndent();
+                }
+            }
+            mixedContent = _mixedContentStack.PopBit();
+
+            base.WriteFullEndElement(prefix, localName, ns);
+        }
+
+        // Same as base class, plus possible indentation.
+        public override void WriteStartAttribute(string prefix, string localName, string ns)
+        {
+            // Add indentation
+            if (newLineOnAttributes)
+            {
+                WriteIndent();
+            }
+
+            base.WriteStartAttribute(prefix, localName, ns);
+        }
+
+        public override void WriteCData(string text)
+        {
+            mixedContent = true;
+            base.WriteCData(text);
+        }
+
+        public override void WriteComment(string text)
+        {
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                WriteIndent();
+            }
+
+            base.WriteComment(text);
+        }
+
+        public override void WriteProcessingInstruction(string target, string text)
+        {
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                WriteIndent();
+            }
+
+            base.WriteProcessingInstruction(target, text);
+        }
+
+        public override void WriteEntityRef(string name)
+        {
+            mixedContent = true;
+            base.WriteEntityRef(name);
+        }
+
+        public override void WriteCharEntity(char ch)
+        {
+            mixedContent = true;
+            base.WriteCharEntity(ch);
+        }
+
+        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
+        {
+            mixedContent = true;
+            base.WriteSurrogateCharEntity(lowChar, highChar);
+        }
+
+        public override void WriteWhitespace(string ws)
+        {
+            mixedContent = true;
+            base.WriteWhitespace(ws);
+        }
+
+        public override void WriteString(string text)
+        {
+            mixedContent = true;
+            base.WriteString(text);
+        }
+
+        public override void WriteChars(char[] buffer, int index, int count)
+        {
+            mixedContent = true;
+            base.WriteChars(buffer, index, count);
+        }
+
+        public override void WriteRaw(char[] buffer, int index, int count)
+        {
+            mixedContent = true;
+            base.WriteRaw(buffer, index, count);
+        }
+
+        public override void WriteRaw(string data)
+        {
+            mixedContent = true;
+            base.WriteRaw(data);
+        }
+
+        public override void WriteBase64(byte[] buffer, int index, int count)
+        {
+            mixedContent = true;
+            base.WriteBase64(buffer, index, count);
+        }
+
+        //
+        // Private methods
+        //
+        private void Init(XmlWriterSettings settings)
+        {
+            indentLevel = 0;
+            indentChars = settings.IndentChars;
+            newLineOnAttributes = settings.NewLineOnAttributes;
+            _mixedContentStack = new BitStack();
+
+            // check indent characters that they are valid XML characters
+            if (base.checkCharacters)
+            {
+                if (newLineOnAttributes)
+                {
+                    base.ValidateContentChars(indentChars, "IndentChars", true);
+                    base.ValidateContentChars(newLineChars, "NewLineChars", true);
+                }
+                else
+                {
+                    base.ValidateContentChars(indentChars, "IndentChars", false);
+                    if (base.newLineHandling != NewLineHandling.Replace)
+                    {
+                        base.ValidateContentChars(newLineChars, "NewLineChars", false);
+                    }
+                }
+            }
+        }
+
+        // Add indentation to output.  Write newline and then repeat IndentChars for each indent level.
+        private void WriteIndent()
+        {
+            RawText(base.newLineChars);
+            for (int i = indentLevel; i > 0; i--)
+            {
+                RawText(indentChars);
+            }
+        }
+    }
+}
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude
new file mode 100644 (file)
index 0000000..772a269
--- /dev/null
@@ -0,0 +1,1961 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriter.ttinclude" #>// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify XmlRawTextWriterGeneratorAsync.ttinclude
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Text;
+using System.Diagnostics;
+using System.Globalization;
+using System.Security;
+using System.Threading.Tasks;
+
+namespace System.Xml
+{
+    // Concrete implementation of XmlWriter abstract class that serializes events as encoded XML
+    // text.  The general-purpose XmlEncodedTextWriter uses the Encoder class to output to any
+    // encoding.  The XmlUtf8TextWriter class combined the encoding operation with serialization
+    // in order to achieve better performance.
+    internal partial class <#= ClassName #> : XmlRawWriter
+    {
+        protected void CheckAsyncCall()
+        {
+            if (!_useAsync)
+            {
+                throw new InvalidOperationException(SR.Xml_WriterAsyncNotSetException);
+            }
+        }
+
+        // Write the xml declaration.  This must be the first call.
+        internal override async Task WriteXmlDeclarationAsync(XmlStandalone standalone)
+        {
+            CheckAsyncCall();
+            // Output xml declaration only if user allows it and it was not already output
+            if (!omitXmlDeclaration && !autoXmlDeclaration)
+            {<# /* Code block is to squash extra line. */
+#><#= SetTextContentMark(4, 1, false) #>
+                await RawTextAsync("<?xml version=\"").ConfigureAwait(false);
+
+                // Version
+                await RawTextAsync("1.0").ConfigureAwait(false);
+
+                // Encoding
+                if (encoding != null)
+                {
+                    await RawTextAsync("\" encoding=\"").ConfigureAwait(false);
+                    await RawTextAsync(encoding.WebName).ConfigureAwait(false);
+                }
+
+                // Standalone
+                if (standalone != XmlStandalone.Omit)
+                {
+                    await RawTextAsync("\" standalone=\"").ConfigureAwait(false);
+                    await RawTextAsync(standalone == XmlStandalone.Yes ? "yes" : "no").ConfigureAwait(false);
+                }
+
+                await RawTextAsync("\"?>").ConfigureAwait(false);
+            }
+        }
+
+        internal override Task WriteXmlDeclarationAsync(string xmldecl)
+        {
+            CheckAsyncCall();
+            // Output xml declaration only if user allows it and it was not already output
+            if (!omitXmlDeclaration && !autoXmlDeclaration)
+            {
+                return WriteProcessingInstructionAsync("xml", xmldecl);
+            }
+
+            return Task.CompletedTask;
+        }
+
+        // Serialize the document type declaration.
+        public override async Task WriteDocTypeAsync(string name, string pubid, string sysid, string subset)
+        {
+            CheckAsyncCall();
+            Debug.Assert(name != null && name.Length > 0);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            await RawTextAsync("<!DOCTYPE ").ConfigureAwait(false);
+            await RawTextAsync(name).ConfigureAwait(false);
+            if (pubid != null)
+            {
+                await RawTextAsync(" PUBLIC \"").ConfigureAwait(false);
+                await RawTextAsync(pubid).ConfigureAwait(false);
+                await RawTextAsync("\" \"").ConfigureAwait(false);
+                if (sysid != null)
+                {
+                    await RawTextAsync(sysid).ConfigureAwait(false);
+                }
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else if (sysid != null)
+            {
+                await RawTextAsync(" SYSTEM \"").ConfigureAwait(false);
+                await RawTextAsync(sysid).ConfigureAwait(false);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+            else
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+            }
+
+            if (subset != null)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+                await RawTextAsync(subset).ConfigureAwait(false);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            }
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize the beginning of an element start tag: "<prefix:localName"
+        public override Task WriteStartElementAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            Task task;
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            if (prefix != null && prefix.Length != 0)
+            {
+                task = RawTextAsync(prefix, ":", localName);
+            }
+            else
+            {
+                task = RawTextAsync(localName);
+            }
+            return task.CallVoidFuncWhenFinishAsync(thisRef => thisRef.WriteStartElementAsync_SetAttEndPos(), this);
+        }
+
+        private void WriteStartElementAsync_SetAttEndPos()
+        {
+            attrEndPos = bufPos;
+        }
+
+        // Serialize an element end tag: "</prefix:localName>", if content was output.  Otherwise, serialize
+        // the shortcut syntax: " />".
+        internal override Task WriteEndElementAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (contentPos != bufPos)
+            {
+                // Content has been output, so can't use shortcut syntax
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/';
+
+                if (prefix != null && prefix.Length != 0)
+                {
+                    return RawTextAsync(prefix, ":", localName, ">");
+                }
+                else
+                {
+                    return RawTextAsync(localName, ">");
+                }
+            }
+            else
+            {
+                // Use shortcut syntax; overwrite the already output '>' character
+                bufPos--;
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+            }
+            return Task.CompletedTask;
+        }
+
+        // Serialize a full element end tag: "</prefix:localName>"
+        internal override Task WriteFullEndElementAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/';
+
+            if (prefix != null && prefix.Length != 0)
+            {
+                return RawTextAsync(prefix, ":", localName, ">");
+            }
+            else
+            {
+                return RawTextAsync(localName, ">");
+            }
+        }
+
+        // Serialize an attribute tag using double quotes around the attribute value: 'prefix:localName="'
+        protected internal override Task WriteStartAttributeAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            Debug.Assert(localName != null && localName.Length > 0);
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (attrEndPos == bufPos)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+            }
+            Task task;
+            if (prefix != null && prefix.Length > 0)
+            {
+                task = RawTextAsync(prefix, ":", localName);
+            }
+            else
+            {
+                task = RawTextAsync(localName);
+            }
+            return task.CallVoidFuncWhenFinishAsync(thisRef => thisRef.WriteStartAttribute_SetInAttribute(), this);
+        }
+
+        private void WriteStartAttribute_SetInAttribute()
+        {
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'=';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            inAttributeValue = true;
+        }
+
+        // Serialize the end of an attribute value using double quotes: '"'
+        protected internal override Task WriteEndAttributeAsync()
+        {
+            CheckAsyncCall();<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            inAttributeValue = false;
+            attrEndPos = bufPos;
+
+            return Task.CompletedTask;
+        }
+
+        internal override async Task WriteNamespaceDeclarationAsync(string prefix, string namespaceName)
+        {
+            CheckAsyncCall();
+            Debug.Assert(prefix != null && namespaceName != null);
+
+            await WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
+            await WriteStringAsync(namespaceName).ConfigureAwait(false);
+            await WriteEndNamespaceDeclarationAsync().ConfigureAwait(false);
+        }
+
+        internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
+        {
+            CheckAsyncCall();
+            Debug.Assert(prefix != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (prefix.Length == 0)
+            {
+                await RawTextAsync(" xmlns=\"").ConfigureAwait(false);
+            }
+            else
+            {
+                await RawTextAsync(" xmlns:").ConfigureAwait(false);
+                await RawTextAsync(prefix).ConfigureAwait(false);
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'=';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            }
+
+            inAttributeValue = true;<#
+#><#= SetTextContentMark(3, true) #>
+        }
+
+        internal override Task WriteEndNamespaceDeclarationAsync()
+        {
+            CheckAsyncCall();<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            inAttributeValue = false;
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"';
+            attrEndPos = bufPos;
+
+            return Task.CompletedTask;
+        }
+
+        // Serialize a CData section.  If the "]]>" pattern is found within
+        // the text, replace it with "]]><![CDATA[>".
+        public override async Task WriteCDataAsync(string text)
+        {
+            CheckAsyncCall();
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            if (mergeCDataSections && bufPos == cdataPos)
+            {
+                // Merge adjacent cdata sections - overwrite the "]]>" characters
+                Debug.Assert(bufPos >= 4);
+                bufPos -= 3;
+            }
+            else
+            {
+                // Start a new cdata section
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'C';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'D';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'T';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A';
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)'[';
+            }
+
+            await WriteCDataSectionAsync(text).ConfigureAwait(false);
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)']';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+
+            textPos = bufPos;
+            cdataPos = bufPos;
+        }
+
+        // Serialize a comment.
+        public override async Task WriteCommentAsync(string text)
+        {
+            CheckAsyncCall();
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+
+            await WriteCommentOrPiAsync(text, '-').ConfigureAwait(false);
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize a processing instruction.
+        public override async Task WriteProcessingInstructionAsync(string name, string text)
+        {
+            CheckAsyncCall();
+            Debug.Assert(name != null && name.Length > 0);
+            Debug.Assert(text != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?';
+            await RawTextAsync(name).ConfigureAwait(false);
+
+            if (text.Length > 0)
+            {
+                <#= BufferName #>[bufPos++] = (<#= BufferType #>)' ';
+                await WriteCommentOrPiAsync(text, '?').ConfigureAwait(false);
+            }
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>';
+        }
+
+        // Serialize an entity reference.
+        public override async Task WriteEntityRefAsync(string name)
+        {
+            CheckAsyncCall();
+            Debug.Assert(name != null && name.Length > 0);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&';
+            await RawTextAsync(name).ConfigureAwait(false);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+
+            if (bufPos > bufLen)
+            {
+                await FlushBufferAsync().ConfigureAwait(false);
+            }
+
+            textPos = bufPos;
+        }
+
+        // Serialize a character entity reference.
+        public override async Task WriteCharEntityAsync(char ch)
+        {
+            CheckAsyncCall();
+            string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo);
+
+            if (checkCharacters && !xmlCharType.IsCharData(ch))
+            {
+                // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char
+                throw XmlConvert.CreateInvalidCharException(ch, '\0');
+            }<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x';
+            await RawTextAsync(strVal).ConfigureAwait(false);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+
+            if (bufPos > bufLen)
+            {
+                await FlushBufferAsync().ConfigureAwait(false);
+            }
+
+            textPos = bufPos;
+        }
+
+        // Serialize a whitespace node.
+
+        public override Task WriteWhitespaceAsync(string ws)
+        {
+            CheckAsyncCall();
+            Debug.Assert(ws != null);<#
+#><#= SetTextContentMark(3, false) #>
+
+            if (inAttributeValue)
+            {
+                return WriteAttributeTextBlockAsync(ws);
+            }
+            else
+            {
+                return WriteElementTextBlockAsync(ws);
+            }
+        }
+
+        // Serialize either attribute or element text using XML rules.
+
+        public override Task WriteStringAsync(string text)
+        {
+            CheckAsyncCall();
+            Debug.Assert(text != null);<#
+#><#= SetTextContentMark(3, true) #>
+
+            if (inAttributeValue)
+            {
+                return WriteAttributeTextBlockAsync(text);
+            }
+            else
+            {
+                return WriteElementTextBlockAsync(text);
+            }
+        }
+
+        // Serialize surrogate character entity.
+        public override async Task WriteSurrogateCharEntityAsync(char lowChar, char highChar)
+        {
+            CheckAsyncCall();<#
+#><#= SetTextContentMark(3, false) #>
+
+            int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar);
+
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#';
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x';
+            await RawTextAsync(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)).ConfigureAwait(false);
+            <#= BufferName #>[bufPos++] = (<#= BufferType #>)';';
+            textPos = bufPos;
+        }
+
+        // Serialize either attribute or element text using XML rules.
+        // Arguments are validated in the XmlWellformedWriter layer.
+
+        public override Task WriteCharsAsync(char[] buffer, int index, int count)
+        {
+            CheckAsyncCall();
+            Debug.Assert(buffer != null);
+            Debug.Assert(index >= 0);
+            Debug.Assert(count >= 0 && index + count <= buffer.Length);<#
+
+#><#= SetTextContentMark(3, true) #>
+
+            if (inAttributeValue)
+            {
+                return WriteAttributeTextBlockAsync(buffer, index, count);
+            }
+            else
+            {
+                return WriteElementTextBlockAsync(buffer, index, count);
+            }
+        }
+
+        // Serialize raw data.
+        // Arguments are validated in the XmlWellformedWriter layer
+
+        public override async Task WriteRawAsync(char[] buffer, int index, int count)
+        {
+            CheckAsyncCall();
+            Debug.Assert(buffer != null);
+            Debug.Assert(index >= 0);
+            Debug.Assert(count >= 0 && index + count <= buffer.Length);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            await WriteRawWithCharCheckingAsync(buffer, index, count).ConfigureAwait(false);
+
+            textPos = bufPos;
+        }
+
+        // Serialize raw data.
+
+        public override async Task WriteRawAsync(string data)
+        {
+            CheckAsyncCall();
+            Debug.Assert(data != null);<#
+
+#><#= SetTextContentMark(3, false) #>
+
+            await WriteRawWithCharCheckingAsync(data).ConfigureAwait(false);
+
+            textPos = bufPos;
+        }
+
+        // Flush all characters in the buffer to output and call Flush() on the output object.
+        public override async Task FlushAsync()
+        {
+            CheckAsyncCall();
+            await FlushBufferAsync().ConfigureAwait(false);
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+            await FlushEncoderAsync().ConfigureAwait(false);
+<# } #>
+
+            if (stream != null)
+            {
+                await stream.FlushAsync().ConfigureAwait(false);
+            }
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+            else if (writer != null)
+            {
+                await writer.FlushAsync().ConfigureAwait(false);
+            }
+<# } #>
+        }
+
+        //
+        // Implementation methods
+        //
+        // Flush all characters in the buffer to output.  Do not flush the output object.
+        protected virtual async Task FlushBufferAsync()
+        {
+            try
+            {
+                // Output all characters (except for previous characters stored at beginning of buffer)
+                if (!writeToNull)
+                {
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    Debug.Assert(stream != null);
+                    await stream.WriteAsync(bufBytes, 1, bufPos - 1).ConfigureAwait(false);
+<# } else { #>
+                    Debug.Assert(stream != null || writer != null);
+
+                    if (stream != null)
+                    {
+                        if (trackTextContent)
+                        {
+                            _charEntityFallback.Reset(_textContentMarks, _lastMarkPos);
+                            // reset text content tracking
+
+                            if ((_lastMarkPos & 1) != 0)
+                            {
+                                // If the previous buffer ended inside a text content we need to preserve that info
+                                //   which means the next index to which we write has to be even
+                                _textContentMarks[1] = 1;
+                                _lastMarkPos = 1;
+                            }
+                            else
+                            {
+                                _lastMarkPos = 0;
+                            }
+                            Debug.Assert(_textContentMarks[0] == 1);
+                        }
+                        await EncodeCharsAsync(1, bufPos, true).ConfigureAwait(false);
+                    }
+                    else
+                    {
+                        // Write text to TextWriter
+                        await writer.WriteAsync(<#= BufferName #>, 1, bufPos - 1).ConfigureAwait(false);
+                    }
+<# } #>
+                }
+            }
+            catch
+            {
+                // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream
+                writeToNull = true;
+                throw;
+            }
+            finally
+            {
+                // Move last buffer character to the beginning of the buffer (so that previous character can always be determined)
+                <#= BufferName #>[0] = <#= BufferName #>[bufPos - 1];
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                if (IsSurrogateByte(bufBytes[0]))
+                {
+                    // Last character was the first byte in a surrogate encoding, so move last three
+                    // bytes of encoding to the beginning of the buffer.
+                    bufBytes[1] = bufBytes[bufPos];
+                    bufBytes[2] = bufBytes[bufPos + 1];
+                    bufBytes[3] = bufBytes[bufPos + 2];
+                }
+<# } #>
+
+                // Reset buffer position
+                textPos = (textPos == bufPos) ? 1 : 0;
+                attrEndPos = (attrEndPos == bufPos) ? 1 : 0;
+                contentPos = 0;    // Needs to be zero, since overwriting '>' character is no longer possible
+                cdataPos = 0;      // Needs to be zero, since overwriting ']]>' characters is no longer possible
+                bufPos = 1;        // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
+                                   // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
+            }
+        }
+<# if (WriterType == RawTextWriterType.Encoded) { #>
+        private async Task EncodeCharsAsync(int startOffset, int endOffset, bool writeAllToStream)
+        {
+            // Write encoded text to stream
+            int chEnc;
+            int bEnc;
+            bool completed;
+            while (startOffset < endOffset)
+            {
+                if (_charEntityFallback != null)
+                {
+                    _charEntityFallback.StartOffset = startOffset;
+                }
+                encoder.Convert(<#= BufferName #>, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed);
+                startOffset += chEnc;
+                bufBytesUsed += bEnc;
+                if (bufBytesUsed >= (bufBytes.Length - 16))
+                {
+                    await stream.WriteAsync(bufBytes, 0, bufBytesUsed).ConfigureAwait(false);
+                    bufBytesUsed = 0;
+                }
+            }
+            if (writeAllToStream && bufBytesUsed > 0)
+            {
+                await stream.WriteAsync(bufBytes, 0, bufBytesUsed).ConfigureAwait(false);
+                bufBytesUsed = 0;
+            }
+        }
+
+        private Task FlushEncoderAsync()
+        {
+            Debug.Assert(bufPos == 1);
+            if (stream != null)
+            {
+                int chEnc;
+                int bEnc;
+                bool completed;
+                // decode no chars, just flush
+                encoder.Convert(<#= BufferName #>, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed);
+                if (bEnc != 0)
+                {
+                    return stream.WriteAsync(bufBytes, 0, bEnc);
+                }
+            }
+
+            return Task.CompletedTask;
+        }
+<# } #>
+
+        // Serialize text that is part of an attribute value.  The '&', '<', '>', and '"' characters
+        // are entitized.
+        protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd)
+        {
+            char* pRaw = pSrc;
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        return (int)(pSrc - pRaw);
+                    }
+
+                    // some character needs to be escaped
+                    switch (ch)
+                    {
+                        case '&':
+                            pDst = AmpEntity(pDst);
+                            break;
+                        case '<':
+                            pDst = LtEntity(pDst);
+                            break;
+                        case '>':
+                            pDst = GtEntity(pDst);
+                            break;
+                        case '"':
+                            pDst = QuoteEntity(pDst);
+                            break;
+                        case '\'':
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        case (char)0x9:
+                            if (newLineHandling == NewLineHandling.None)
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            else
+                            {
+                                // escape tab in attributes
+                                pDst = TabEntity(pDst);
+                            }
+                            break;
+                        case (char)0xD:
+                            if (newLineHandling == NewLineHandling.None)
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            else
+                            {
+                                // escape new lines in attributes
+                                pDst = CarriageReturnEntity(pDst);
+                            }
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.None)
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            else
+                            {
+                                // escape new lines in attributes
+                                pDst = LineFeedEntity(pDst);
+                            }
+                            break;
+                        default:
+<#= EncodeChar(7, true) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+
+            return -1;
+        }
+
+        protected unsafe int WriteAttributeTextBlockNoFlush(char[] chars, int index, int count)
+        {
+            if (count == 0)
+            {
+                return -1;
+            }
+            fixed (char* pSrc = &chars[index])
+            {
+                char* pSrcBeg = pSrc;
+                char* pSrcEnd = pSrcBeg + count;
+                return WriteAttributeTextBlockNoFlush(pSrcBeg, pSrcEnd);
+            }
+        }
+
+        protected unsafe int WriteAttributeTextBlockNoFlush(string text, int index, int count)
+        {
+            if (count == 0)
+            {
+                return -1;
+            }
+            fixed (char* pSrc = text)
+            {
+                char* pSrcBeg = pSrc + index;
+                char* pSrcEnd = pSrcBeg + count;
+                return WriteAttributeTextBlockNoFlush(pSrcBeg, pSrcEnd);
+            }
+        }
+
+        protected async Task WriteAttributeTextBlockAsync(char[] chars, int index, int count)
+        {
+            int writeLen = 0;
+            int curIndex = index;
+            int leftCount = count;
+            do
+            {
+                writeLen = WriteAttributeTextBlockNoFlush(chars, curIndex, leftCount);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0);
+        }
+
+        protected Task WriteAttributeTextBlockAsync(string text)
+        {
+            int writeLen = 0;
+            int curIndex = 0;
+            int leftCount = text.Length;
+
+            writeLen = WriteAttributeTextBlockNoFlush(text, curIndex, leftCount);
+            curIndex += writeLen;
+            leftCount -= writeLen;
+            if (writeLen >= 0)
+            {
+                return _WriteAttributeTextBlockAsync(text, curIndex, leftCount);
+            }
+
+            return Task.CompletedTask;
+        }
+
+        private async Task _WriteAttributeTextBlockAsync(string text, int curIndex, int leftCount)
+        {
+            int writeLen;
+            await FlushBufferAsync().ConfigureAwait(false);
+            do
+            {
+                writeLen = WriteAttributeTextBlockNoFlush(text, curIndex, leftCount);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0);
+        }
+
+        // Serialize text that is part of element content.  The '&', '<', and '>' characters
+        // are entitized.
+        protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            char* pRaw = pSrc;
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        return (int)(pSrc - pRaw);
+                    }
+
+                    // some character needs to be escaped
+                    switch (ch)
+                    {
+                        case '&':
+                            pDst = AmpEntity(pDst);
+                            break;
+                        case '<':
+                            pDst = LtEntity(pDst);
+                            break;
+                        case '>':
+                            pDst = GtEntity(pDst);
+                            break;
+                        case '"':
+                        case '\'':
+                        case (char)0x9:
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                bufPos = (int)(pDst - pDstBegin);
+                                needWriteNewLine = true;
+                                return (int)(pSrc - pRaw);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case (char)0xD:
+                            switch (newLineHandling)
+                            {
+                                case NewLineHandling.Replace:
+                                    // Replace "\r\n", or "\r" with NewLineChars
+                                    if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                    {
+                                        pSrc++;
+                                    }
+
+                                    bufPos = (int)(pDst - pDstBegin);
+                                    needWriteNewLine = true;
+                                    return (int)(pSrc - pRaw);
+
+                                case NewLineHandling.Entitize:
+                                    // Entitize 0xD
+                                    pDst = CarriageReturnEntity(pDst);
+                                    break;
+                                case NewLineHandling.None:
+                                    *pDst = (<#= BufferType #>)ch;
+                                    pDst++;
+                                    break;
+                            }
+                            break;
+                        default:
+<#= EncodeChar(7, true) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+                textPos = bufPos;
+                contentPos = 0;
+            }
+
+            return -1;
+        }
+
+        protected unsafe int WriteElementTextBlockNoFlush(char[] chars, int index, int count, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            if (count == 0)
+            {
+                contentPos = 0;
+                return -1;
+            }
+            fixed (char* pSrc = &chars[index])
+            {
+                char* pSrcBeg = pSrc;
+                char* pSrcEnd = pSrcBeg + count;
+                return WriteElementTextBlockNoFlush(pSrcBeg, pSrcEnd, out needWriteNewLine);
+            }
+        }
+
+        protected unsafe int WriteElementTextBlockNoFlush(string text, int index, int count, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            if (count == 0)
+            {
+                contentPos = 0;
+                return -1;
+            }
+            fixed (char* pSrc = text)
+            {
+                char* pSrcBeg = pSrc + index;
+                char* pSrcEnd = pSrcBeg + count;
+                return WriteElementTextBlockNoFlush(pSrcBeg, pSrcEnd, out needWriteNewLine);
+            }
+        }
+
+        protected async Task WriteElementTextBlockAsync(char[] chars, int index, int count)
+        {
+            int writeLen = 0;
+            int curIndex = index;
+            int leftCount = count;
+            bool needWriteNewLine = false;
+            do
+            {
+                writeLen = WriteElementTextBlockNoFlush(chars, curIndex, leftCount, out needWriteNewLine);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (needWriteNewLine)
+                {
+                    //hit WriteNewLine
+                    await RawTextAsync(newLineChars).ConfigureAwait(false);
+                    curIndex++;
+                    leftCount--;
+                }
+                else if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0 || needWriteNewLine);
+        }
+
+        protected Task WriteElementTextBlockAsync(string text)
+        {
+            int writeLen = 0;
+            int curIndex = 0;
+            int leftCount = text.Length;
+            bool needWriteNewLine = false;
+
+            writeLen = WriteElementTextBlockNoFlush(text, curIndex, leftCount, out needWriteNewLine);
+            curIndex += writeLen;
+            leftCount -= writeLen;
+            if (needWriteNewLine)
+            {
+                return _WriteElementTextBlockAsync(true, text, curIndex, leftCount);
+            }
+            else if (writeLen >= 0)
+            {
+                return _WriteElementTextBlockAsync(false, text, curIndex, leftCount);
+            }
+
+            return Task.CompletedTask;
+        }
+
+        private async Task _WriteElementTextBlockAsync(bool newLine, string text, int curIndex, int leftCount)
+        {
+            int writeLen = 0;
+            bool needWriteNewLine = false;
+
+            if (newLine)
+            {
+                await RawTextAsync(newLineChars).ConfigureAwait(false);
+                curIndex++;
+                leftCount--;
+            }
+            else
+            {
+                await FlushBufferAsync().ConfigureAwait(false);
+            }
+
+            do
+            {
+                writeLen = WriteElementTextBlockNoFlush(text, curIndex, leftCount, out needWriteNewLine);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (needWriteNewLine)
+                {
+                    //hit WriteNewLine
+                    await RawTextAsync(newLineChars).ConfigureAwait(false);
+                    curIndex++;
+                    leftCount--;
+                }
+                else if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0 || needWriteNewLine);
+        }
+
+        protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd)
+        {
+            char* pRaw = pSrcBegin;
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+                char* pSrc = pSrcBegin;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && ((ch = *pSrc) <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && ((ch = *pSrc) < XmlCharType.SurHighStart))
+<# } #>
+                    {
+                        pSrc++;
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                    }
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        return (int)(pSrc - pRaw);
+                    }
+
+<#= EncodeChar(5, false) #>
+                }
+
+                bufPos = (int)(pDst - pDstBegin);
+            }
+
+            return -1;
+        }
+
+        protected unsafe int RawTextNoFlush(string text, int index, int count)
+        {
+            if (count == 0)
+            {
+                return -1;
+            }
+            fixed (char* pSrc = text)
+            {
+                char* pSrcBegin = pSrc + index;
+                char* pSrcEnd = pSrcBegin + count;
+                return RawTextNoFlush(pSrcBegin, pSrcEnd);
+            }
+        }
+
+        // special-case the one string overload, as it's so common
+        protected Task RawTextAsync(string text)
+        {
+            int writeLen = RawTextNoFlush(text, 0, text.Length);
+            return writeLen >= 0 ?
+                _RawTextAsync(text, writeLen, text.Length - writeLen) :
+                Task.CompletedTask;
+        }
+
+        protected Task RawTextAsync(string text1, string text2 = null, string text3 = null, string text4 = null)
+        {
+            Debug.Assert(text1 != null);
+            Debug.Assert(text2 != null || (text3 == null && text4 == null));
+            Debug.Assert(text3 != null || (text4 == null));
+
+            int writeLen;
+
+            // Write out the first string
+            writeLen = RawTextNoFlush(text1, 0, text1.Length);
+            if (writeLen >= 0)
+            {
+                // If we were only able to partially write it, write out the remainder
+                // and then write out the other strings.
+                return _RawTextAsync(text1, writeLen, text1.Length - writeLen, text2, text3, text4);
+            }
+
+            // We wrote out the first string.  Try to write out the second, if it exists.
+            if (text2 != null)
+            {
+                writeLen = RawTextNoFlush(text2, 0, text2.Length);
+                if (writeLen >= 0)
+                {
+                    // If we were only able to write out some of the second string,
+                    // write out the remainder and then the other strings,
+                    return _RawTextAsync(text2, writeLen, text2.Length - writeLen, text3, text4);
+                }
+            }
+
+            // We wrote out the first and second strings.  Try to write out the third
+            // if it exists.
+            if (text3 != null)
+            {
+                writeLen = RawTextNoFlush(text3, 0, text3.Length);
+                if (writeLen >= 0)
+                {
+                    // If we were only able to write out some of the third string,
+                    // write out the remainder and then the last string.
+                    return _RawTextAsync(text3, writeLen, text3.Length - writeLen, text4);
+                }
+            }
+
+            // Finally, try to write out the fourth string, if it exists.
+            if (text4 != null)
+            {
+                writeLen = RawTextNoFlush(text4, 0, text4.Length);
+                if (writeLen >= 0)
+                {
+                    return _RawTextAsync(text4, writeLen, text4.Length - writeLen);
+                }
+            }
+
+            // All strings written successfully.
+            return Task.CompletedTask;
+        }
+
+        private async Task _RawTextAsync(
+            string text1, int curIndex1, int leftCount1,
+            string text2 = null, string text3 = null, string text4 = null)
+        {
+            Debug.Assert(text1 != null);
+            Debug.Assert(text2 != null || (text3 == null && text4 == null));
+            Debug.Assert(text3 != null || (text4 == null));
+
+            // Write out the remainder of the first string
+            await FlushBufferAsync().ConfigureAwait(false);
+            int writeLen = 0;
+            do
+            {
+                writeLen = RawTextNoFlush(text1, curIndex1, leftCount1);
+                curIndex1 += writeLen;
+                leftCount1 -= writeLen;
+                if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0);
+
+            // If there are additional strings, write them out as well
+            if (text2 != null)
+            {
+                await RawTextAsync(text2, text3, text4).ConfigureAwait(false);
+            }
+        }
+
+        protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrcEnd, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            char* pRaw = pSrcBegin;
+
+            fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+            {
+                char* pSrc = pSrcBegin;
+                <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                int ch = 0;
+                for (;;)
+                {
+                    <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                    if (pDstEnd > pDstBegin + bufLen)
+                    {
+                        pDstEnd = pDstBegin + bufLen;
+                    }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                    while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F))
+<# } else { #>
+                    while (pDst < pDstEnd && xmlCharType.IsTextChar((char)(ch = *pSrc)))
+<# } #>
+                    {
+                        *pDst = (<#= BufferType #>)ch;
+                        pDst++;
+                        pSrc++;
+                    }
+
+                    Debug.Assert(pSrc <= pSrcEnd);
+
+                    // end of value
+                    if (pSrc >= pSrcEnd)
+                    {
+                        break;
+                    }
+
+                    // end of buffer
+                    if (pDst >= pDstEnd)
+                    {
+                        bufPos = (int)(pDst - pDstBegin);
+                        return (int)(pSrc - pRaw);
+                    }
+
+                    // handle special characters
+                    switch (ch)
+                    {
+                        case ']':
+                        case '<':
+                        case '&':
+                        case (char)0x9:
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            break;
+                        case (char)0xD:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                // Normalize "\r\n", or "\r" to NewLineChars
+                                if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                {
+                                    pSrc++;
+                                }
+
+                                bufPos = (int)(pDst - pDstBegin);
+                                needWriteNewLine = true;
+                                return (int)(pSrc - pRaw);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        case (char)0xA:
+                            if (newLineHandling == NewLineHandling.Replace)
+                            {
+                                bufPos = (int)(pDst - pDstBegin);
+                                needWriteNewLine = true;
+                                return (int)(pSrc - pRaw);
+                            }
+                            else
+                            {
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                            }
+                            break;
+                        default:
+<#= EncodeChar(7, false) #>
+                            continue;
+                    }
+                    pSrc++;
+                }
+                bufPos = (int)(pDst - pDstBegin);
+            }
+
+            return -1;
+        }
+
+        protected unsafe int WriteRawWithCharCheckingNoFlush(char[] chars, int index, int count, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            if (count == 0)
+            {
+                return -1;
+            }
+            fixed (char* pSrc = &chars[index])
+            {
+                char* pSrcBeg = pSrc;
+                char* pSrcEnd = pSrcBeg + count;
+                return WriteRawWithCharCheckingNoFlush(pSrcBeg, pSrcEnd, out needWriteNewLine);
+            }
+        }
+
+        protected unsafe int WriteRawWithCharCheckingNoFlush(string text, int index, int count, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            if (count == 0)
+            {
+                return -1;
+            }
+            fixed (char* pSrc = text)
+            {
+                char* pSrcBeg = pSrc + index;
+                char* pSrcEnd = pSrcBeg + count;
+                return WriteRawWithCharCheckingNoFlush(pSrcBeg, pSrcEnd, out needWriteNewLine);
+            }
+        }
+
+        protected async Task WriteRawWithCharCheckingAsync(char[] chars, int index, int count)
+        {
+            int writeLen = 0;
+            int curIndex = index;
+            int leftCount = count;
+            bool needWriteNewLine = false;
+            do
+            {
+                writeLen = WriteRawWithCharCheckingNoFlush(chars, curIndex, leftCount, out needWriteNewLine);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (needWriteNewLine)
+                {
+                    await RawTextAsync(newLineChars).ConfigureAwait(false);
+                    curIndex++;
+                    leftCount--;
+                }
+                else if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0 || needWriteNewLine);
+        }
+
+        protected async Task WriteRawWithCharCheckingAsync(string text)
+        {
+            int writeLen = 0;
+            int curIndex = 0;
+            int leftCount = text.Length;
+            bool needWriteNewLine = false;
+            do
+            {
+                writeLen = WriteRawWithCharCheckingNoFlush(text, curIndex, leftCount, out needWriteNewLine);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (needWriteNewLine)
+                {
+                    await RawTextAsync(newLineChars).ConfigureAwait(false);
+                    curIndex++;
+                    leftCount--;
+                }
+                else if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0 || needWriteNewLine);
+        }
+
+        protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, int stopChar, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            if (count == 0)
+            {
+                return -1;
+            }
+            fixed (char* pSrcText = text)
+            {
+                char* pSrcBegin = pSrcText + index;
+
+                fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+                {
+                    char* pSrc = pSrcBegin;
+
+                    char* pRaw = pSrc;
+
+                    char* pSrcEnd = pSrcBegin + count;
+
+                    <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                    int ch = 0;
+                    for (;;)
+                    {
+                        <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                        if (pDstEnd > pDstBegin + bufLen)
+                        {
+                            pDstEnd = pDstBegin + bufLen;
+                        }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                        while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F))
+<# } else { #>
+                        while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar))
+<# } #>
+                        {
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            pSrc++;
+                        }
+
+                        Debug.Assert(pSrc <= pSrcEnd);
+
+                        // end of value
+                        if (pSrc >= pSrcEnd)
+                        {
+                            break;
+                        }
+
+                        // end of buffer
+                        if (pDst >= pDstEnd)
+                        {
+                            bufPos = (int)(pDst - pDstBegin);
+                            return (int)(pSrc - pRaw);
+                        }
+
+                        // handle special characters
+                        switch (ch)
+                        {
+                            case '-':
+                                *pDst = (<#= BufferType #>)'-';
+                                pDst++;
+                                if (ch == stopChar)
+                                {
+                                    // Insert space between adjacent dashes or before comment's end dashes
+                                    if (pSrc + 1 == pSrcEnd || *(pSrc + 1) == '-')
+                                    {
+                                        *pDst = (<#= BufferType #>)' ';
+                                        pDst++;
+                                    }
+                                }
+                                break;
+                            case '?':
+                                *pDst = (<#= BufferType #>)'?';
+                                pDst++;
+                                if (ch == stopChar)
+                                {
+                                    // Processing instruction: insert space between adjacent '?' and '>'
+                                    if (pSrc + 1 < pSrcEnd && *(pSrc + 1) == '>')
+                                    {
+                                        *pDst = (<#= BufferType #>)' ';
+                                        pDst++;
+                                    }
+                                }
+                                break;
+                            case ']':
+                                *pDst = (<#= BufferType #>)']';
+                                pDst++;
+                                break;
+                            case (char)0xD:
+                                if (newLineHandling == NewLineHandling.Replace)
+                                {
+                                    // Normalize "\r\n", or "\r" to NewLineChars
+                                    if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                    {
+                                        pSrc++;
+                                    }
+
+                                    bufPos = (int)(pDst - pDstBegin);
+                                    needWriteNewLine = true;
+                                    return (int)(pSrc - pRaw);
+                                }
+                                else
+                                {
+                                    *pDst = (<#= BufferType #>)ch;
+                                    pDst++;
+                                }
+                                break;
+                            case (char)0xA:
+                                if (newLineHandling == NewLineHandling.Replace)
+                                {
+                                    bufPos = (int)(pDst - pDstBegin);
+                                    needWriteNewLine = true;
+                                    return (int)(pSrc - pRaw);
+                                }
+                                else
+                                {
+                                    *pDst = (<#= BufferType #>)ch;
+                                    pDst++;
+                                }
+                                break;
+                            case '<':
+                            case '&':
+                            case (char)0x9:
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                                break;
+                            default:
+<#= EncodeChar(8, false) #>
+                                continue;
+                        }
+                        pSrc++;
+                    }
+                    bufPos = (int)(pDst - pDstBegin);
+                }
+
+                return -1;
+            }
+        }
+
+        protected async Task WriteCommentOrPiAsync(string text, int stopChar)
+        {
+            if (text.Length == 0)
+            {
+                if (bufPos >= bufLen)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+                return;
+            }
+
+            int writeLen = 0;
+            int curIndex = 0;
+            int leftCount = text.Length;
+            bool needWriteNewLine = false;
+            do
+            {
+                writeLen = WriteCommentOrPiNoFlush(text, curIndex, leftCount, stopChar, out needWriteNewLine);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (needWriteNewLine)
+                {
+                    await RawTextAsync(newLineChars).ConfigureAwait(false);
+                    curIndex++;
+                    leftCount--;
+                }
+                else if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0 || needWriteNewLine);
+        }
+
+        protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, out bool needWriteNewLine)
+        {
+            needWriteNewLine = false;
+            if (count == 0)
+            {
+                return -1;
+            }
+
+            // write text
+
+            fixed (char* pSrcText = text)
+            {
+                char* pSrcBegin = pSrcText + index;
+
+                fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>)
+                {
+                    char* pSrc = pSrcBegin;
+
+                    char* pSrcEnd = pSrcBegin + count;
+
+                    char* pRaw = pSrc;
+
+                    <#= BufferType #>* pDst = pDstBegin + bufPos;
+
+                    int ch = 0;
+                    for (;;)
+                    {
+                        <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc);
+                        if (pDstEnd > pDstBegin + bufLen)
+                        {
+                            pDstEnd = pDstBegin + bufLen;
+                        }
+
+<# if (WriterType == RawTextWriterType.Utf8) { #>
+                        while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F))
+<# } else { #>
+                        while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']'))
+<# } #>
+                        {
+                            *pDst = (<#= BufferType #>)ch;
+                            pDst++;
+                            pSrc++;
+                        }
+
+                        Debug.Assert(pSrc <= pSrcEnd);
+
+                        // end of value
+                        if (pSrc >= pSrcEnd)
+                        {
+                            break;
+                        }
+
+                        // end of buffer
+                        if (pDst >= pDstEnd)
+                        {
+                            bufPos = (int)(pDst - pDstBegin);
+                            return (int)(pSrc - pRaw);
+                        }
+
+                        // handle special characters
+                        switch (ch)
+                        {
+                            case '>':
+                                if (hadDoubleBracket && pDst[-1] == (<#= BufferType #>)']')
+                                {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
+                                    // The characters "]]>" were found within the CData text
+                                    pDst = RawEndCData(pDst);
+                                    pDst = RawStartCData(pDst);
+                                }
+                                *pDst = (<#= BufferType #>)'>';
+                                pDst++;
+                                break;
+                            case ']':
+                                if (pDst[-1] == (<#= BufferType #>)']')
+                                {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
+                                    hadDoubleBracket = true;
+                                }
+                                else
+                                {
+                                    hadDoubleBracket = false;
+                                }
+                                *pDst = (<#= BufferType #>)']';
+                                pDst++;
+                                break;
+                            case (char)0xD:
+                                if (newLineHandling == NewLineHandling.Replace)
+                                {
+                                    // Normalize "\r\n", or "\r" to NewLineChars
+                                    if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n')
+                                    {
+                                        pSrc++;
+                                    }
+
+                                    bufPos = (int)(pDst - pDstBegin);
+                                    needWriteNewLine = true;
+                                    return (int)(pSrc - pRaw);
+                                }
+                                else
+                                {
+                                    *pDst = (<#= BufferType #>)ch;
+                                    pDst++;
+                                }
+                                break;
+                            case (char)0xA:
+                                if (newLineHandling == NewLineHandling.Replace)
+                                {
+                                    bufPos = (int)(pDst - pDstBegin);
+                                    needWriteNewLine = true;
+                                    return (int)(pSrc - pRaw);
+                                }
+                                else
+                                {
+                                    *pDst = (<#= BufferType #>)ch;
+                                    pDst++;
+                                }
+                                break;
+                            case '&':
+                            case '<':
+                            case '"':
+                            case '\'':
+                            case (char)0x9:
+                                *pDst = (<#= BufferType #>)ch;
+                                pDst++;
+                                break;
+                            default:
+<#= EncodeChar(8, false) #>
+                                continue;
+                        }
+                        pSrc++;
+                    }
+                    bufPos = (int)(pDst - pDstBegin);
+                }
+
+                return -1;
+            }
+        }
+
+        protected async Task WriteCDataSectionAsync(string text)
+        {
+            if (text.Length == 0)
+            {
+                if (bufPos >= bufLen)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+                return;
+            }
+
+            int writeLen = 0;
+            int curIndex = 0;
+            int leftCount = text.Length;
+            bool needWriteNewLine = false;
+            do
+            {
+                writeLen = WriteCDataSectionNoFlush(text, curIndex, leftCount, out needWriteNewLine);
+                curIndex += writeLen;
+                leftCount -= writeLen;
+                if (needWriteNewLine)
+                {
+                    await RawTextAsync(newLineChars).ConfigureAwait(false);
+                    curIndex++;
+                    leftCount--;
+                }
+                else if (writeLen >= 0)
+                {
+                    await FlushBufferAsync().ConfigureAwait(false);
+                }
+            } while (writeLen >= 0 || needWriteNewLine);
+        }
+    }
+
+    // Same as base text writer class except that elements, attributes, comments, and pi's are indented.
+    internal partial class <#= ClassNameIndent #> : <#= ClassName #>
+    {
+        public override async Task WriteDocTypeAsync(string name, string pubid, string sysid, string subset)
+        {
+            CheckAsyncCall();
+            // Add indentation
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                await WriteIndentAsync().ConfigureAwait(false);
+            }
+            await base.WriteDocTypeAsync(name, pubid, sysid, subset).ConfigureAwait(false);
+        }
+
+        public override async Task WriteStartElementAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null);
+
+            // Add indentation
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                await WriteIndentAsync().ConfigureAwait(false);
+            }
+            indentLevel++;
+            _mixedContentStack.PushBit(mixedContent);
+
+            await base.WriteStartElementAsync(prefix, localName, ns).ConfigureAwait(false);
+        }
+
+        internal override async Task WriteEndElementAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            // Add indentation
+            indentLevel--;
+            if (!mixedContent && base.contentPos != base.bufPos)
+            {
+                // There was content, so try to indent
+                if (base.textPos != base.bufPos)
+                {
+                    await WriteIndentAsync().ConfigureAwait(false);
+                }
+            }
+            mixedContent = _mixedContentStack.PopBit();
+
+            await base.WriteEndElementAsync(prefix, localName, ns).ConfigureAwait(false);
+        }
+
+        internal override async Task WriteFullEndElementAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            // Add indentation
+            indentLevel--;
+            if (!mixedContent && base.contentPos != base.bufPos)
+            {
+                // There was content, so try to indent
+                if (base.textPos != base.bufPos)
+                {
+                    await WriteIndentAsync().ConfigureAwait(false);
+                }
+            }
+            mixedContent = _mixedContentStack.PopBit();
+
+            await base.WriteFullEndElementAsync(prefix, localName, ns).ConfigureAwait(false);
+        }
+
+        // Same as base class, plus possible indentation.
+        protected internal override async Task WriteStartAttributeAsync(string prefix, string localName, string ns)
+        {
+            CheckAsyncCall();
+            // Add indentation
+            if (newLineOnAttributes)
+            {
+                await WriteIndentAsync().ConfigureAwait(false);
+            }
+
+            await base.WriteStartAttributeAsync(prefix, localName, ns).ConfigureAwait(false);
+        }
+
+        public override Task WriteCDataAsync(string text)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteCDataAsync(text);
+        }
+
+        public override async Task WriteCommentAsync(string text)
+        {
+            CheckAsyncCall();
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                await WriteIndentAsync().ConfigureAwait(false);
+            }
+
+            await base.WriteCommentAsync(text).ConfigureAwait(false);
+        }
+
+        public override async Task WriteProcessingInstructionAsync(string target, string text)
+        {
+            CheckAsyncCall();
+            if (!mixedContent && base.textPos != base.bufPos)
+            {
+                await WriteIndentAsync().ConfigureAwait(false);
+            }
+
+            await base.WriteProcessingInstructionAsync(target, text).ConfigureAwait(false);
+        }
+
+        public override Task WriteEntityRefAsync(string name)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteEntityRefAsync(name);
+        }
+
+        public override Task WriteCharEntityAsync(char ch)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteCharEntityAsync(ch);
+        }
+
+        public override Task WriteSurrogateCharEntityAsync(char lowChar, char highChar)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteSurrogateCharEntityAsync(lowChar, highChar);
+        }
+
+        public override Task WriteWhitespaceAsync(string ws)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteWhitespaceAsync(ws);
+        }
+
+        public override Task WriteStringAsync(string text)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteStringAsync(text);
+        }
+
+        public override Task WriteCharsAsync(char[] buffer, int index, int count)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteCharsAsync(buffer, index, count);
+        }
+
+        public override Task WriteRawAsync(char[] buffer, int index, int count)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteRawAsync(buffer, index, count);
+        }
+
+        public override Task WriteRawAsync(string data)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteRawAsync(data);
+        }
+
+        public override Task WriteBase64Async(byte[] buffer, int index, int count)
+        {
+            CheckAsyncCall();
+            mixedContent = true;
+            return base.WriteBase64Async(buffer, index, count);
+        }
+
+        // Add indentation to output.  Write newline and then repeat IndentChars for each indent level.
+        private async Task WriteIndentAsync()
+        {
+            CheckAsyncCall();
+            await RawTextAsync(base.newLineChars).ConfigureAwait(false);
+            for (int i = indentLevel; i > 0; i--)
+            {
+                await RawTextAsync(indentChars).ConfigureAwait(false);
+            }
+        }
+    }
+}
index 567adfd..5ef0e49 100644 (file)
@@ -2,17 +2,8 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-// Note: This code went through some modifications and generation comment might not be fully valid
-// WARNING: This file is generated and should not be modified directly.  Instead,
-// modify XmlTextWriterGenerator.cxx and run gen.bat in the same directory.
-// This batch file will execute the following commands:
-//
-//   cl.exe /C /EP /D _XML_ENCODED_TEXT_WRITER XmlRawTextWriterGenerator.cxx > XmlEncodedRawTextWriter.cs
-//
-// Because these two implementations of XmlTextWriter are so similar, the C++ preprocessor
-// is used to generate each implementation from one template file, using macros and ifdefs.
-
-// Note: This file was generated without #define SILVERLIGHT
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify XmlRawTextWriterGenerator.ttinclude
 
 using System;
 using System.IO;
@@ -40,7 +31,7 @@ namespace System.Xml
         // output stream
         protected Stream stream;
 
-        // encoding of the stream or text writer 
+        // encoding of the stream or text writer
         protected Encoding encoding;
 
         // char type tables
@@ -48,7 +39,7 @@ namespace System.Xml
 
         // buffer positions
         protected int bufPos = 1;     // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
-                                      // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
+                                      // close an empty element or in CDATA section detection of double ]; bufBytes[0] will always be 0
         protected int textPos = 1;    // text end position; don't indent first element, pi, or comment
         protected int contentPos;     // element content end position
         protected int cdataPos;       // cdata end position
@@ -60,6 +51,7 @@ namespace System.Xml
         protected bool hadDoubleBracket;
         protected bool inAttributeValue;
 
+
         // writer settings
         protected NewLineHandling newLineHandling;
         protected bool closeOutput;
@@ -121,7 +113,6 @@ namespace System.Xml
             }
 
             bufBytes = new byte[bufLen + OVERFLOW];
-
             // Output UTF-8 byte order mark if Encoding object wants it
             if (!stream.CanSeek || stream.Position == 0)
             {
@@ -152,11 +143,11 @@ namespace System.Xml
             {
                 XmlWriterSettings settings = new XmlWriterSettings();
 
-                settings.Encoding = this.encoding;
-                settings.OmitXmlDeclaration = this.omitXmlDeclaration;
-                settings.NewLineHandling = this.newLineHandling;
-                settings.NewLineChars = this.newLineChars;
-                settings.CloseOutput = this.closeOutput;
+                settings.Encoding = encoding;
+                settings.OmitXmlDeclaration = omitXmlDeclaration;
+                settings.NewLineHandling = newLineHandling;
+                settings.NewLineChars = newLineChars;
+                settings.CloseOutput = closeOutput;
                 settings.ConformanceLevel = ConformanceLevel.Auto;
                 settings.CheckCharacters = checkCharacters;
 
@@ -169,7 +160,7 @@ namespace System.Xml
             }
         }
 
-        // Write the xml declaration.  This must be the first call.  
+        // Write the xml declaration.  This must be the first call.
         internal override void WriteXmlDeclaration(XmlStandalone standalone)
         {
             // Output xml declaration only if user allows it and it was not already output
@@ -243,7 +234,7 @@ namespace System.Xml
                 bufBytes[bufPos++] = (byte)']';
             }
 
-            bufBytes[this.bufPos++] = (byte)'>';
+            bufBytes[bufPos++] = (byte)'>';
         }
 
         // Serialize the beginning of an element start tag: "<prefix:localName"
@@ -256,7 +247,7 @@ namespace System.Xml
             if (prefix != null && prefix.Length != 0)
             {
                 RawText(prefix);
-                bufBytes[this.bufPos++] = (byte)':';
+                bufBytes[bufPos++] = (byte)':';
             }
 
             RawText(localName);
@@ -350,6 +341,7 @@ namespace System.Xml
         // Serialize the end of an attribute value using double quotes: '"'
         public override void WriteEndAttribute()
         {
+
             bufBytes[bufPos++] = (byte)'"';
             inAttributeValue = false;
             attrEndPos = bufPos;
@@ -359,9 +351,9 @@ namespace System.Xml
         {
             Debug.Assert(prefix != null && namespaceName != null);
 
-            this.WriteStartNamespaceDeclaration(prefix);
-            this.WriteString(namespaceName);
-            this.WriteEndNamespaceDeclaration();
+            WriteStartNamespaceDeclaration(prefix);
+            WriteString(namespaceName);
+            WriteEndNamespaceDeclaration();
         }
 
         internal override bool SupportsNamespaceDeclarationInChunks
@@ -662,7 +654,6 @@ namespace System.Xml
         {
             FlushBuffer();
             FlushEncoder();
-
             if (stream != null)
             {
                 stream.Flush();
@@ -694,7 +685,6 @@ namespace System.Xml
             {
                 // Move last buffer character to the beginning of the buffer (so that previous character can always be determined)
                 bufBytes[0] = bufBytes[bufPos - 1];
-
                 if (IsSurrogateByte(bufBytes[0]))
                 {
                     // Last character was the first byte in a surrogate encoding, so move last three
@@ -710,7 +700,7 @@ namespace System.Xml
                 contentPos = 0;    // Needs to be zero, since overwriting '>' character is no longer possible
                 cdataPos = 0;      // Needs to be zero, since overwriting ']]>' characters is no longer possible
                 bufPos = 1;        // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to
-                                   // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0
+                                   // close an empty element or in CDATA section detection of double ]; bufBytes[0] will always be 0
             }
         }
 
@@ -722,12 +712,11 @@ namespace System.Xml
 
         // Serialize text that is part of an attribute value.  The '&', '<', '>', and '"' characters
         // are entitized.
-
         protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd)
         {
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -817,7 +806,24 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -828,12 +834,11 @@ namespace System.Xml
 
         // Serialize text that is part of element content.  The '&', '<', and '>' characters
         // are entitized.
-
         protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd)
         {
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -920,7 +925,24 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -945,16 +967,16 @@ namespace System.Xml
         {
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
                 char* pSrc = pSrcBegin;
 
                 int ch = 0;
                 for (;;)
                 {
                     byte* pDstEnd = pDst + (pSrcEnd - pSrc);
-                    if (pDstEnd > pDstBegin + this.bufLen)
+                    if (pDstEnd > pDstBegin + bufLen)
                     {
-                        pDstEnd = pDstBegin + this.bufLen;
+                        pDstEnd = pDstBegin + bufLen;
                     }
 
                     while (pDst < pDstEnd && ((ch = *pSrc) <= 0x7F))
@@ -980,7 +1002,24 @@ namespace System.Xml
                         continue;
                     }
 
-                    if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                    /* Surrogate character */
+                    if (XmlCharType.IsSurrogate(ch))
+                    {
+                        pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                        pSrc += 2;
+                    }
+                    /* Invalid XML character */
+                    else if (ch <= 0x7F || ch >= 0xFFFE)
+                    {
+                        pDst = InvalidXmlChar(ch, pDst, false);
+                        pSrc++;
+                    }
+                    /* Multibyte UTF8 character */
+                    else
+                    {
+                        pDst = EncodeMultibyteUTF8(ch, pDst);
+                        pSrc++;
+                    }
                 }
 
                 bufPos = (int)(pDst - pDstBegin);
@@ -1066,7 +1105,24 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1150,7 +1206,7 @@ namespace System.Xml
                             pDst++;
                             if (ch == stopChar)
                             {
-                                // Processing instruction: insert space between adjacent '?' and '>' 
+                                // Processing instruction: insert space between adjacent '?' and '>'
                                 if (pSrc + 1 < pSrcEnd && *(pSrc + 1) == '>')
                                 {
                                     *pDst = (byte)' ';
@@ -1197,7 +1253,24 @@ namespace System.Xml
                             pDst++;
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1267,7 +1340,7 @@ namespace System.Xml
                     {
                         case '>':
                             if (hadDoubleBracket && pDst[-1] == (byte)']')
-                            {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
+                            {   // pDst[-1] will always correct - there is a padding character at bufBytes[0]
                                 // The characters "]]>" were found within the CData text
                                 pDst = RawEndCData(pDst);
                                 pDst = RawStartCData(pDst);
@@ -1277,7 +1350,7 @@ namespace System.Xml
                             break;
                         case ']':
                             if (pDst[-1] == (byte)']')
-                            {   // pDst[-1] will always correct - there is a padding character at _BUFFER[0]
+                            {   // pDst[-1] will always correct - there is a padding character at bufBytes[0]
                                 hadDoubleBracket = true;
                             }
                             else
@@ -1324,7 +1397,24 @@ namespace System.Xml
                             pDst++;
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1400,7 +1490,6 @@ namespace System.Xml
                     {
                         pDst = EncodeMultibyteUTF8(ch, pDst);
                     }
-
                     return pDst;
                 }
             }
@@ -1409,7 +1498,24 @@ namespace System.Xml
         internal unsafe void EncodeChar(ref char* pSrc, char* pSrcEnd, ref byte* pDst)
         {
             int ch = *pSrc;
-            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+            /* Surrogate character */
+            if (XmlCharType.IsSurrogate(ch))
+            {
+                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                pSrc += 2;
+            }
+            /* Invalid XML character */
+            else if (ch <= 0x7F || ch >= 0xFFFE)
+            {
+                pDst = InvalidXmlChar(ch, pDst, false);
+                pSrc++;
+            }
+            /* Multibyte UTF8 character */
+            else
+            {
+                pDst = EncodeMultibyteUTF8(ch, pDst);
+                pSrc++;
+            }
         }
 
         internal static unsafe byte* EncodeMultibyteUTF8(int ch, byte* pDst)
@@ -1462,7 +1568,6 @@ namespace System.Xml
         }
 
         // Write NewLineChars to the specified buffer position and return an updated position.
-
         protected unsafe byte* WriteNewLine(byte* pDst)
         {
             fixed (byte* pDstBegin = bufBytes)
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.tt
new file mode 100644 (file)
index 0000000..2813668
--- /dev/null
@@ -0,0 +1,6 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterUtf8.ttinclude" #>
+<#@ include file="XmlRawTextWriterGenerator.ttinclude" #>
index 817d3b3..31567c1 100644 (file)
@@ -2,6 +2,9 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+// WARNING: This file is generated and should not be modified directly.
+// Instead, modify XmlRawTextWriterGeneratorAsync.ttinclude
+
 using System;
 using System.IO;
 using System.Xml;
@@ -27,13 +30,14 @@ namespace System.Xml
             }
         }
 
-        // Write the xml declaration.  This must be the first call.  
+        // Write the xml declaration.  This must be the first call.
         internal override async Task WriteXmlDeclarationAsync(XmlStandalone standalone)
         {
             CheckAsyncCall();
             // Output xml declaration only if user allows it and it was not already output
             if (!omitXmlDeclaration && !autoXmlDeclaration)
             {
+
                 await RawTextAsync("<?xml version=\"").ConfigureAwait(false);
 
                 // Version
@@ -106,7 +110,7 @@ namespace System.Xml
                 bufBytes[bufPos++] = (byte)']';
             }
 
-            bufBytes[this.bufPos++] = (byte)'>';
+            bufBytes[bufPos++] = (byte)'>';
         }
 
         // Serialize the beginning of an element start tag: "<prefix:localName"
@@ -116,8 +120,8 @@ namespace System.Xml
             Debug.Assert(localName != null && localName.Length > 0);
             Debug.Assert(prefix != null);
 
-            bufBytes[bufPos++] = (byte)'<';
             Task task;
+            bufBytes[bufPos++] = (byte)'<';
             if (prefix != null && prefix.Length != 0)
             {
                 task = RawTextAsync(prefix, ":", localName);
@@ -126,7 +130,6 @@ namespace System.Xml
             {
                 task = RawTextAsync(localName);
             }
-
             return task.CallVoidFuncWhenFinishAsync(thisRef => thisRef.WriteStartElementAsync_SetAttEndPos(), this);
         }
 
@@ -203,17 +206,19 @@ namespace System.Xml
             Task task;
             if (prefix != null && prefix.Length > 0)
             {
-                task = RawTextAsync(prefix, ":", localName, "=\"");
+                task = RawTextAsync(prefix, ":", localName);
             }
             else
             {
-                task = RawTextAsync(localName, "=\"");
+                task = RawTextAsync(localName);
             }
             return task.CallVoidFuncWhenFinishAsync(thisRef => thisRef.WriteStartAttribute_SetInAttribute(), this);
         }
 
         private void WriteStartAttribute_SetInAttribute()
         {
+            bufBytes[bufPos++] = (byte)'=';
+            bufBytes[bufPos++] = (byte)'"';
             inAttributeValue = true;
         }
 
@@ -234,9 +239,9 @@ namespace System.Xml
             CheckAsyncCall();
             Debug.Assert(prefix != null && namespaceName != null);
 
-            await this.WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
-            await this.WriteStringAsync(namespaceName).ConfigureAwait(false);
-            await this.WriteEndNamespaceDeclarationAsync().ConfigureAwait(false);
+            await WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
+            await WriteStringAsync(namespaceName).ConfigureAwait(false);
+            await WriteEndNamespaceDeclarationAsync().ConfigureAwait(false);
         }
 
         internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
@@ -492,7 +497,6 @@ namespace System.Xml
         {
             CheckAsyncCall();
             await FlushBufferAsync().ConfigureAwait(false);
-            await FlushEncoderAsync().ConfigureAwait(false);
 
             if (stream != null)
             {
@@ -545,13 +549,6 @@ namespace System.Xml
             }
         }
 
-        private Task FlushEncoderAsync()
-        {
-            // intentionally empty
-
-            return Task.CompletedTask;
-        }
-
         // Serialize text that is part of an attribute value.  The '&', '<', '>', and '"' characters
         // are entitized.
         protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd)
@@ -560,7 +557,7 @@ namespace System.Xml
 
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -648,7 +645,24 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -746,7 +760,7 @@ namespace System.Xml
 
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
 
                 int ch = 0;
                 for (;;)
@@ -834,7 +848,24 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, true); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, true);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -967,16 +998,16 @@ namespace System.Xml
 
             fixed (byte* pDstBegin = bufBytes)
             {
-                byte* pDst = pDstBegin + this.bufPos;
+                byte* pDst = pDstBegin + bufPos;
                 char* pSrc = pSrcBegin;
 
                 int ch = 0;
                 for (;;)
                 {
                     byte* pDstEnd = pDst + (pSrcEnd - pSrc);
-                    if (pDstEnd > pDstBegin + this.bufLen)
+                    if (pDstEnd > pDstBegin + bufLen)
                     {
-                        pDstEnd = pDstBegin + this.bufLen;
+                        pDstEnd = pDstBegin + bufLen;
                     }
 
                     while (pDst < pDstEnd && ((ch = *pSrc) <= 0x7F))
@@ -1000,7 +1031,24 @@ namespace System.Xml
                         return (int)(pSrc - pRaw);
                     }
 
-                    if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                    /* Surrogate character */
+                    if (XmlCharType.IsSurrogate(ch))
+                    {
+                        pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                        pSrc += 2;
+                    }
+                    /* Invalid XML character */
+                    else if (ch <= 0x7F || ch >= 0xFFFE)
+                    {
+                        pDst = InvalidXmlChar(ch, pDst, false);
+                        pSrc++;
+                    }
+                    /* Multibyte UTF8 character */
+                    else
+                    {
+                        pDst = EncodeMultibyteUTF8(ch, pDst);
+                        pSrc++;
+                    }
                 }
 
                 bufPos = (int)(pDst - pDstBegin);
@@ -1056,7 +1104,7 @@ namespace System.Xml
                 if (writeLen >= 0)
                 {
                     // If we were only able to write out some of the second string,
-                    // write out the remainder and then the other strings, 
+                    // write out the remainder and then the other strings,
                     return _RawTextAsync(text2, writeLen, text2.Length - writeLen, text3, text4);
                 }
             }
@@ -1089,10 +1137,10 @@ namespace System.Xml
         }
 
         private async Task _RawTextAsync(
-            string text, int curIndex, int leftCount,
+            string text1, int curIndex1, int leftCount1,
             string text2 = null, string text3 = null, string text4 = null)
         {
-            Debug.Assert(text != null);
+            Debug.Assert(text1 != null);
             Debug.Assert(text2 != null || (text3 == null && text4 == null));
             Debug.Assert(text3 != null || (text4 == null));
 
@@ -1101,9 +1149,9 @@ namespace System.Xml
             int writeLen = 0;
             do
             {
-                writeLen = RawTextNoFlush(text, curIndex, leftCount);
-                curIndex += writeLen;
-                leftCount -= writeLen;
+                writeLen = RawTextNoFlush(text1, curIndex1, leftCount1);
+                curIndex1 += writeLen;
+                leftCount1 -= writeLen;
                 if (writeLen >= 0)
                 {
                     await FlushBufferAsync().ConfigureAwait(false);
@@ -1201,7 +1249,24 @@ namespace System.Xml
                             }
                             break;
                         default:
-                            if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                            /* Surrogate character */
+                            if (XmlCharType.IsSurrogate(ch))
+                            {
+                                pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                pSrc += 2;
+                            }
+                            /* Invalid XML character */
+                            else if (ch <= 0x7F || ch >= 0xFFFE)
+                            {
+                                pDst = InvalidXmlChar(ch, pDst, false);
+                                pSrc++;
+                            }
+                            /* Multibyte UTF8 character */
+                            else
+                            {
+                                pDst = EncodeMultibyteUTF8(ch, pDst);
+                                pSrc++;
+                            }
                             continue;
                     }
                     pSrc++;
@@ -1363,7 +1428,7 @@ namespace System.Xml
                                 pDst++;
                                 if (ch == stopChar)
                                 {
-                                    // Processing instruction: insert space between adjacent '?' and '>' 
+                                    // Processing instruction: insert space between adjacent '?' and '>'
                                     if (pSrc + 1 < pSrcEnd && *(pSrc + 1) == '>')
                                     {
                                         *pDst = (byte)' ';
@@ -1414,7 +1479,24 @@ namespace System.Xml
                                 pDst++;
                                 break;
                             default:
-                                if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                                /* Surrogate character */
+                                if (XmlCharType.IsSurrogate(ch))
+                                {
+                                    pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                    pSrc += 2;
+                                }
+                                /* Invalid XML character */
+                                else if (ch <= 0x7F || ch >= 0xFFFE)
+                                {
+                                    pDst = InvalidXmlChar(ch, pDst, false);
+                                    pSrc++;
+                                }
+                                /* Multibyte UTF8 character */
+                                else
+                                {
+                                    pDst = EncodeMultibyteUTF8(ch, pDst);
+                                    pSrc++;
+                                }
                                 continue;
                         }
                         pSrc++;
@@ -1580,7 +1662,24 @@ namespace System.Xml
                                 pDst++;
                                 break;
                             default:
-                                if (XmlCharType.IsSurrogate(ch)) { pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst); pSrc += 2; } else if (ch <= 0x7F || ch >= 0xFFFE) { pDst = InvalidXmlChar(ch, pDst, false); pSrc++; } else { pDst = EncodeMultibyteUTF8(ch, pDst); pSrc++; };
+                                /* Surrogate character */
+                                if (XmlCharType.IsSurrogate(ch))
+                                {
+                                    pDst = EncodeSurrogate(pSrc, pSrcEnd, pDst);
+                                    pSrc += 2;
+                                }
+                                /* Invalid XML character */
+                                else if (ch <= 0x7F || ch >= 0xFFFE)
+                                {
+                                    pDst = InvalidXmlChar(ch, pDst, false);
+                                    pSrc++;
+                                }
+                                /* Multibyte UTF8 character */
+                                else
+                                {
+                                    pDst = EncodeMultibyteUTF8(ch, pDst);
+                                    pSrc++;
+                                }
                                 continue;
                         }
                         pSrc++;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.tt b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.tt
new file mode 100644 (file)
index 0000000..92d8c1e
--- /dev/null
@@ -0,0 +1,6 @@
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ output extension=".cs" #>
+<#@ import namespace="System" #>
+<#@ include file="RawTextWriterUtf8.ttinclude" #>
+<#@ include file="XmlRawTextWriterGeneratorAsync.ttinclude" #>