initial commit
This commit is contained in:
67
Identity.cs
Normal file
67
Identity.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Benchmark
|
||||
{
|
||||
public readonly struct Identity
|
||||
{
|
||||
public Identity(string prefix, int index, int revision)
|
||||
{
|
||||
Prefix = prefix;
|
||||
Index = index;
|
||||
Revision = revision;
|
||||
}
|
||||
|
||||
public string Prefix { get; }
|
||||
public int Index { get; }
|
||||
public int Revision { get; }
|
||||
|
||||
public static bool TryParse(string value, out Identity identity)
|
||||
{
|
||||
identity = default;
|
||||
var position = value.Length;
|
||||
if (!TryGetNumber(value, null, ref position, out var revision)) return false;
|
||||
if (value[position] != '-') return false;
|
||||
if (!TryGetNumber(value, 7, ref position, out var index)) return false;
|
||||
if (!TryGetPrefix(value, ref position, out var prefix)) return false;
|
||||
identity = new Identity(prefix, index, revision);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetPrefix(in string identity, ref int lastPosition, out string prefix)
|
||||
{
|
||||
prefix = identity.Remove(lastPosition + 1);
|
||||
if (prefix.Length <= 3) return false;
|
||||
return !prefix.Any(character => character < 'A' || character > 'Z');
|
||||
}
|
||||
|
||||
private static bool TryGetNumber(in string identity, int? exactLength, ref int currentPosition, out int revision)
|
||||
{
|
||||
revision = 0;
|
||||
var start = currentPosition;
|
||||
for (currentPosition = start - 1; currentPosition >= 0; currentPosition--)
|
||||
{
|
||||
var current = identity[currentPosition];
|
||||
if(current == '0') continue;
|
||||
if (current < '1' || current > '9') break;
|
||||
revision += (current - '0') * IntegerPow(10, start - currentPosition - 1);
|
||||
}
|
||||
|
||||
if (exactLength != null && start - (currentPosition + 1) != exactLength) return false;
|
||||
return revision != default;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int IntegerPow(int x, int y)
|
||||
{
|
||||
if (y == 0) return 1;
|
||||
var result = x;
|
||||
for (var i = 1; i < y; i++)
|
||||
{
|
||||
result *= x;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user