Skip to content

Instantly share code, notes, and snippets.

@benaadams
Created September 30, 2017 22:15
Show Gist options
  • Save benaadams/288c9287f8e816d9746579db7f94fa40 to your computer and use it in GitHub Desktop.
Save benaadams/288c9287f8e816d9746579db7f94fa40 to your computer and use it in GitHub Desktop.
public struct AsciiString : IEquatable<AsciiString>
{
private readonly byte[] _data;
public AsciiString(byte[] bytes) => _data = bytes;
public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s);
public int Length => _data.Length;
public static implicit operator ReadOnlySpan<byte>(AsciiString str) => str._data;
public static implicit operator byte[] (AsciiString str) => str._data;
public static implicit operator AsciiString(byte[] bytes) => new AsciiString(bytes);
public static implicit operator AsciiString(string str) => new AsciiString(str);
public override string ToString() => Encoding.ASCII.GetString(_data);
public static explicit operator string(AsciiString str) => str.ToString();
public bool Equals(AsciiString other) => ReferenceEquals(_data, other._data) || SequenceEqual(_data, other._data);
private bool SequenceEqual(byte[] data1, byte[] data2) => new Span<byte>(data1).SequenceEqual(data2);
public static bool operator ==(AsciiString a, AsciiString b) => a.Equals(b);
public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b);
public override bool Equals(object other) => (other is AsciiString) && Equals((AsciiString)other);
public override int GetHashCode()
{
// Copied from x64 version of string.GetLegacyNonRandomizedHashCode()
// https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/String.Comparison.cs
var data = _data;
int hash1 = 5381;
int hash2 = hash1;
foreach (int b in data)
{
hash1 = ((hash1 << 5) + hash1) ^ b;
}
return hash1 + (hash2 * 1566083941);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment