Skip to content

Commit 47cd24e

Browse files
Modernize XmlUTF8TextWriter with u8/inline out's. (#75812)
* Modernize XmlUTF8TextWriter with u8/inline out's. * PR feedback --------- Co-authored-by: Steve Molloy <[email protected]>
1 parent b1fbb80 commit 47cd24e

File tree

2 files changed

+46
-134
lines changed

2 files changed

+46
-134
lines changed

src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlStreamNodeWriter.cs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -263,22 +263,6 @@ protected unsafe void WriteUTF8Char(int ch)
263263
}
264264
}
265265

266-
protected void WriteUTF8Chars(byte[] chars, int charOffset, int charCount)
267-
{
268-
if (charCount < bufferLength)
269-
{
270-
int offset;
271-
byte[] buffer = GetBuffer(charCount, out offset);
272-
Buffer.BlockCopy(chars, charOffset, buffer, offset, charCount);
273-
Advance(charCount);
274-
}
275-
else
276-
{
277-
FlushBuffer();
278-
OutputStream.Write(chars, charOffset, charCount);
279-
}
280-
}
281-
282266
protected unsafe void WriteUTF8Chars(string value)
283267
{
284268
int count = value.Length;
@@ -291,6 +275,21 @@ protected unsafe void WriteUTF8Chars(string value)
291275
}
292276
}
293277

278+
protected void WriteUTF8Bytes(ReadOnlySpan<byte> value)
279+
{
280+
if (value.Length < bufferLength)
281+
{
282+
byte[] buffer = GetBuffer(value.Length, out int offset);
283+
value.CopyTo(buffer.AsSpan(offset));
284+
Advance(value.Length);
285+
}
286+
else
287+
{
288+
FlushBuffer();
289+
OutputStream.Write(value);
290+
}
291+
}
292+
294293
protected unsafe void UnsafeWriteUTF8Chars(char* chars, int charCount)
295294
{
296295
const int charChunkSize = bufferLength / maxBytesPerChar;

src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextWriter.cs

Lines changed: 31 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ internal class XmlUTF8NodeWriter : XmlStreamNodeWriter
5858
private Encoding? _encoding;
5959
private char[]? _chars;
6060

61-
private static readonly byte[] s_startDecl = "<?xml version=\"1.0\" encoding=\""u8.ToArray();
62-
private static readonly byte[] s_endDecl = "\"?>"u8.ToArray();
63-
private static readonly byte[] s_utf8Decl = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"u8.ToArray();
64-
6561
private static ReadOnlySpan<byte> Digits => "0123456789ABCDEF"u8;
6662

6763
private static readonly bool[] s_defaultIsEscapedAttributeChar = new bool[]
@@ -127,64 +123,34 @@ public override void WriteDeclaration()
127123
{
128124
if (_encoding == null)
129125
{
130-
WriteUTF8Chars(s_utf8Decl, 0, s_utf8Decl.Length);
126+
WriteUTF8Bytes("<?xml version=\"1.0\" encoding=\"utf-8\"?>"u8);
131127
}
132128
else
133129
{
134-
WriteUTF8Chars(s_startDecl, 0, s_startDecl.Length);
130+
WriteUTF8Bytes("<?xml version=\"1.0\" encoding=\""u8);
135131
if (_encoding.WebName == Encoding.BigEndianUnicode.WebName)
136-
WriteUTF8Chars("utf-16BE");
132+
WriteUTF8Bytes("utf-16BE"u8);
137133
else
138134
WriteUTF8Chars(_encoding.WebName);
139-
WriteUTF8Chars(s_endDecl, 0, s_endDecl.Length);
135+
WriteUTF8Bytes("\"?>"u8);
140136
}
141137
}
142138

143139
public override void WriteCData(string text)
144140
{
145-
byte[] buffer;
146-
int offset;
147-
148-
buffer = GetBuffer(9, out offset);
149-
buffer[offset + 0] = (byte)'<';
150-
buffer[offset + 1] = (byte)'!';
151-
buffer[offset + 2] = (byte)'[';
152-
buffer[offset + 3] = (byte)'C';
153-
buffer[offset + 4] = (byte)'D';
154-
buffer[offset + 5] = (byte)'A';
155-
buffer[offset + 6] = (byte)'T';
156-
buffer[offset + 7] = (byte)'A';
157-
buffer[offset + 8] = (byte)'[';
158-
Advance(9);
159-
141+
WriteUTF8Bytes("<![CDATA["u8);
160142
WriteUTF8Chars(text);
161-
162-
buffer = GetBuffer(3, out offset);
163-
buffer[offset + 0] = (byte)']';
164-
buffer[offset + 1] = (byte)']';
165-
buffer[offset + 2] = (byte)'>';
166-
Advance(3);
143+
WriteUTF8Bytes("]]>"u8);
167144
}
168145

169146
private void WriteStartComment()
170147
{
171-
int offset;
172-
byte[] buffer = GetBuffer(4, out offset);
173-
buffer[offset + 0] = (byte)'<';
174-
buffer[offset + 1] = (byte)'!';
175-
buffer[offset + 2] = (byte)'-';
176-
buffer[offset + 3] = (byte)'-';
177-
Advance(4);
148+
WriteUTF8Bytes("<!--"u8);
178149
}
179150

180151
private void WriteEndComment()
181152
{
182-
int offset;
183-
byte[] buffer = GetBuffer(3, out offset);
184-
buffer[offset + 0] = (byte)'-';
185-
buffer[offset + 1] = (byte)'-';
186-
buffer[offset + 2] = (byte)'>';
187-
Advance(3);
153+
WriteUTF8Bytes("-->"u8);
188154
}
189155

190156
public override void WriteComment(string text)
@@ -297,15 +263,7 @@ public override void WriteEndElement(byte[] prefixBuffer, int prefixOffset, int
297263

298264
private void WriteStartXmlnsAttribute()
299265
{
300-
int offset;
301-
byte[] buffer = GetBuffer(6, out offset);
302-
buffer[offset + 0] = (byte)' ';
303-
buffer[offset + 1] = (byte)'x';
304-
buffer[offset + 2] = (byte)'m';
305-
buffer[offset + 3] = (byte)'l';
306-
buffer[offset + 4] = (byte)'n';
307-
buffer[offset + 5] = (byte)'s';
308-
Advance(6);
266+
WriteUTF8Bytes(" xmlns"u8);
309267
_inAttribute = true;
310268
}
311269

@@ -403,7 +361,7 @@ private void WritePrefix(byte[] prefixBuffer, int prefixOffset, int prefixLength
403361
}
404362
else
405363
{
406-
WriteUTF8Chars(prefixBuffer, prefixOffset, prefixLength);
364+
WriteUTF8Bytes(prefixBuffer.AsSpan(prefixOffset, prefixLength));
407365
}
408366
}
409367

@@ -414,7 +372,7 @@ private void WriteLocalName(string localName)
414372

415373
private void WriteLocalName(byte[] localNameBuffer, int localNameOffset, int localNameLength)
416374
{
417-
WriteUTF8Chars(localNameBuffer, localNameOffset, localNameLength);
375+
WriteUTF8Bytes(localNameBuffer.AsSpan(localNameOffset, localNameLength));
418376
}
419377

420378
public override void WriteEscapedText(XmlDictionaryString s)
@@ -473,7 +431,7 @@ public override void WriteEscapedText(byte[] chars, int offset, int count)
473431
byte ch = chars[offset + j];
474432
if (ch < isEscapedCharLength && isEscapedChar[ch])
475433
{
476-
WriteUTF8Chars(chars, offset + i, j - i);
434+
WriteUTF8Bytes(chars.AsSpan(offset + i, j - i));
477435
WriteCharEntity(ch);
478436
i = j + 1;
479437
}
@@ -486,13 +444,13 @@ public override void WriteEscapedText(byte[] chars, int offset, int count)
486444
byte ch3 = chars[offset + j + 2];
487445
if (ch2 == 191 && (ch3 == 190 || ch3 == 191))
488446
{
489-
WriteUTF8Chars(chars, offset + i, j - i);
447+
WriteUTF8Bytes(chars.AsSpan(offset + i, j - i));
490448
WriteCharEntity(ch3 == 190 ? (char)0xFFFE : (char)0xFFFF);
491449
i = j + 3;
492450
}
493451
}
494452
}
495-
WriteUTF8Chars(chars, offset + i, count - i);
453+
WriteUTF8Bytes(chars.AsSpan(offset + i, count - i));
496454
}
497455

498456
public void WriteText(int ch)
@@ -502,7 +460,7 @@ public void WriteText(int ch)
502460

503461
public override void WriteText(byte[] chars, int offset, int count)
504462
{
505-
WriteUTF8Chars(chars, offset, count);
463+
WriteUTF8Bytes(chars.AsSpan(offset, count));
506464
}
507465

508466
public override unsafe void WriteText(char[] chars, int offset, int count)
@@ -528,62 +486,27 @@ public override void WriteText(XmlDictionaryString value)
528486

529487
public void WriteLessThanCharEntity()
530488
{
531-
int offset;
532-
byte[] buffer = GetBuffer(4, out offset);
533-
buffer[offset + 0] = (byte)'&';
534-
buffer[offset + 1] = (byte)'l';
535-
buffer[offset + 2] = (byte)'t';
536-
buffer[offset + 3] = (byte)';';
537-
Advance(4);
489+
WriteUTF8Bytes("&lt;"u8);
538490
}
539491

540492
public void WriteGreaterThanCharEntity()
541493
{
542-
int offset;
543-
byte[] buffer = GetBuffer(4, out offset);
544-
buffer[offset + 0] = (byte)'&';
545-
buffer[offset + 1] = (byte)'g';
546-
buffer[offset + 2] = (byte)'t';
547-
buffer[offset + 3] = (byte)';';
548-
Advance(4);
494+
WriteUTF8Bytes("&gt;"u8);
549495
}
550496

551497
public void WriteAmpersandCharEntity()
552498
{
553-
int offset;
554-
byte[] buffer = GetBuffer(5, out offset);
555-
buffer[offset + 0] = (byte)'&';
556-
buffer[offset + 1] = (byte)'a';
557-
buffer[offset + 2] = (byte)'m';
558-
buffer[offset + 3] = (byte)'p';
559-
buffer[offset + 4] = (byte)';';
560-
Advance(5);
499+
WriteUTF8Bytes("&amp;"u8);
561500
}
562501

563502
public void WriteApostropheCharEntity()
564503
{
565-
int offset;
566-
byte[] buffer = GetBuffer(6, out offset);
567-
buffer[offset + 0] = (byte)'&';
568-
buffer[offset + 1] = (byte)'a';
569-
buffer[offset + 2] = (byte)'p';
570-
buffer[offset + 3] = (byte)'o';
571-
buffer[offset + 4] = (byte)'s';
572-
buffer[offset + 5] = (byte)';';
573-
Advance(6);
504+
WriteUTF8Bytes("&apos;"u8);
574505
}
575506

576507
public void WriteQuoteCharEntity()
577508
{
578-
int offset;
579-
byte[] buffer = GetBuffer(6, out offset);
580-
buffer[offset + 0] = (byte)'&';
581-
buffer[offset + 1] = (byte)'q';
582-
buffer[offset + 2] = (byte)'u';
583-
buffer[offset + 3] = (byte)'o';
584-
buffer[offset + 4] = (byte)'t';
585-
buffer[offset + 5] = (byte)';';
586-
Advance(6);
509+
WriteUTF8Bytes("&quot;"u8);
587510
}
588511

589512
private void WriteHexCharEntity(int ch)
@@ -595,7 +518,7 @@ private void WriteHexCharEntity(int ch)
595518
chars[--offset] = (byte)'x';
596519
chars[--offset] = (byte)'#';
597520
chars[--offset] = (byte)'&';
598-
WriteUTF8Chars(chars, offset, maxEntityLength - offset);
521+
WriteUTF8Bytes(chars.AsSpan(offset, maxEntityLength - offset));
599522
}
600523

601524
public override void WriteCharEntity(int ch)
@@ -638,36 +561,31 @@ private static int ToBase16(byte[] chars, int offset, uint value)
638561

