Compare commits
6 Commits
d565c48084
...
v1.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b68ba982d | |||
| 43135a5ffb | |||
| 2afd66aa57 | |||
| 71ec5b2f35 | |||
| 30af957fc6 | |||
| d60b94dbaa |
@@ -28,7 +28,7 @@ public class Encode
|
|||||||
var resultBytes = Base32.Decode(testString);
|
var resultBytes = Base32.Decode(testString);
|
||||||
var resultString = Base32.Encode(resultBytes);
|
var resultString = Base32.Encode(resultBytes);
|
||||||
|
|
||||||
resultString.Should().BeEquivalentTo(testString);
|
resultString.Should().Be(testString);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -51,6 +51,19 @@ public class Encode
|
|||||||
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[] testArray)
|
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[] testArray)
|
||||||
{
|
{
|
||||||
var actualBase32 = Base32.Encode(testArray);
|
var actualBase32 = Base32.Encode(testArray);
|
||||||
actualBase32?.Should().Be(string.Empty);
|
actualBase32.Should().Be(string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[] { })]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void WhenCalledWithEmptyByteArray_ShouldReturnZeroAndNotChangeOutput(byte[] testArray)
|
||||||
|
{
|
||||||
|
char[] output = ['1', '2', '3', '4'];
|
||||||
|
|
||||||
|
var charsWritten = Base32.Encode(testArray, output);
|
||||||
|
|
||||||
|
charsWritten.Should().Be(0);
|
||||||
|
output.Should().Equal(['1', '2', '3', '4']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,4 +50,36 @@ public class Decode
|
|||||||
var result = Base64Url.Decode(testString);
|
var result = Base64Url.Decode(testString);
|
||||||
result.Should().BeEquivalentTo(expected);
|
result.Should().BeEquivalentTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(" ")]
|
||||||
|
[InlineData("hg2&515i3215")]
|
||||||
|
[InlineData("hg712)21")]
|
||||||
|
[InlineData("hg712f 21")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1806:Do not ignore method results", Justification = "Test case")]
|
||||||
|
public void WhenCalledWithInvalidString_ShouldThrowFormatException(string testString)
|
||||||
|
{
|
||||||
|
Action action = () => Base64Url.Decode(testString);
|
||||||
|
action.Should().Throw<FormatException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("5QrdUxDUV CAEGw8pvLsEw")]
|
||||||
|
[InlineData("6nE2uKQ4$0ar9kpmybgkdw")]
|
||||||
|
[InlineData("PyD6zwDqXkG*S1HPsp41wQ")]
|
||||||
|
[InlineData("!dOlPOh3wEe9PlyQgTMt2g")]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1806:Do not ignore method results", Justification = "Test case")]
|
||||||
|
public void WhenCalledWithInvalidGuidString_ShouldThrowFormatException(string testString)
|
||||||
|
{
|
||||||
|
Action action = () => Base64Url.DecodeGuid(testString);
|
||||||
|
action.Should().Throw<FormatException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("")]
|
||||||
|
public void WhenCalledWithNullString_ShouldReturnEmptyArray(string testString)
|
||||||
|
{
|
||||||
|
Base64Url.Decode(testString).Should().BeEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,4 +29,26 @@ public class Encode
|
|||||||
var result = Base64Url.Encode(testBytes);
|
var result = Base64Url.Encode(testBytes);
|
||||||
result.Should().Be(expected);
|
result.Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[] { })]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void WhenCalledWithEmptyByteArray_ShouldReturnEmptyString(byte[] testArray)
|
||||||
|
{
|
||||||
|
var actualBase32 = Base64Url.Encode(testArray);
|
||||||
|
actualBase32.Should().Be(string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[] { })]
|
||||||
|
[InlineData(null)]
|
||||||
|
public void WhenCalledWithEmptyByteArray_ShouldReturnZeroAndNotChangeOutput(byte[] testArray)
|
||||||
|
{
|
||||||
|
char[] output = ['1', '2', '3', '4'];
|
||||||
|
|
||||||
|
var charsWritten = Base64Url.Encode(testArray, output);
|
||||||
|
|
||||||
|
charsWritten.Should().Be(0);
|
||||||
|
output.Should().Equal(['1', '2', '3', '4']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,87 @@ public class NewGuid
|
|||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
-25000000 -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
-25000000, -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
||||||
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
||||||
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000)]
|
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000, 250000000)]
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
-25000000 -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
-25000000, -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
||||||
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
||||||
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000)]
|
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000, 250000000)]
|
||||||
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
|
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
||||||
|
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
||||||
|
-6576, -6162, -5630, -5505, -5472, -5382, -4706, -4680, -4509, -4454,
|
||||||
|
-4314, -3920, -3251, -3233, -3116, -2792, -2685, -2574, -2338, -2173,
|
||||||
|
-1934, -1914, -1528, -1483, -1410, -870, -757, -730, -263, -220,
|
||||||
|
151, 426, 588, 970, 1213, 1269, 1376, 1397, 1450, 1770,
|
||||||
|
2063, 2577, 2750, 2860, 3139, 3161, 3488, 3630, 3774, 4004,
|
||||||
|
4163, 4198, 4366, 4662, 4746, 4879, 5467, 5601, 5912, 5979,
|
||||||
|
6128, 6277, 6323, 6437, 6699, 6853, 7556, 7776, 7795, 8099,
|
||||||
|
8336, 8592, 8682, 8683, 8818, 8904, 9375, 9466, 9551, 9708)]
|
||||||
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
|
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
||||||
|
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
||||||
|
-6576, -6162, -5630, -5505, -5472, -5382, -4706, -4680, -4509, -4454,
|
||||||
|
-4314, -3920, -3251, -3233, -3116, -2792, -2685, -2574, -2338, -2173,
|
||||||
|
-1934, -1914, -1528, -1483, -1410, -870, -757, -730, -263, -220,
|
||||||
|
151, 426, 588, 970, 1213, 1269, 1376, 1397, 1450, 1770,
|
||||||
|
2063, 2577, 2750, 2860, 3139, 3161, 3488, 3630, 3774, 4004,
|
||||||
|
4163, 4198, 4366, 4662, 4746, 4879, 5467, 5601, 5912, 5979,
|
||||||
|
6128, 6277, 6323, 6437, 6699, 6853, 7556, 7776, 7795, 8099,
|
||||||
|
8336, 8592, 8682, 8683, 8818, 8904, 9375, 9466, 9551, 9708)]
|
||||||
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
|
5635912, 6673780, 17277183, 17512959, 19098799, 21672621, 30581958, 30824885, 31874213, 35192781,
|
||||||
|
36337094, 37752116, 38387215, 39154682, 40525427, 52288093, 55218356, 59065156, 65231785, 75430932,
|
||||||
|
76289058, 79078058, 85770685, 85925884, 94726743, 94864163, 95781967, 96150006, 96482085, 102570414,
|
||||||
|
107768232, 110571078, 110680108, 117974892, 119800380, 126381415, 135895862, 140034471, 149039187, 150906974,
|
||||||
|
156853001, 160514433, 166446323, 170148965, 171759448, 176494242, 184537553, 188558155, 197194403, 197615804,
|
||||||
|
201195323, 202294490, 203040975, 203331457, 205016944, 213460258, 217072025, 217185345, 231344025, 232390198,
|
||||||
|
235053215, 240175073, 245030721, 252275255, 252310334, 277070940, 277359970, 280624756, 288601124, 292427106,
|
||||||
|
292563035, 299285016, 303834917, 310357836, 315078337, 316367236, 318311758, 318873972, 319675272, 321784171,
|
||||||
|
324204294, 327667283, 330287252, 338438172, 349863360, 360777768, 366398711, 368637150, 368776734, 371900343,
|
||||||
|
379094084, 379818879, 381448333, 381814627, 382393101, 382483709, 385600870, 389455134, 396115960, 399364095)]
|
||||||
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
|
5635912, 6673780, 17277183, 17512959, 19098799, 21672621, 30581958, 30824885, 31874213, 35192781,
|
||||||
|
36337094, 37752116, 38387215, 39154682, 40525427, 52288093, 55218356, 59065156, 65231785, 75430932,
|
||||||
|
76289058, 79078058, 85770685, 85925884, 94726743, 94864163, 95781967, 96150006, 96482085, 102570414,
|
||||||
|
107768232, 110571078, 110680108, 117974892, 119800380, 126381415, 135895862, 140034471, 149039187, 150906974,
|
||||||
|
156853001, 160514433, 166446323, 170148965, 171759448, 176494242, 184537553, 188558155, 197194403, 197615804,
|
||||||
|
201195323, 202294490, 203040975, 203331457, 205016944, 213460258, 217072025, 217185345, 231344025, 232390198,
|
||||||
|
235053215, 240175073, 245030721, 252275255, 252310334, 277070940, 277359970, 280624756, 288601124, 292427106,
|
||||||
|
292563035, 299285016, 303834917, 310357836, 315078337, 316367236, 318311758, 318873972, 319675272, 321784171,
|
||||||
|
324204294, 327667283, 330287252, 338438172, 349863360, 360777768, 366398711, 368637150, 368776734, 371900343,
|
||||||
|
379094084, 379818879, 381448333, 381814627, 382393101, 382483709, 385600870, 389455134, 396115960, 399364095)]
|
||||||
|
public void Guids_Differing_By_Minutes_Should_Be_Sortable(GuidV8Entropy entropy, params int[] seconds)
|
||||||
|
{
|
||||||
|
var rng = new Random(25);
|
||||||
|
var referenceTime = new DateTime(2024, 05, 17, 15, 36, 13, 771, DateTimeKind.Utc);
|
||||||
|
SortedList<DateTime, Guid> expected = new(seconds.Length);
|
||||||
|
foreach (var s in seconds)
|
||||||
|
{
|
||||||
|
var timestamp = referenceTime.AddMinutes(s);
|
||||||
|
expected.Add(timestamp, GuidV8.NewGuid(timestamp, entropy));
|
||||||
|
}
|
||||||
|
|
||||||
|
var sut = expected.Values.ToArray();
|
||||||
|
rng.Shuffle(sut);
|
||||||
|
|
||||||
|
sut.Order().Should().Equal(expected.Select(x => x.Value));
|
||||||
|
sut.OrderBy(x => x.ToString()).Should().Equal(expected.Select(x => x.Value));
|
||||||
|
|
||||||
|
sut.OrderDescending().Should().Equal(expected.Reverse().Select(x => x.Value));
|
||||||
|
sut.OrderByDescending(x => x.ToString()).Should().Equal(expected.Reverse().Select(x => x.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
|
-250000000, -25000000, -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
||||||
|
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
||||||
|
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000, 2100000000)]
|
||||||
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
|
-250000000, -25000000, -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
||||||
|
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
||||||
|
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000, 2100000000)]
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
||||||
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
||||||
@@ -43,7 +117,7 @@ public class NewGuid
|
|||||||
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
||||||
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
||||||
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
||||||
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484)]
|
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484, 982233485)]
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
6629058, 24114993, 40561510, 46245969, 46876997, 48747281, 80489854, 110237218, 117445694, 118974860,
|
6629058, 24114993, 40561510, 46245969, 46876997, 48747281, 80489854, 110237218, 117445694, 118974860,
|
||||||
135132579, 141760591, 149114066, 158322437, 159065333, 164925904, 173848639, 175086337, 175704556, 176335514,
|
135132579, 141760591, 149114066, 158322437, 159065333, 164925904, 173848639, 175086337, 175704556, 176335514,
|
||||||
@@ -54,7 +128,7 @@ public class NewGuid
|
|||||||
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
||||||
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
||||||
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
||||||
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484)]
|
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484, 982233485)]
|
||||||
public void Guids_Differing_By_Seconds_Should_Be_Sortable(GuidV8Entropy entropy, params int[] seconds)
|
public void Guids_Differing_By_Seconds_Should_Be_Sortable(GuidV8Entropy entropy, params int[] seconds)
|
||||||
{
|
{
|
||||||
var rng = new Random(25);
|
var rng = new Random(25);
|
||||||
@@ -69,19 +143,22 @@ public class NewGuid
|
|||||||
var sut = expected.Values.ToArray();
|
var sut = expected.Values.ToArray();
|
||||||
rng.Shuffle(sut);
|
rng.Shuffle(sut);
|
||||||
|
|
||||||
sut.Order().Should().BeEquivalentTo(expected.Select(x => x.Value));
|
sut.Order().Should().Equal(expected.Select(x => x.Value));
|
||||||
sut.OrderDescending().Should().BeEquivalentTo(expected.Reverse().Select(x => x.Value));
|
sut.OrderBy(x => x.ToString()).Should().Equal(expected.Select(x => x.Value));
|
||||||
|
|
||||||
|
sut.OrderDescending().Should().Equal(expected.Reverse().Select(x => x.Value));
|
||||||
|
sut.OrderByDescending(x => x.ToString()).Should().Equal(expected.Reverse().Select(x => x.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
-25000000 -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
-250000000, -25000000, -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
||||||
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
||||||
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000)]
|
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000, 2100000000)]
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
-25000000 -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
-250000000, -25000000, -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
||||||
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
||||||
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000)]
|
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000, 2100000000)]
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
[InlineData(GuidV8Entropy.Weak,
|
||||||
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
||||||
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
||||||
@@ -114,7 +191,7 @@ public class NewGuid
|
|||||||
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
||||||
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
||||||
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
||||||
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484)]
|
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484, 982233485)]
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
[InlineData(GuidV8Entropy.Strong,
|
||||||
6629058, 24114993, 40561510, 46245969, 46876997, 48747281, 80489854, 110237218, 117445694, 118974860,
|
6629058, 24114993, 40561510, 46245969, 46876997, 48747281, 80489854, 110237218, 117445694, 118974860,
|
||||||
135132579, 141760591, 149114066, 158322437, 159065333, 164925904, 173848639, 175086337, 175704556, 176335514,
|
135132579, 141760591, 149114066, 158322437, 159065333, 164925904, 173848639, 175086337, 175704556, 176335514,
|
||||||
@@ -125,10 +202,10 @@ public class NewGuid
|
|||||||
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
||||||
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
||||||
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
||||||
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484)]
|
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484, 982233485)]
|
||||||
public void Guids_Differing_By_Milliseconds_Should_Be_Sortable(GuidV8Entropy entropy, params int[] seconds)
|
public void Guids_Differing_By_Milliseconds_Should_Be_Sortable(GuidV8Entropy entropy, params int[] seconds)
|
||||||
{
|
{
|
||||||
var rng = new Random(25);
|
var rng = new Random(26);
|
||||||
var referenceTime = new DateTime(2024, 05, 17, 15, 36, 13, 771, DateTimeKind.Utc);
|
var referenceTime = new DateTime(2024, 05, 17, 15, 36, 13, 771, DateTimeKind.Utc);
|
||||||
SortedList<DateTime, Guid> expected = new(seconds.Length);
|
SortedList<DateTime, Guid> expected = new(seconds.Length);
|
||||||
foreach (var s in seconds)
|
foreach (var s in seconds)
|
||||||
@@ -140,78 +217,10 @@ public class NewGuid
|
|||||||
var sut = expected.Values.ToArray();
|
var sut = expected.Values.ToArray();
|
||||||
rng.Shuffle(sut);
|
rng.Shuffle(sut);
|
||||||
|
|
||||||
sut.Order().Should().BeEquivalentTo(expected.Select(x => x.Value));
|
sut.Order().Should().Equal(expected.Select(x => x.Value));
|
||||||
sut.OrderDescending().Should().BeEquivalentTo(expected.Reverse().Select(x => x.Value));
|
sut.OrderBy(x => x.ToString()).Should().Equal(expected.Select(x => x.Value));
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
sut.OrderDescending().Should().Equal(expected.Reverse().Select(x => x.Value));
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
sut.OrderByDescending(x => x.ToString()).Should().Equal(expected.Reverse().Select(x => x.Value));
|
||||||
-25000000 -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
|
||||||
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
|
||||||
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000)]
|
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
|
||||||
-25000000 -10000000, -5000000, -2000000, -1000000, -500000, -250000, -100000, -25000, -10000, -5000,
|
|
||||||
-2500, -1000, -500, -499, -497, -450, -300, -200, -50, -1, 0, 1, 2, 5, 10, 20, 50, 100, 200, 350, 500, 1000,
|
|
||||||
2500, 5000, 10000, 25000, 100000, 250000, 500000, 1000000, 2000000, 5000000, 10000000)]
|
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
|
||||||
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
|
||||||
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
|
||||||
-6576, -6162, -5630, -5505, -5472, -5382, -4706, -4680, -4509, -4454,
|
|
||||||
-4314, -3920, -3251, -3233, -3116, -2792, -2685, -2574, -2338, -2173,
|
|
||||||
-1934, -1914, -1528, -1483, -1410, -870, -757, -730, -263, -220,
|
|
||||||
151, 426, 588, 970, 1213, 1269, 1376, 1397, 1450, 1770,
|
|
||||||
2063, 2577, 2750, 2860, 3139, 3161, 3488, 3630, 3774, 4004,
|
|
||||||
4163, 4198, 4366, 4662, 4746, 4879, 5467, 5601, 5912, 5979,
|
|
||||||
6128, 6277, 6323, 6437, 6699, 6853, 7556, 7776, 7795, 8099,
|
|
||||||
8336, 8592, 8682, 8683, 8818, 8904, 9375, 9466, 9551, 9708)]
|
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
|
||||||
-9863, -9740, -9214, -8878, -8674, -8652, -8640, -8565, -8518, -8449,
|
|
||||||
-8390, -8193, -8108, -7808, -7501, -7203, -7133, -7020, -6983, -6855,
|
|
||||||
-6576, -6162, -5630, -5505, -5472, -5382, -4706, -4680, -4509, -4454,
|
|
||||||
-4314, -3920, -3251, -3233, -3116, -2792, -2685, -2574, -2338, -2173,
|
|
||||||
-1934, -1914, -1528, -1483, -1410, -870, -757, -730, -263, -220,
|
|
||||||
151, 426, 588, 970, 1213, 1269, 1376, 1397, 1450, 1770,
|
|
||||||
2063, 2577, 2750, 2860, 3139, 3161, 3488, 3630, 3774, 4004,
|
|
||||||
4163, 4198, 4366, 4662, 4746, 4879, 5467, 5601, 5912, 5979,
|
|
||||||
6128, 6277, 6323, 6437, 6699, 6853, 7556, 7776, 7795, 8099,
|
|
||||||
8336, 8592, 8682, 8683, 8818, 8904, 9375, 9466, 9551, 9708)]
|
|
||||||
[InlineData(GuidV8Entropy.Weak,
|
|
||||||
6629058, 24114993, 40561510, 46245969, 46876997, 48747281, 80489854, 110237218, 117445694, 118974860,
|
|
||||||
135132579, 141760591, 149114066, 158322437, 159065333, 164925904, 173848639, 175086337, 175704556, 176335514,
|
|
||||||
200302773, 207133553, 230088723, 234521706, 239587338, 263755571, 264571928, 290118284, 292346548, 319322378,
|
|
||||||
320988273, 322638028, 324110126, 326855208, 332533719, 336668313, 350798512, 366520367, 380595181, 405033666,
|
|
||||||
410929500, 414099488, 417697882, 421269768, 431907031, 435262715, 442168482, 449797406, 458508845, 489039529,
|
|
||||||
503344305, 514934509, 537515867, 555210743, 563951463, 578783864, 580560518, 580902916, 605801607, 635231377,
|
|
||||||
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
|
||||||
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
|
||||||
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
|
||||||
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484)]
|
|
||||||
[InlineData(GuidV8Entropy.Strong,
|
|
||||||
6629058, 24114993, 40561510, 46245969, 46876997, 48747281, 80489854, 110237218, 117445694, 118974860,
|
|
||||||
135132579, 141760591, 149114066, 158322437, 159065333, 164925904, 173848639, 175086337, 175704556, 176335514,
|
|
||||||
200302773, 207133553, 230088723, 234521706, 239587338, 263755571, 264571928, 290118284, 292346548, 319322378,
|
|
||||||
320988273, 322638028, 324110126, 326855208, 332533719, 336668313, 350798512, 366520367, 380595181, 405033666,
|
|
||||||
410929500, 414099488, 417697882, 421269768, 431907031, 435262715, 442168482, 449797406, 458508845, 489039529,
|
|
||||||
503344305, 514934509, 537515867, 555210743, 563951463, 578783864, 580560518, 580902916, 605801607, 635231377,
|
|
||||||
636537435, 637241486, 676077268, 691630262, 696158602, 714007596, 715537265, 718873134, 724266320, 741049828,
|
|
||||||
749379956, 757561933, 758668417, 761735205, 770349479, 797570403, 805896481, 809050934, 821655964, 821980469,
|
|
||||||
830824227, 840429528, 851772315, 859717719, 859763860, 867675943, 912124563, 914880620, 923914294, 930298008,
|
|
||||||
932610035, 937468680, 945565998, 949277691, 949397209, 951283050, 953249971, 953953188, 976210158, 982233484)]
|
|
||||||
public void Guids_Differing_By_Microseconds_Should_Be_Sortable(GuidV8Entropy entropy, params int[] seconds)
|
|
||||||
{
|
|
||||||
var rng = new Random(25);
|
|
||||||
var referenceTime = new DateTime(2024, 05, 17, 15, 36, 13, 771, DateTimeKind.Utc);
|
|
||||||
SortedList<DateTime, Guid> expected = new(seconds.Length);
|
|
||||||
foreach (var s in seconds)
|
|
||||||
{
|
|
||||||
var timestamp = referenceTime.AddMicroseconds(s);
|
|
||||||
expected.Add(timestamp, GuidV8.NewGuid(timestamp, entropy));
|
|
||||||
}
|
|
||||||
|
|
||||||
var sut = expected.Values.ToArray();
|
|
||||||
rng.Shuffle(sut);
|
|
||||||
|
|
||||||
sut.Order().Should().BeEquivalentTo(expected.Select(x => x.Value));
|
|
||||||
sut.OrderDescending().Should().BeEquivalentTo(expected.Reverse().Select(x => x.Value));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
Core.Tests/SystemIOStreamExtensionsTests/Populate.cs
Normal file
58
Core.Tests/SystemIOStreamExtensionsTests/Populate.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using Just.Core.Extensions;
|
||||||
|
|
||||||
|
namespace Just.Core.Tests.SystemIOStreamExtensionsTests;
|
||||||
|
|
||||||
|
public class Populate
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(0, 0)]
|
||||||
|
[InlineData(0, 1)]
|
||||||
|
[InlineData(0, 3)]
|
||||||
|
[InlineData(0, 5)]
|
||||||
|
[InlineData(3, 0)]
|
||||||
|
[InlineData(3, 1)]
|
||||||
|
[InlineData(3, 5)]
|
||||||
|
[InlineData(5, 0)]
|
||||||
|
[InlineData(5, 1)]
|
||||||
|
[InlineData(5, 5)]
|
||||||
|
public void WhenCalled_ShouldPopulateSpecifiedRange(int offset, int length)
|
||||||
|
{
|
||||||
|
byte[] streamContent = [0x01, 0x02, 0x03, 0x04, 0x05,];
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[10];
|
||||||
|
|
||||||
|
stream.Populate(buffer, offset, length);
|
||||||
|
|
||||||
|
buffer.Skip(offset).Take(length).Should().Equal(streamContent.Take(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, }, 4)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 4)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 5)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, }, 5)]
|
||||||
|
public void WhenStreamContainsSameOrGreaterAmmountOfItems_ShouldPopulateBuffer(byte[] streamContent, int bufferSize)
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
|
||||||
|
stream.Populate(buffer);
|
||||||
|
|
||||||
|
buffer.Should().Equal(streamContent.Take(bufferSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, }, 5)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 6)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 10)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, }, 9)]
|
||||||
|
public void WhenStreamContainsLessItems_ShouldThrowEndOfStreamException(byte[] streamContent, int bufferSize)
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
|
||||||
|
Action action = () => stream.Populate(buffer);
|
||||||
|
|
||||||
|
action.Should().Throw<EndOfStreamException>();
|
||||||
|
}
|
||||||
|
}
|
||||||
72
Core.Tests/SystemIOStreamExtensionsTests/PopulateAsync.cs
Normal file
72
Core.Tests/SystemIOStreamExtensionsTests/PopulateAsync.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using Just.Core.Extensions;
|
||||||
|
|
||||||
|
namespace Just.Core.Tests.SystemIOStreamExtensionsTests;
|
||||||
|
|
||||||
|
public class PopulateAsync
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task WhenCancellationRequested_ShouldThrowOperationCanceledException()
|
||||||
|
{
|
||||||
|
using var cts = new CancellationTokenSource();
|
||||||
|
byte[] streamContent = [0x01, 0x02, 0x03, 0x04, 0x05,];
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[5];
|
||||||
|
|
||||||
|
Func<Task> action = async () => await stream.PopulateAsync(buffer, cts.Token);
|
||||||
|
cts.Cancel();
|
||||||
|
|
||||||
|
await action.Should().ThrowAsync<OperationCanceledException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(0, 0)]
|
||||||
|
[InlineData(0, 1)]
|
||||||
|
[InlineData(0, 3)]
|
||||||
|
[InlineData(0, 5)]
|
||||||
|
[InlineData(3, 0)]
|
||||||
|
[InlineData(3, 1)]
|
||||||
|
[InlineData(3, 5)]
|
||||||
|
[InlineData(5, 0)]
|
||||||
|
[InlineData(5, 1)]
|
||||||
|
[InlineData(5, 5)]
|
||||||
|
public async Task WhenCalled_ShouldPopulateSpecifiedRange(int offset, int length)
|
||||||
|
{
|
||||||
|
byte[] streamContent = [0x01, 0x02, 0x03, 0x04, 0x05,];
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[10];
|
||||||
|
|
||||||
|
await stream.PopulateAsync(buffer, offset, length);
|
||||||
|
|
||||||
|
buffer.Skip(offset).Take(length).Should().Equal(streamContent.Take(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, }, 4)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 4)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 5)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, }, 5)]
|
||||||
|
public async Task WhenStreamContainsSameOrGreaterAmmountOfItems_ShouldPopulateBuffer(byte[] streamContent, int bufferSize)
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
|
||||||
|
await stream.PopulateAsync(buffer);
|
||||||
|
|
||||||
|
buffer.Should().Equal(streamContent.Take(bufferSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, }, 5)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 6)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, }, 10)]
|
||||||
|
[InlineData(new byte[]{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, }, 9)]
|
||||||
|
public async Task WhenStreamContainsLessItems_ShouldThrowEndOfStreamException(byte[] streamContent, int bufferSize)
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream(streamContent);
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
|
||||||
|
Func<Task> action = async () => await stream.PopulateAsync(buffer);
|
||||||
|
|
||||||
|
await action.Should().ThrowAsync<EndOfStreamException>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,8 @@ public static class Base32
|
|||||||
[Pure]
|
[Pure]
|
||||||
public static int Encode(ReadOnlySpan<byte> input, Span<char> output)
|
public static int Encode(ReadOnlySpan<byte> input, Span<char> output)
|
||||||
{
|
{
|
||||||
|
if (input.IsEmpty) return 0;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
ReadOnlySpan<char> alphabet = Alphabet;
|
ReadOnlySpan<char> alphabet = Alphabet;
|
||||||
for (int offset = 0; offset < input.Length;)
|
for (int offset = 0; offset < input.Length;)
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ public static class Base64Url
|
|||||||
|
|
||||||
[Pure] public static int Encode(ReadOnlySpan<byte> input, Span<char> output)
|
[Pure] public static int Encode(ReadOnlySpan<byte> input, Span<char> output)
|
||||||
{
|
{
|
||||||
|
if (input.IsEmpty) return 0;
|
||||||
|
|
||||||
var charlen = 8 * ((input.Length + 5) / 6);
|
var charlen = 8 * ((input.Length + 5) / 6);
|
||||||
Span<char> chars = stackalloc char[charlen];
|
Span<char> chars = stackalloc char[charlen];
|
||||||
Convert.TryToBase64Chars(input, chars, out int charsWritten);
|
Convert.TryToBase64Chars(input, chars, out int charsWritten);
|
||||||
|
|||||||
90
Core/Collections/ImmutableSequence.cs
Normal file
90
Core/Collections/ImmutableSequence.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
|
namespace Just.Core.Collections;
|
||||||
|
|
||||||
|
public class ImmutableSequence<T> :
|
||||||
|
IEnumerable<T>,
|
||||||
|
IReadOnlyList<T>,
|
||||||
|
IEquatable<ImmutableSequence<T>>
|
||||||
|
{
|
||||||
|
private static readonly int InitialHash = typeof(ImmutableSequence<T>).GetHashCode();
|
||||||
|
private static readonly Func<T?, T?, bool> CompareItem = EqualityComparer<T>.Default.Equals;
|
||||||
|
private readonly ImmutableList<T> _values;
|
||||||
|
|
||||||
|
public ImmutableSequence(ImmutableList<T> values) => _values = values;
|
||||||
|
public ImmutableSequence() : this(ImmutableArray<T>.Empty)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public ImmutableSequence(IEnumerable<T> values)
|
||||||
|
{
|
||||||
|
_values = [..values];
|
||||||
|
}
|
||||||
|
public ImmutableSequence(ReadOnlySpan<T> values) : this(ImmutableList.Create(values))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty => _values.IsEmpty;
|
||||||
|
public int Count => _values.Count;
|
||||||
|
public T this[int index] => _values[index];
|
||||||
|
public T this[Index index] => _values[index];
|
||||||
|
public ImmutableSequence<T> this[Range range]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var (offset, count) = range.GetOffsetAndLength(_values.Count);
|
||||||
|
return ConstructNew(_values.GetRange(offset, count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual ImmutableSequence<T> ConstructNew(ImmutableList<T> values) => new(values);
|
||||||
|
|
||||||
|
public ImmutableSequence<T> Add(T value) => ConstructNew([.._values, value]);
|
||||||
|
public ImmutableSequence<T> AddFront(T value) => ConstructNew([value, .._values]);
|
||||||
|
|
||||||
|
public ImmutableList<T>.Enumerator GetEnumerator() => _values.GetEnumerator();
|
||||||
|
IEnumerator<T> IEnumerable<T>.GetEnumerator() => ((IEnumerable<T>)_values).GetEnumerator();
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_values).GetEnumerator();
|
||||||
|
|
||||||
|
public override string ToString() => string.Join(Environment.NewLine, _values);
|
||||||
|
|
||||||
|
public virtual bool Equals([NotNullWhen(true)] ImmutableSequence<T>? other)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(this, other))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_values.Count != other?._values.Count)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _values.Count; i++)
|
||||||
|
{
|
||||||
|
if (!CompareItem(_values[i], other._values[i]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals([NotNullWhen(true)] object? obj) => Equals(obj as ImmutableSequence<T>);
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
HashCode hash = new();
|
||||||
|
hash.Add(InitialHash);
|
||||||
|
|
||||||
|
foreach (var value in _values)
|
||||||
|
{
|
||||||
|
hash.Add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash.ToHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(ImmutableSequence<T>? left, ImmutableSequence<T>? right) => left is null ? right is null : left.Equals(right);
|
||||||
|
public static bool operator !=(ImmutableSequence<T>? left, ImmutableSequence<T>? right) => !(left == right);
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<Description>Small .Net library with useful helper classes, functions and extensions.</Description>
|
<Description>Small .Net library with useful helper classes, functions and extensions.</Description>
|
||||||
<PackageTags>extensions;helpers;helper-functions</PackageTags>
|
<PackageTags>extensions;helpers;helper-functions</PackageTags>
|
||||||
<Authors>JustFixMe</Authors>
|
<Authors>JustFixMe</Authors>
|
||||||
<Copyright>Copyright (c) 2023 JustFixMe</Copyright>
|
<Copyright>Copyright (c) 2023,2024 JustFixMe</Copyright>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
<RepositoryUrl>https://github.com/JustFixMe/Just.Core/</RepositoryUrl>
|
<RepositoryUrl>https://github.com/JustFixMe/Just.Core/</RepositoryUrl>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public static class SystemIOStreamExtensions
|
|||||||
=> stream.Populate(buffer.AsSpan());
|
=> stream.Populate(buffer.AsSpan());
|
||||||
public static void Populate(this Stream stream, Span<byte> buffer)
|
public static void Populate(this Stream stream, Span<byte> buffer)
|
||||||
{
|
{
|
||||||
do
|
while (buffer.Length > 0)
|
||||||
{
|
{
|
||||||
var readed = stream.Read(buffer);
|
var readed = stream.Read(buffer);
|
||||||
|
|
||||||
@@ -19,7 +19,6 @@ public static class SystemIOStreamExtensions
|
|||||||
|
|
||||||
buffer = buffer[readed..];
|
buffer = buffer[readed..];
|
||||||
}
|
}
|
||||||
while (buffer.Length > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async ValueTask PopulateAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default)
|
public static async ValueTask PopulateAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default)
|
||||||
@@ -28,7 +27,7 @@ public static class SystemIOStreamExtensions
|
|||||||
=> await stream.PopulateAsync(buffer.AsMemory(offset, length), cancellationToken);
|
=> await stream.PopulateAsync(buffer.AsMemory(offset, length), cancellationToken);
|
||||||
public static async ValueTask PopulateAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default)
|
public static async ValueTask PopulateAsync(this Stream stream, Memory<byte> buffer, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
do
|
while (buffer.Length > 0)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
@@ -41,6 +40,5 @@ public static class SystemIOStreamExtensions
|
|||||||
|
|
||||||
buffer = buffer[readed..];
|
buffer = buffer[readed..];
|
||||||
}
|
}
|
||||||
while (buffer.Length > 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,28 +13,28 @@ public static class GuidV8
|
|||||||
[Pure]
|
[Pure]
|
||||||
public static Guid NewGuid(DateTime dateTime, GuidV8Entropy entropy = GuidV8Entropy.Strong)
|
public static Guid NewGuid(DateTime dateTime, GuidV8Entropy entropy = GuidV8Entropy.Strong)
|
||||||
{
|
{
|
||||||
var timestamp = dateTime.ToBinary() & 0x3FFF_FFFF_FFFF_FFFF;
|
var epoch = dateTime.Subtract(DateTime.UnixEpoch);
|
||||||
|
var timestamp = epoch.Ticks / (TimeSpan.TicksPerMillisecond / 10);
|
||||||
|
|
||||||
Span<byte> ts = stackalloc byte[8];
|
Span<byte> ts = stackalloc byte[8];
|
||||||
MemoryMarshal.Write(ts, timestamp);
|
MemoryMarshal.Write(ts, timestamp);
|
||||||
|
|
||||||
Span<byte> bytes = stackalloc byte[16];
|
Span<byte> bytes = stackalloc byte[16];
|
||||||
|
|
||||||
ts[4..].CopyTo(bytes[..4]);
|
ts[0..2].CopyTo(bytes[4..6]);
|
||||||
ts[2..4].CopyTo(bytes[4..6]);
|
ts[2..6].CopyTo(bytes[..4]);
|
||||||
ts[..2].CopyTo(bytes[6..8]);
|
|
||||||
|
|
||||||
bytes[7] = (byte)((bytes[7] & 0x0f) | 0x80);
|
|
||||||
|
|
||||||
if (entropy == GuidV8Entropy.Strong)
|
if (entropy == GuidV8Entropy.Strong)
|
||||||
{
|
{
|
||||||
RandomNumberGenerator.Fill(bytes[8..]);
|
RandomNumberGenerator.Fill(bytes[6..]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Random.Shared.NextBytes(bytes[8..]);
|
Random.Shared.NextBytes(bytes[6..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bytes[7] = (byte)((bytes[7] & 0x0F) | 0x80);
|
||||||
|
|
||||||
return new Guid(bytes);
|
return new Guid(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2023 JustFixMe
|
Copyright (c) 2023,2024 JustFixMe
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
Reference in New Issue
Block a user