Compare commits

...

3 Commits

22 changed files with 336 additions and 107 deletions

View File

@ -9,29 +9,119 @@
<a href="https://github.com/oliverbooth/X10D/blob/master/LICENSE.md"><img src="https://img.shields.io/github/license/oliverbooth/X10D?style=flat-square" alt="MIT License" title="MIT License"></a>
</p>
### About
## About
X10D (pronounced *extend*), is a .NET package that provides extension methods for numerous types. The purpose of this library is to simplify a codebase by reducing the need for repeated code when performing common operations. Simplify your codebase. Take advantage of .NET. Use extension methods.
*(I'm also [dogfooding](https://www.pcmag.com/encyclopedia/term/dogfooding) this library, so there's that.)*
### What are extension methods?
Extension methods are a clever .NET feature that augment existing types with new functionality. They are defined as
static methods in a static class, and are called as if they were instance methods on the type they are extending. Take,
for example, the following code:
```csharp
public static class Program
{
public static void Main()
{
string str = "Hello, world!";
Console.WriteLine(str.Reverse());
}
}
public static class StringExtensions
{
public static string Reverse(this string str)
{
char[] chars = str.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
}
```
This will print `!dlrow ,olleH` to the console. The `Reverse` method is defined in the `StringExtensions` class, yet is
called as if it were an instance method on the `str` variable, even though it's not.
### Why use extension methods?
Extension methods were introduced when LINQ was added to .NET. LINQ is a set of extension methods that provide a way to
query, filter, and transform data. If you were to access LINQ's methods statically, you would have to write code like
this:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
IEnumerable<int> evenNumbers = Enumerable.Where(numbers, x => x % 2 == 0);
IEnumerable<int> doubledNumbers = Enumerable.Select(evenNumbers, x => x * 2);
int sum = Enumerable.Sum(doubledNumbers);
Console.WriteLine(sum);
}
}
```
And if you wanted to one-line this, you'd have to write this:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(Enumerable.Sum(Enumerable.Select(Enumerable.Where(numbers, x => x % 2 == 0), x => x * 2)));
}
}
```
This is a lot of code to write, and it's not very readable. The nested method calls make it incredibly difficult to
follow. However, because LINQ is implemented as extension methods, you can write the following code instead:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(numbers.Where(x => x % 2 == 0).Select(x => x * 2).Sum());
}
}
```
Because the methods are called as if they were instance methods on `IEnumerable<T>`, they can be chained together,
making the code much more readable.
X10D aims to provide these same benefits as LINQ, but for dozens of other types and for countless other use cases. See
the [documentation](#documentation) for a complete breakdown of what's available.
## Installation
### NuGet installation
```ps
Install-Package X10D -Version 4.0.0
```
### Manual installation
Download the [latest release](https://github.com/oliverbooth/X10D/releases/latest) from this repository and adding a direct assembly reference for your chosen platform.
### Unity installation
For the Unity installation guide, refer to the [README.md in X10D.Unity](X10D.Unity/README.md).
## Features
I'm planning on writing complete and extensive documentation in the near future. As of this time, feel free to browse the source or the API using your favourite IDE.
For those familiar with the 2.6.0 API, please read [CHANGELOG.md](CHANGELOG.md) for a complete list of changes. **3.0.0 is a major release and introduces many breaking changes.**
## Documentation
Documentation and the API reference is available at https://oliverbooth.github.io/X10D/index.html. *I'm sorry this took
so long to get up and running. DocFX will be the death of me.*
## Contributing
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
X10D is released under the MIT License. See [here](https://github.com/oliverbooth/X10D/blob/main/LICENSE.md) for more details.

View File

@ -33,7 +33,7 @@ internal class DoubleTests
var expected = new byte[] { 0x40, 0x45, 0x40, 0, 0, 0, 0, 0 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -44,7 +44,7 @@ internal class DoubleTests
var expected = new byte[] { 0, 0, 0, 0, 0, 0x40, 0x45, 0x40 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -53,7 +53,7 @@ internal class DoubleTests
{
const double value = 42.5;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
[Test]
@ -61,6 +61,6 @@ internal class DoubleTests
{
const double value = 42.5;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
}

View File

@ -33,7 +33,7 @@ internal class Int16Tests
byte[] expected = { 0x0F, 0 };
Span<byte> actual = stackalloc byte[2];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -44,7 +44,7 @@ internal class Int16Tests
byte[] expected = { 0, 0x0F };
Span<byte> actual = stackalloc byte[2];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -53,7 +53,7 @@ internal class Int16Tests
{
const short value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
@ -61,6 +61,6 @@ internal class Int16Tests
{
const short value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -33,7 +33,7 @@ internal class Int32Tests
var expected = new byte[] { 0, 0, 0, 0x0F };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -44,7 +44,7 @@ internal class Int32Tests
var expected = new byte[] { 0x0F, 0, 0, 0 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -53,7 +53,7 @@ internal class Int32Tests
{
const int value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
[Test]
@ -61,6 +61,6 @@ internal class Int32Tests
{
const int value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
}

View File

@ -33,7 +33,7 @@ internal class Int64Tests
byte[] expected = { 0x0F, 0, 0, 0, 0, 0, 0, 0 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -44,7 +44,7 @@ internal class Int64Tests
byte[] expected = { 0, 0, 0, 0, 0, 0, 0, 0x0F };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -53,7 +53,7 @@ internal class Int64Tests
{
const long value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
@ -61,6 +61,6 @@ internal class Int64Tests
{
const long value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -33,7 +33,7 @@ internal class SingleTests
var expected = new byte[] { 0x42, 0x2A, 0, 0 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -44,7 +44,7 @@ internal class SingleTests
var expected = new byte[] { 0, 0, 0x2A, 0x42 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -53,7 +53,7 @@ internal class SingleTests
{
const float value = 42.5f;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
[Test]
@ -61,6 +61,6 @@ internal class SingleTests
{
const float value = 42.5f;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
}

View File

@ -1,4 +1,4 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
@ -33,7 +33,7 @@ internal class UInt16Tests
byte[] expected = { 0x0F, 0 };
Span<byte> actual = stackalloc byte[2];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -45,7 +45,7 @@ internal class UInt16Tests
byte[] expected = { 0, 0x0F };
Span<byte> actual = stackalloc byte[2];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -55,7 +55,7 @@ internal class UInt16Tests
{
const ushort value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
@ -63,6 +63,6 @@ internal class UInt16Tests
{
const ushort value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -1,4 +1,4 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
@ -33,7 +33,7 @@ internal class UInt32Tests
byte[] expected = { 0x0F, 0, 0, 0 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -45,7 +45,7 @@ internal class UInt32Tests
byte[] expected = { 0, 0, 0, 0x0F };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -55,7 +55,7 @@ internal class UInt32Tests
{
const uint value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
@ -63,6 +63,6 @@ internal class UInt32Tests
{
const uint value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -1,4 +1,4 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
@ -33,7 +33,7 @@ internal class UInt64Tests
byte[] expected = { 0x0F, 0, 0, 0, 0, 0, 0, 0 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteLittleEndian(actual));
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -45,7 +45,7 @@ internal class UInt64Tests
byte[] expected = { 0, 0, 0, 0, 0, 0, 0, 0x0F };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteBigEndian(actual));
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
@ -55,7 +55,7 @@ internal class UInt64Tests
{
const ulong value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndian(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
@ -63,6 +63,6 @@ internal class UInt64Tests
{
const ulong value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndian(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -18,7 +18,7 @@ public static class DecimalExtensions
public static byte[] GetBigEndianBytes(this decimal value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -31,7 +31,7 @@ public static class DecimalExtensions
public static byte[] GetLittleEndianBytes(this decimal value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -41,15 +41,15 @@ public static class DecimalExtensions
/// <param name="value">The <see cref="float" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this decimal value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this decimal value, Span<byte> destination)
{
Span<int> buffer = stackalloc int[4];
GetBits(value, buffer);
if (buffer[0].TryWriteBigEndian(destination[..4]) &&
buffer[1].TryWriteBigEndian(destination[4..8]) &&
buffer[2].TryWriteBigEndian(destination[8..12]) &&
buffer[3].TryWriteBigEndian(destination[12..]))
if (buffer[0].TryWriteBigEndianBytes(destination[..4]) &&
buffer[1].TryWriteBigEndianBytes(destination[4..8]) &&
buffer[2].TryWriteBigEndianBytes(destination[8..12]) &&
buffer[3].TryWriteBigEndianBytes(destination[12..]))
{
if (BitConverter.IsLittleEndian)
{
@ -69,15 +69,15 @@ public static class DecimalExtensions
/// <param name="value">The <see cref="float" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this decimal value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this decimal value, Span<byte> destination)
{
Span<int> buffer = stackalloc int[4];
GetBits(value, buffer);
if (buffer[0].TryWriteLittleEndian(destination[..4]) &&
buffer[1].TryWriteLittleEndian(destination[4..8]) &&
buffer[2].TryWriteLittleEndian(destination[8..12]) &&
buffer[3].TryWriteLittleEndian(destination[12..]))
if (buffer[0].TryWriteLittleEndianBytes(destination[..4]) &&
buffer[1].TryWriteLittleEndianBytes(destination[4..8]) &&
buffer[2].TryWriteLittleEndianBytes(destination[8..12]) &&
buffer[3].TryWriteLittleEndianBytes(destination[12..]))
{
if (!BitConverter.IsLittleEndian)
{

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
@ -18,7 +18,7 @@ public static class DoubleExtensions
public static byte[] GetBigEndianBytes(this double value)
{
Span<byte> buffer = stackalloc byte[8];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -31,7 +31,7 @@ public static class DoubleExtensions
public static byte[] GetLittleEndianBytes(this double value)
{
Span<byte> buffer = stackalloc byte[8];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -41,7 +41,7 @@ public static class DoubleExtensions
/// <param name="value">The <see cref="float" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this double value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this double value, Span<byte> destination)
{
#if NET5_0_OR_GREATER
return BinaryPrimitives.TryWriteDoubleBigEndian(destination, value);
@ -62,7 +62,7 @@ public static class DoubleExtensions
/// <param name="value">The <see cref="float" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this double value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this double value, Span<byte> destination)
{
#if NET5_0_OR_GREATER
return BinaryPrimitives.TryWriteDoubleLittleEndian(destination, value);

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
@ -17,7 +17,7 @@ public static class Int16Extensions
public static byte[] GetBigEndianBytes(this short value)
{
Span<byte> buffer = stackalloc byte[2];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -30,7 +30,7 @@ public static class Int16Extensions
public static byte[] GetLittleEndianBytes(this short value)
{
Span<byte> buffer = stackalloc byte[2];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -40,7 +40,7 @@ public static class Int16Extensions
/// <param name="value">The <see cref="short" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this short value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this short value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteInt16BigEndian(destination, value);
}
@ -51,7 +51,7 @@ public static class Int16Extensions
/// <param name="value">The <see cref="short" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this short value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this short value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteInt16LittleEndian(destination, value);
}

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
@ -17,7 +17,7 @@ public static class Int32Extensions
public static byte[] GetBigEndianBytes(this int value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -30,7 +30,7 @@ public static class Int32Extensions
public static byte[] GetLittleEndianBytes(this int value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -40,7 +40,7 @@ public static class Int32Extensions
/// <param name="value">The <see cref="int" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this int value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this int value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteInt32BigEndian(destination, value);
}
@ -51,7 +51,7 @@ public static class Int32Extensions
/// <param name="value">The <see cref="int" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this int value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this int value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteInt32LittleEndian(destination, value);
}

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
@ -17,7 +17,7 @@ public static class Int64Extensions
public static byte[] GetBigEndianBytes(this long value)
{
Span<byte> buffer = stackalloc byte[8];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -30,7 +30,7 @@ public static class Int64Extensions
public static byte[] GetLittleEndianBytes(this long value)
{
Span<byte> buffer = stackalloc byte[8];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -40,7 +40,7 @@ public static class Int64Extensions
/// <param name="value">The <see cref="long" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this long value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this long value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteInt64BigEndian(destination, value);
}
@ -51,7 +51,7 @@ public static class Int64Extensions
/// <param name="value">The <see cref="long" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this long value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this long value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteInt64LittleEndian(destination, value);
}

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
#if !NET5_0_OR_GREATER
using System.Runtime.InteropServices;
@ -20,7 +20,7 @@ public static class SingleExtensions
public static byte[] GetBigEndianBytes(this float value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -33,7 +33,7 @@ public static class SingleExtensions
public static byte[] GetLittleEndianBytes(this float value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -43,7 +43,7 @@ public static class SingleExtensions
/// <param name="value">The <see cref="float" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this float value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this float value, Span<byte> destination)
{
#if NET5_0_OR_GREATER
return BinaryPrimitives.TryWriteSingleBigEndian(destination, value);
@ -64,7 +64,7 @@ public static class SingleExtensions
/// <param name="value">The <see cref="float" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this float value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this float value, Span<byte> destination)
{
#if NET5_0_OR_GREATER
return BinaryPrimitives.TryWriteSingleLittleEndian(destination, value);

View File

@ -25,7 +25,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[2];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -50,7 +50,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -75,7 +75,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[8];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -101,7 +101,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[2];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -127,7 +127,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -153,7 +153,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[8];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -178,7 +178,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -204,7 +204,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[8];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -230,7 +230,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[16];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -255,7 +255,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[2];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -280,7 +280,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[4];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -305,7 +305,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[8];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -330,7 +330,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[4];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -356,7 +356,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[8];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return stream.WriteInternal(buffer);
}
@ -382,7 +382,7 @@ public static partial class StreamExtensions
}
Span<byte> buffer = stackalloc byte[16];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return stream.WriteInternal(buffer);
}

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
@ -18,7 +18,7 @@ public static class UInt16Extensions
public static byte[] GetBigEndianBytes(this ushort value)
{
Span<byte> buffer = stackalloc byte[2];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -31,7 +31,7 @@ public static class UInt16Extensions
public static byte[] GetLittleEndianBytes(this ushort value)
{
Span<byte> buffer = stackalloc byte[2];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -41,7 +41,7 @@ public static class UInt16Extensions
/// <param name="value">The <see cref="ushort" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this ushort value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this ushort value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteUInt16BigEndian(destination, value);
}
@ -52,7 +52,7 @@ public static class UInt16Extensions
/// <param name="value">The <see cref="ushort" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this ushort value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this ushort value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteUInt16LittleEndian(destination, value);
}

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
@ -18,7 +18,7 @@ public static class UInt32Extensions
public static byte[] GetBigEndianBytes(this uint value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -31,7 +31,7 @@ public static class UInt32Extensions
public static byte[] GetLittleEndianBytes(this uint value)
{
Span<byte> buffer = stackalloc byte[4];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -41,7 +41,7 @@ public static class UInt32Extensions
/// <param name="value">The <see cref="uint" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this uint value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this uint value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteUInt32BigEndian(destination, value);
}
@ -52,7 +52,7 @@ public static class UInt32Extensions
/// <param name="value">The <see cref="uint" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this uint value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this uint value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteUInt32LittleEndian(destination, value);
}

View File

@ -1,4 +1,4 @@
using System.Buffers.Binary;
using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
@ -18,7 +18,7 @@ public static class UInt64Extensions
public static byte[] GetBigEndianBytes(this ulong value)
{
Span<byte> buffer = stackalloc byte[8];
value.TryWriteBigEndian(buffer);
value.TryWriteBigEndianBytes(buffer);
return buffer.ToArray();
}
@ -31,7 +31,7 @@ public static class UInt64Extensions
public static byte[] GetLittleEndianBytes(this ulong value)
{
Span<byte> buffer = stackalloc byte[8];
value.TryWriteLittleEndian(buffer);
value.TryWriteLittleEndianBytes(buffer);
return buffer.ToArray();
}
@ -41,7 +41,7 @@ public static class UInt64Extensions
/// <param name="value">The <see cref="ulong" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteBigEndian(this ulong value, Span<byte> destination)
public static bool TryWriteBigEndianBytes(this ulong value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteUInt64BigEndian(destination, value);
}
@ -52,7 +52,7 @@ public static class UInt64Extensions
/// <param name="value">The <see cref="ulong" /> value.</param>
/// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
/// <returns><see langword="true" /> if the conversion was successful; otherwise, <see langword="false" />.</returns>
public static bool TryWriteLittleEndian(this ulong value, Span<byte> destination)
public static bool TryWriteLittleEndianBytes(this ulong value, Span<byte> destination)
{
return BinaryPrimitives.TryWriteUInt64LittleEndian(destination, value);
}

View File

@ -1 +1,86 @@
# Add your introductions here!
## X10D
X10D (pronounced *extend*), is a .NET package that provides extension methods for numerous types. The purpose of this library is to simplify a codebase by reducing the need for repeated code when performing common operations. Simplify your codebase. Take advantage of .NET. Use extension methods.
*(I'm also [dogfooding](https://www.pcmag.com/encyclopedia/term/dogfooding) this library, so there's that.)*
### What are extension methods?
Extension methods are a clever .NET feature that augment existing types with new functionality. They are defined as
static methods in a static class, and are called as if they were instance methods on the type they are extending. Take,
for example, the following code:
```csharp
public static class Program
{
public static void Main()
{
string str = "Hello, world!";
Console.WriteLine(str.Reverse());
}
}
public static class StringExtensions
{
public static string Reverse(this string str)
{
char[] chars = str.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
}
```
This will print `!dlrow ,olleH` to the console. The `Reverse` method is defined in the `StringExtensions` class, yet is
called as if it were an instance method on the `str` variable, even though it's not.
### Why use extension methods?
Extension methods were introduced when LINQ was added to .NET. LINQ is a set of extension methods that provide a way to
query, filter, and transform data. If you were to access LINQ's methods statically, you would have to write code like
this:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
IEnumerable<int> evenNumbers = Enumerable.Where(numbers, x => x % 2 == 0);
IEnumerable<int> doubledNumbers = Enumerable.Select(evenNumbers, x => x * 2);
int sum = Enumerable.Sum(doubledNumbers);
Console.WriteLine(sum);
}
}
```
And if you wanted to one-line this, you'd have to write this:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(Enumerable.Sum(Enumerable.Select(Enumerable.Where(numbers, x => x % 2 == 0), x => x * 2)));
}
}
```
This is a lot of code to write, and it's not very readable. The nested method calls make it incredibly difficult to
follow. However, because LINQ is implemented as extension methods, you can write the following code instead:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(numbers.Where(x => x % 2 == 0).Select(x => x * 2).Sum());
}
}
```
Because the methods are called as if they were instance methods on `IEnumerable<T>`, they can be chained together,
making the code much more readable.
X10D aims to provide these same benefits as LINQ, but for dozens of other types and for countless other use cases.

View File

@ -0,0 +1,52 @@
# Migration from 3.x.x
X10D 4.0.0 is a major release that introduces breaking changes. This document will help you migrate your code from 3.x.x
to 4.0.0.
## Removed APIs
### X10D.DSharpPlus library
The `X10D.DSharpPlus` library has been removed. This library was used to provide extension methods for the DSharpPlus
wrapper library. However, I have since moved to using a different library, and as such, I feel it is no longer in the
scope of X10D or in my best interest to maintain it. The library will remain available on NuGet until DSharpPlus release
5.0.0 as stable, and X10D.DSharpPlus will NOT be part of X10D 4.0.0. I'm sorry for any inconvenience this may cause.
### `Endianness` enum
The `Endianness` enum was used to specify the endianness of data when reading or writing to a stream. This was causing
some clutter, and makes it harder to develop X10D, so it was removed. In its stead, any method which accepted an
`Endianness` parameter now has two overloads: one for big-endian, and one for little-endian. For example, the following
code:
```csharp
someStream.Write(12345, Endianness.BigEndian);
// or
Span<byte> buffer = stackalloc byte[4];
12345.TryWriteBytes(buffer, Endianness.BigEndian);
```
would now be written as:
```csharp
someStream.WriteBigEndian(12345);
// or
Span<byte> buffer = stackalloc byte[4];
12345.TryWriteLittleEndianBytes(buffer);
```
### `IEnumerable<T>.ConcatOne(T)` extension method
The `IEnumerable<T>.ConcatOne` extension method was used to concatenate a single item to an enumerable. At the time, I
was unaware of the `Enumerable.Append` method, which does the same thing. As such, `ConcatOne` has been removed. There
is no migration path for this, as the built in `Append` method from LINQ is a drop-in replacement.
## Exception Changes
If you were previously catching TypeInitializationException when calling `Stream.GetHash<>` or `Stream.TryWriteHash<>`,
you will now need to catch a ArgumentException instead. The justification for this change is that ArgumentException is
more general, and more easily understood by developers.

View File

@ -1,2 +1,4 @@
- name: Introduction
href: intro.md
- name: Migration from 3.x.x
href: migration-from-3.x.x.md