Penumbra/Penumbra.GameData/ByteString/Utf8String.Comparison.cs

140 lines
No EOL
3.4 KiB
C#

using System;
using System.Linq;
namespace Penumbra.GameData.ByteString;
public sealed unsafe partial class Utf8String : IEquatable< Utf8String >, IComparable< Utf8String >
{
public bool Equals( Utf8String? other )
{
if( ReferenceEquals( null, other ) )
{
return false;
}
if( ReferenceEquals( this, other ) )
{
return true;
}
return _crc32 == other._crc32 && ByteStringFunctions.Equals( _path, Length, other._path, other.Length );
}
public bool EqualsCi( Utf8String? other )
{
if( ReferenceEquals( null, other ) )
{
return false;
}
if( ReferenceEquals( this, other ) )
{
return true;
}
if( ( IsAsciiLowerInternal ?? false ) && ( other.IsAsciiLowerInternal ?? false ) )
{
return _crc32 == other._crc32 && ByteStringFunctions.Equals( _path, Length, other._path, other.Length );
}
return ByteStringFunctions.AsciiCaselessEquals( _path, Length, other._path, other.Length );
}
public int CompareTo( Utf8String? other )
{
if( ReferenceEquals( this, other ) )
{
return 0;
}
if( ReferenceEquals( null, other ) )
{
return 1;
}
return ByteStringFunctions.Compare( _path, Length, other._path, other.Length );
}
public int CompareToCi( Utf8String? other )
{
if( ReferenceEquals( null, other ) )
{
return 0;
}
if( ReferenceEquals( this, other ) )
{
return 1;
}
if( ( IsAsciiLowerInternal ?? false ) && ( other.IsAsciiLowerInternal ?? false ) )
{
return ByteStringFunctions.Compare( _path, Length, other._path, other.Length );
}
return ByteStringFunctions.AsciiCaselessCompare( _path, Length, other._path, other.Length );
}
public bool StartsWith( Utf8String other )
{
var otherLength = other.Length;
return otherLength <= Length && ByteStringFunctions.Equals( other.Path, otherLength, Path, otherLength );
}
public bool EndsWith( Utf8String other )
{
var otherLength = other.Length;
var offset = Length - otherLength;
return offset >= 0 && ByteStringFunctions.Equals( other.Path, otherLength, Path + offset, otherLength );
}
public bool StartsWith( params char[] chars )
{
if( chars.Length > Length )
{
return false;
}
var ptr = _path;
return chars.All( t => *ptr++ == ( byte )t );
}
public bool EndsWith( params char[] chars )
{
if( chars.Length > Length )
{
return false;
}
var ptr = _path + Length - chars.Length;
return chars.All( c => *ptr++ == ( byte )c );
}
public int IndexOf( byte b, int from = 0 )
{
var end = _path + Length;
for( var tmp = _path + from; tmp < end; ++tmp )
{
if( *tmp == b )
{
return ( int )( tmp - _path );
}
}
return -1;
}
public int LastIndexOf( byte b, int to = 0 )
{
var end = _path + to;
for( var tmp = _path + Length - 1; tmp >= end; --tmp )
{
if( *tmp == b )
{
return ( int )( tmp - _path );
}
}
return -1;
}
}