639562
public override void WriteBoolText(bool value)
640563
{
641-
int offset;
642-
byte[] buffer = GetBuffer(XmlConverter.MaxBoolChars, out offset);
564+
byte[] buffer = GetBuffer(XmlConverter.MaxBoolChars, out int offset);
643565
Advance(XmlConverter.ToChars(value, buffer, offset));
644566
}
645567

646568
public override void WriteDecimalText(decimal value)
647569
{
648-
int offset;
649-
byte[] buffer = GetBuffer(XmlConverter.MaxDecimalChars, out offset);
570+
byte[] buffer = GetBuffer(XmlConverter.MaxDecimalChars, out int offset);
650571
Advance(XmlConverter.ToChars(value, buffer, offset));
651572
}
652573

653574
public override void WriteDoubleText(double value)
654575
{
655-
int offset;
656-
byte[] buffer = GetBuffer(XmlConverter.MaxDoubleChars, out offset);
576+
byte[] buffer = GetBuffer(XmlConverter.MaxDoubleChars, out int offset);
657577
Advance(XmlConverter.ToChars(value, buffer, offset));
658578
}
659579

660580
public override void WriteFloatText(float value)
661581
{
662-
int offset;
663-
byte[] buffer = GetBuffer(XmlConverter.MaxFloatChars, out offset);
582+
byte[] buffer = GetBuffer(XmlConverter.MaxFloatChars, out int offset);
664583
Advance(XmlConverter.ToChars(value, buffer, offset));
665584
}
666585

667586
public override void WriteDateTimeText(DateTime value)
668587
{
669-
int offset;
670-
byte[] buffer = GetBuffer(XmlConverter.MaxDateTimeChars, out offset);
588+
byte[] buffer = GetBuffer(XmlConverter.MaxDateTimeChars, out int offset);
671589
Advance(XmlConverter.ToChars(value, buffer, offset));
672590
}
673591

@@ -688,22 +606,19 @@ public override void WriteUniqueIdText(UniqueId value)
688606

689607
public override void WriteInt32Text(int value)
690608
{
691-
int offset;
692-
byte[] buffer = GetBuffer(XmlConverter.MaxInt32Chars, out offset);
609+
byte[] buffer = GetBuffer(XmlConverter.MaxInt32Chars, out int offset);
693610
Advance(XmlConverter.ToChars(value, buffer, offset));
694611
}
695612

696613
public override void WriteInt64Text(long value)
697614
{
698-
int offset;
699-
byte[] buffer = GetBuffer(XmlConverter.MaxInt64Chars, out offset);
615+
byte[] buffer = GetBuffer(XmlConverter.MaxInt64Chars, out int offset);
700616
Advance(XmlConverter.ToChars(value, buffer, offset));
701617
}
702618

703619
public override void WriteUInt64Text(ulong value)
704620
{
705-
int offset;
706-
byte[] buffer = GetBuffer(XmlConverter.MaxUInt64Chars, out offset);
621+
byte[] buffer = GetBuffer(XmlConverter.MaxUInt64Chars, out int offset);
707622
Advance(XmlConverter.ToChars(value, buffer, offset));
708623
}
709624

@@ -738,16 +653,14 @@ private void InternalWriteBase64Text(byte[] buffer, int offset, int count)
738653
{
739654
int byteCount = Math.Min(bufferLength / 4 * 3, count - count % 3);
740655
int charCount = byteCount / 3 * 4;
741-
int charOffset;
742-
byte[] chars = GetBuffer(charCount, out charOffset);
656+
byte[] chars = GetBuffer(charCount, out int charOffset);
743657
Advance(encoding.GetChars(buffer, offset, byteCount, chars, charOffset));
744658
offset += byteCount;
745659
count -= byteCount;
746660
}
747661
if (count > 0)
748662
{
749-
int charOffset;
750-
byte[] chars = GetBuffer(4, out charOffset);
663+
byte[] chars = GetBuffer(4, out int charOffset);
751664
Advance(encoding.GetChars(buffer, offset, count, chars, charOffset));
752665
}
753666
}

0 commit comments

Comments
 (0)