Skip to content

Commit

Permalink
Use C# compiler's static data support in Encoding.Preamble (dotnet/co…
Browse files Browse the repository at this point in the history
…reclr#20768)

* Use C# compiler's static data support in Encoding.Preamble

Also avoid Array.Empty and just use default span for an empty preamble.

* Address PR feedback


Commit migrated from dotnet/coreclr@faa4c87
  • Loading branch information
stephentoub committed Nov 3, 2018
1 parent 3e42709 commit 1bdf10b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 17 deletions.
Expand Up @@ -39,9 +39,6 @@ public sealed class UTF32Encoding : Encoding
internal static readonly UTF32Encoding s_default = new UTF32Encoding(bigEndian: false, byteOrderMark: true);
internal static readonly UTF32Encoding s_bigEndianDefault = new UTF32Encoding(bigEndian: true, byteOrderMark: true);

private static readonly byte[] s_bigEndianPreamble = new byte[4] { 0x00, 0x00, 0xFE, 0xFF };
private static readonly byte[] s_littleEndianPreamble = new byte[4] { 0xFF, 0xFE, 0x00, 0x00 };

private readonly bool _emitUTF32ByteOrderMark = false;
private readonly bool _isThrowException = false;
private readonly bool _bigEndian = false;
Expand Down Expand Up @@ -1155,9 +1152,10 @@ public override byte[] GetPreamble()
}

public override ReadOnlySpan<byte> Preamble =>
GetType() != typeof(UTF32Encoding) ? GetPreamble() : // in case a derived UTF32Encoding overrode GetPreamble
_emitUTF32ByteOrderMark ? (_bigEndian ? s_bigEndianPreamble : s_littleEndianPreamble) :
Array.Empty<byte>();
GetType() != typeof(UTF32Encoding) ? new ReadOnlySpan<byte>(GetPreamble()) : // in case a derived UTF32Encoding overrode GetPreamble
!_emitUTF32ByteOrderMark ? default :
_bigEndian ? (ReadOnlySpan<byte>)new byte[4] { 0x00, 0x00, 0xFE, 0xFF } : // uses C# compiler's optimization for static byte[] data
(ReadOnlySpan<byte>)new byte[4] { 0xFF, 0xFE, 0x00, 0x00 };

public override bool Equals(object value)
{
Expand Down
Expand Up @@ -55,14 +55,14 @@ internal sealed class UTF8EncodingSealed : UTF8Encoding
{
public UTF8EncodingSealed(bool encoderShouldEmitUTF8Identifier) : base(encoderShouldEmitUTF8Identifier) { }

public override ReadOnlySpan<byte> Preamble => _emitUTF8Identifier ? s_preamble : Array.Empty<byte>();
public override ReadOnlySpan<byte> Preamble => _emitUTF8Identifier ? PreambleSpan : default;
}

// Used by Encoding.UTF8 for lazy initialization
// The initialization code will not be run until a static member of the class is referenced
internal static readonly UTF8EncodingSealed s_default = new UTF8EncodingSealed(encoderShouldEmitUTF8Identifier: true);

internal static readonly byte[] s_preamble = new byte[3] { 0xEF, 0xBB, 0xBF };
internal static ReadOnlySpan<byte> PreambleSpan => new byte[3] { 0xEF, 0xBB, 0xBF }; // uses C# compiler's optimization for static byte[] data

// Yes, the idea of emitting U+FEFF as a UTF-8 identifier has made it into
// the standard.
Expand Down Expand Up @@ -2549,9 +2549,9 @@ public override byte[] GetPreamble()
}

public override ReadOnlySpan<byte> Preamble =>
GetType() != typeof(UTF8Encoding) ? GetPreamble() : // in case a derived UTF8Encoding overrode GetPreamble
_emitUTF8Identifier ? s_preamble :
Array.Empty<byte>();
GetType() != typeof(UTF8Encoding) ? new ReadOnlySpan<byte>(GetPreamble()) : // in case a derived UTF8Encoding overrode GetPreamble
_emitUTF8Identifier ? PreambleSpan :
default;

public override bool Equals(object value)
{
Expand Down
Expand Up @@ -26,9 +26,6 @@ public class UnicodeEncoding : Encoding
internal static readonly UnicodeEncoding s_bigEndianDefault = new UnicodeEncoding(bigEndian: true, byteOrderMark: true);
internal static readonly UnicodeEncoding s_littleEndianDefault = new UnicodeEncoding(bigEndian: false, byteOrderMark: true);

private static readonly byte[] s_bigEndianPreamble = new byte[2] { 0xfe, 0xff };
private static readonly byte[] s_littleEndianPreamble = new byte[2] { 0xff, 0xfe };

private readonly bool isThrowException = false;

private readonly bool bigEndian = false;
Expand Down Expand Up @@ -1793,9 +1790,10 @@ public override byte[] GetPreamble()
}

public override ReadOnlySpan<byte> Preamble =>
GetType() != typeof(UnicodeEncoding) ? GetPreamble() : // in case a derived UnicodeEncoding overrode GetPreamble
byteOrderMark ? (bigEndian ? s_bigEndianPreamble : s_littleEndianPreamble) :
Array.Empty<byte>();
GetType() != typeof(UnicodeEncoding) ? new ReadOnlySpan<byte>(GetPreamble()) : // in case a derived UnicodeEncoding overrode GetPreamble
!byteOrderMark ? default :
bigEndian ? (ReadOnlySpan<byte>)new byte[2] { 0xfe, 0xff } : // uses C# compiler's optimization for static byte[] data
(ReadOnlySpan<byte>)new byte[2] { 0xff, 0xfe };

public override int GetMaxByteCount(int charCount)
{
Expand Down

0 comments on commit 1bdf10b

Please sign in to comment.