mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-25 11:58:48 +00:00
Compare commits
6 Commits
30b7a465a7
...
f238d420f4
Author | SHA1 | Date | |
---|---|---|---|
f238d420f4 | |||
5ff7b68b37 | |||
9aed06b533 | |||
71b0bec85c | |||
50d9cad2f3 | |||
1157e36eff |
1
.github/workflows/docfx.yml
vendored
1
.github/workflows/docfx.yml
vendored
@ -3,6 +3,7 @@ name: DocFX
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docfx:
|
docfx:
|
||||||
|
@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
BigEndian/LittleEndian methods.
|
BigEndian/LittleEndian methods.
|
||||||
- X10D: `Stream.GetHash<>` and `Stream.TryWriteHash<>` now throw ArgumentException in lieu of
|
- X10D: `Stream.GetHash<>` and `Stream.TryWriteHash<>` now throw ArgumentException in lieu of
|
||||||
TypeInitializationException.
|
TypeInitializationException.
|
||||||
|
- X10D: `Stream.GetHash<>` and `Stream.TryWriteHash<>` are now more efficient on second and subsequent calls.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using X10D.Linq;
|
using X10D.Linq;
|
||||||
|
|
||||||
namespace X10D.Tests.Linq;
|
namespace X10D.Tests.Linq;
|
||||||
@ -16,7 +16,7 @@ internal class ReadOnlySpanTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void AllShouldBeCorrect()
|
public void AllShouldBeCorrect()
|
||||||
{
|
{
|
||||||
var span = new ReadOnlySpan<int>(new[] {2, 4, 6, 8, 10});
|
var span = new ReadOnlySpan<int>(new[] { 2, 4, 6, 8, 10 });
|
||||||
Assert.That(span.All(x => x % 2 == 0));
|
Assert.That(span.All(x => x % 2 == 0));
|
||||||
Assert.That(span.All(x => x % 2 == 1), Is.False);
|
Assert.That(span.All(x => x % 2 == 1), Is.False);
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ internal class ReadOnlySpanTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void AnyShouldBeCorrect()
|
public void AnyShouldBeCorrect()
|
||||||
{
|
{
|
||||||
var span = new ReadOnlySpan<int>(new[] {2, 4, 6, 8, 10});
|
var span = new ReadOnlySpan<int>(new[] { 2, 4, 6, 8, 10 });
|
||||||
Assert.That(span.Any(x => x % 2 == 0));
|
Assert.That(span.Any(x => x % 2 == 0));
|
||||||
Assert.That(span.Any(x => x % 2 == 1), Is.False);
|
Assert.That(span.Any(x => x % 2 == 1), Is.False);
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ internal class ReadOnlySpanTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void Count_ShouldReturn5_ForEvenNumbers_GivenNumbers1To10()
|
public void Count_ShouldReturn5_ForEvenNumbers_GivenNumbers1To10()
|
||||||
{
|
{
|
||||||
var span = new ReadOnlySpan<int>(new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
|
var span = new ReadOnlySpan<int>(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||||
Assert.That(span.Count(i => i % 2 == 0), Is.EqualTo(5));
|
Assert.That(span.Count(i => i % 2 == 0), Is.EqualTo(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using X10D.Linq;
|
using X10D.Linq;
|
||||||
|
|
||||||
namespace X10D.Tests.Linq;
|
namespace X10D.Tests.Linq;
|
||||||
@ -16,7 +16,7 @@ internal class SpanTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void AllShouldBeCorrect()
|
public void AllShouldBeCorrect()
|
||||||
{
|
{
|
||||||
var span = new Span<int>(new[] {2, 4, 6, 8, 10});
|
var span = new Span<int>(new[] { 2, 4, 6, 8, 10 });
|
||||||
Assert.That(span.All(x => x % 2 == 0));
|
Assert.That(span.All(x => x % 2 == 0));
|
||||||
Assert.That(span.All(x => x % 2 == 1), Is.False);
|
Assert.That(span.All(x => x % 2 == 1), Is.False);
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ internal class SpanTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void AnyShouldBeCorrect()
|
public void AnyShouldBeCorrect()
|
||||||
{
|
{
|
||||||
var span = new Span<int>(new[] {2, 4, 6, 8, 10});
|
var span = new Span<int>(new[] { 2, 4, 6, 8, 10 });
|
||||||
Assert.That(span.Any(x => x % 2 == 0));
|
Assert.That(span.Any(x => x % 2 == 0));
|
||||||
Assert.That(span.Any(x => x % 2 == 1), Is.False);
|
Assert.That(span.Any(x => x % 2 == 1), Is.False);
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ internal class SpanTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void Count_ShouldReturn5_ForEvenNumbers_GivenNumbers1To10()
|
public void Count_ShouldReturn5_ForEvenNumbers_GivenNumbers1To10()
|
||||||
{
|
{
|
||||||
var span = new Span<int>(new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
|
var span = new Span<int>(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
|
||||||
Assert.That(span.Count(i => i % 2 == 0), Is.EqualTo(5));
|
Assert.That(span.Count(i => i % 2 == 0), Is.EqualTo(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
523
X10D/src/IO/StreamExtensions.Reading.cs
Normal file
523
X10D/src/IO/StreamExtensions.Reading.cs
Normal file
@ -0,0 +1,523 @@
|
|||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace X10D.IO;
|
||||||
|
|
||||||
|
public static partial class StreamExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="decimal" /> from the current stream as big endian, and advances the stream position by sixteen
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static decimal ReadDecimalBigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int decimalSize = sizeof(decimal);
|
||||||
|
const int int32Size = sizeof(int);
|
||||||
|
const int partitionSize = decimalSize / int32Size;
|
||||||
|
|
||||||
|
Span<int> buffer = stackalloc int[partitionSize];
|
||||||
|
for (var index = 0; index < partitionSize; index++)
|
||||||
|
{
|
||||||
|
buffer[index] = stream.ReadInt32BigEndian();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
buffer.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
return new decimal(buffer);
|
||||||
|
#else
|
||||||
|
return new decimal(buffer.ToArray());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="decimal" /> from the current stream as big endian, and advances the stream position by sixteen
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static decimal ReadDecimalLittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int decimalSize = sizeof(decimal);
|
||||||
|
const int int32Size = sizeof(int);
|
||||||
|
const int partitionSize = decimalSize / int32Size;
|
||||||
|
|
||||||
|
Span<int> buffer = stackalloc int[partitionSize];
|
||||||
|
for (var index = 0; index < partitionSize; index++)
|
||||||
|
{
|
||||||
|
buffer[index] = stream.ReadInt32LittleEndian();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
buffer.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
return new decimal(buffer);
|
||||||
|
#else
|
||||||
|
return new decimal(buffer.ToArray());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="double" /> from the current stream as big endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static double ReadDoubleBigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
return BinaryPrimitives.ReadDoubleBigEndian(buffer);
|
||||||
|
#else
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
buffer.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return MemoryMarshal.Read<double>(buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="double" /> from the current stream as little endian, and advances the stream position by eight
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static double ReadDoubleLittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
return BinaryPrimitives.ReadDoubleLittleEndian(buffer);
|
||||||
|
#else
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
buffer.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return MemoryMarshal.Read<double>(buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="short" /> from the current stream as big endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static short ReadInt16BigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadInt16BigEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="short" /> from the current stream as little endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static short ReadInt16LittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadInt16LittleEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="int" /> from the current stream as big endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static int ReadInt32BigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadInt32BigEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="int" /> from the current stream as little endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static int ReadInt32LittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadInt32LittleEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="long" /> from the current stream as big endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static long ReadInt64BigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadInt64BigEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="long" /> from the current stream as little endian, and advances the stream position by eight
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
public static long ReadInt64LittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadInt64LittleEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="float" /> from the current stream as big endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static float ReadSingleBigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
return BinaryPrimitives.ReadSingleBigEndian(buffer);
|
||||||
|
#else
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
buffer.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return MemoryMarshal.Read<float>(buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="float" /> from the current stream as little endian, and advances the stream position by four
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static float ReadSingleLittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
return BinaryPrimitives.ReadSingleLittleEndian(buffer);
|
||||||
|
#else
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
buffer.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return MemoryMarshal.Read<float>(buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="ushort" /> from the current stream as big endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static ushort ReadUInt16BigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadUInt16BigEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="ushort" /> from the current stream as little endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static ushort ReadUInt16LittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadUInt16LittleEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="uint" /> from the current stream as big endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static uint ReadUInt32BigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadUInt32BigEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="uint" /> from the current stream as little endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static uint ReadUInt32LittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadUInt32LittleEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="ulong" /> from the current stream as big endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The big endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static ulong ReadUInt64BigEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadUInt64BigEndian(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an <see cref="ulong" /> from the current stream as little endian, and advances the stream position by eight
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream from which the value should be read.</param>
|
||||||
|
/// <returns>The little endian value.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" /></exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support reading.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static ulong ReadUInt64LittleEndian(this Stream stream)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportReading);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
_ = stream.Read(buffer);
|
||||||
|
return BinaryPrimitives.ReadUInt64LittleEndian(buffer);
|
||||||
|
}
|
||||||
|
}
|
473
X10D/src/IO/StreamExtensions.Writing.cs
Normal file
473
X10D/src/IO/StreamExtensions.Writing.cs
Normal file
@ -0,0 +1,473 @@
|
|||||||
|
using System.Buffers.Binary;
|
||||||
|
|
||||||
|
namespace X10D.IO;
|
||||||
|
|
||||||
|
public static partial class StreamExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="short" /> to the current stream as big endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="short" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteBigEndian(this Stream stream, short value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="int" /> to the current stream as big endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="int" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteBigEndian(this Stream stream, int value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="long" /> to the current stream as big endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="long" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteBigEndian(this Stream stream, long value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="ushort" /> to the current stream as big endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="ushort" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static int WriteBigEndian(this Stream stream, ushort value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="uint" /> to the current stream as big endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="uint" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static int WriteBigEndian(this Stream stream, uint value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="ulong" /> to the current stream as big endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="ulong" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static int WriteBigEndian(this Stream stream, ulong value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="float" /> to the current stream as little endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="float" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteBigEndian(this Stream stream, float value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="double" /> to the current stream as little endian, and advances the stream position by eight
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="double" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteBigEndian(this Stream stream, double value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="decimal" /> to the current stream as little endian, and advances the stream position by sixteen
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="decimal" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteBigEndian(this Stream stream, decimal value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[16];
|
||||||
|
value.TryWriteBigEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="short" /> to the current stream as little endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="short" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteLittleEndian(this Stream stream, short value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
value.TryWriteLittleEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes an <see cref="int" /> to the current stream as little endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="int" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteLittleEndian(this Stream stream, int value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
value.TryWriteLittleEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="long" /> to the current stream as little endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="long" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteLittleEndian(this Stream stream, long value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
value.TryWriteLittleEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="float" /> to the current stream as little endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="float" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteLittleEndian(this Stream stream, float value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
value.TryWriteLittleEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="double" /> to the current stream as little endian, and advances the stream position by eight
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="double" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteLittleEndian(this Stream stream, double value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
value.TryWriteLittleEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="decimal" /> to the current stream as little endian, and advances the stream position by sixteen
|
||||||
|
/// bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The <see cref="decimal" /> to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
public static int WriteLittleEndian(this Stream stream, decimal value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[16];
|
||||||
|
value.TryWriteLittleEndian(buffer);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="ushort" /> to the current stream as little endian, and advances the stream position by two bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The two-byte signed integer to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static int WriteLittleEndian(this Stream stream, ushort value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
BinaryPrimitives.WriteUInt16LittleEndian(buffer, value);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="uint" /> to the current stream as little endian, and advances the stream position by four bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The two-byte signed integer to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static int WriteLittleEndian(this Stream stream, uint value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
BinaryPrimitives.WriteUInt32LittleEndian(buffer, value);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a <see cref="ulong" /> to the current stream as little endian, and advances the stream position by eight bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The stream to which the value should be written.</param>
|
||||||
|
/// <param name="value">The two-byte signed integer to write.</param>
|
||||||
|
/// <returns>The number of bytes written to the stream.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="stream" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="stream" /> does not support writing.</exception>
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public static int WriteLittleEndian(this Stream stream, ulong value)
|
||||||
|
{
|
||||||
|
if (stream is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(ExceptionMessages.StreamDoesNotSupportWriting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[8];
|
||||||
|
BinaryPrimitives.WriteUInt64LittleEndian(buffer, value);
|
||||||
|
return stream.WriteInternal(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int WriteInternal(this Stream stream, ReadOnlySpan<byte> value)
|
||||||
|
{
|
||||||
|
long preWritePosition = stream.Position;
|
||||||
|
stream.Write(value);
|
||||||
|
return (int)(stream.Position - preWritePosition);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,7 @@
|
|||||||
"src": "../",
|
"src": "../",
|
||||||
"files": [
|
"files": [
|
||||||
"X10D/**/**.csproj",
|
"X10D/**/**.csproj",
|
||||||
|
"X10D.Hosting/**/**.csproj",
|
||||||
"X10D.Unity/**/**.csproj"
|
"X10D.Unity/**/**.csproj"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user