Skip to content

Commit

Permalink
[Move] Part-6 Classes into Different Library - Neo.Extensions (#3410
Browse files Browse the repository at this point in the history
)

* Part-1 `Neo.IO` - move

* Part-2

* Added `BigInteger` to `Neo.Extensions`

* Found more `BigInteger`

* Added `ByteArray` to `Neo.Extensions`

* Added `DateTime` Extensions to `Neo.Extensions`

* Added `HashSetExtensions`, `HashSetExtensions2`, `IpAddressExtensions`, `AssemblyExtensions`, `StringExtensdions`
Deleted `Helper.cs` file

* Added `ICollection`, `Memory`,  `String`, `Unsafe` extensions

* Adding `using`

* dotnet format

* Added more Extensions

* Move some methods

* Added Tests

* Added `tests` from `Part-2`

* Added `tests` for `PART-4`

* Added `tests` for `PART-5`

* Dotnet format

* dotnet format

* Renamed ByteExtensions2 to ByteExtensions

* Apply suggestions from code review

---------

Co-authored-by: Shargon <[email protected]>
Co-authored-by: Jimmy <[email protected]>
Co-authored-by: NGD Admin <[email protected]>
  • Loading branch information
4 people authored Nov 25, 2024
1 parent af5242f commit b2cbfc0
Show file tree
Hide file tree
Showing 92 changed files with 844 additions and 395 deletions.
2 changes: 1 addition & 1 deletion src/Neo/Cryptography/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using Neo.Extensions;
using Neo.Network.P2P.Payloads;
using Neo.Wallets;
using Org.BouncyCastle.Crypto.Digests;
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/Cryptography/MerkleTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using Neo.Extensions;
using System;
using System.Collections;
using System.Collections.Generic;
Expand Down
66 changes: 66 additions & 0 deletions src/Neo/Extensions/ByteExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// ByteExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using System;

namespace Neo.Extensions
{
public static class ByteExtensions
{
/// <summary>
/// Compresses the specified data using the LZ4 algorithm.
/// </summary>
/// <param name="data">The data to be compressed.</param>
/// <returns>The compressed data.</returns>
public static ReadOnlyMemory<byte> CompressLz4(this byte[] data)
{
return data.AsSpan().CompressLz4();
}

/// <summary>
/// Decompresses the specified data using the LZ4 algorithm.
/// </summary>
/// <param name="data">The compressed data.</param>
/// <param name="maxOutput">The maximum data size after decompression.</param>
/// <returns>The original data.</returns>
public static byte[] DecompressLz4(this byte[] data, int maxOutput)
{
return data.AsSpan().DecompressLz4(maxOutput);
}

/// <summary>
/// Converts a byte array to an <see cref="ISerializable"/> object.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="value">The byte array to be converted.</param>
/// <param name="start">The offset into the byte array from which to begin using data.</param>
/// <returns>The converted <see cref="ISerializable"/> object.</returns>
public static T AsSerializable<T>(this byte[] value, int start = 0) where T : ISerializable, new()
{
MemoryReader reader = new(value.AsMemory(start));
return reader.ReadSerializable<T>();
}

/// <summary>
/// Converts a byte array to an <see cref="ISerializable"/> array.
/// </summary>
/// <typeparam name="T">The type of the array element.</typeparam>
/// <param name="value">The byte array to be converted.</param>
/// <param name="max">The maximum number of elements contained in the converted array.</param>
/// <returns>The converted <see cref="ISerializable"/> array.</returns>
public static T[] AsSerializableArray<T>(this byte[] value, int max = 0x1000000) where T : ISerializable, new()
{
MemoryReader reader = new(value);
return reader.ReadSerializableArray<T>(max);
}
}
}
79 changes: 79 additions & 0 deletions src/Neo/Extensions/IO/BinaryReaderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// BinaryReaderExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.IO;

namespace Neo.Extensions
{
public static class BinaryReaderExtensions
{
/// <summary>
/// Reads a byte array of the specified size from a <see cref="BinaryReader"/>.
/// </summary>
/// <param name="reader">The <see cref="BinaryReader"/> for reading data.</param>
/// <param name="size">The size of the byte array.</param>
/// <returns>The byte array read from the <see cref="BinaryReader"/>.</returns>
public static byte[] ReadFixedBytes(this BinaryReader reader, int size)
{
var index = 0;
var data = new byte[size];

while (size > 0)
{
var bytesRead = reader.Read(data, index, size);

if (bytesRead <= 0)
{
throw new FormatException();
}

size -= bytesRead;
index += bytesRead;
}

return data;
}

/// <summary>
/// Reads a byte array from a <see cref="BinaryReader"/>.
/// </summary>
/// <param name="reader">The <see cref="BinaryReader"/> for reading data.</param>
/// <param name="max">The maximum size of the byte array.</param>
/// <returns>The byte array read from the <see cref="BinaryReader"/>.</returns>
public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0x1000000)
{
return reader.ReadFixedBytes((int)reader.ReadVarInt((ulong)max));
}

/// <summary>
/// Reads an integer from a <see cref="BinaryReader"/>.
/// </summary>
/// <param name="reader">The <see cref="BinaryReader"/> for reading data.</param>
/// <param name="max">The maximum value of the integer.</param>
/// <returns>The integer read from the <see cref="BinaryReader"/>.</returns>
public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue)
{
var fb = reader.ReadByte();
ulong value;
if (fb == 0xFD)
value = reader.ReadUInt16();
else if (fb == 0xFE)
value = reader.ReadUInt32();
else if (fb == 0xFF)
value = reader.ReadUInt64();
else
value = fb;
if (value > max) throw new FormatException();
return value;
}
}
}
137 changes: 137 additions & 0 deletions src/Neo/Extensions/IO/BinaryWriterExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// BinaryWriterExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using System;
using System.Collections.Generic;
using System.IO;

namespace Neo.Extensions
{
public static class BinaryWriterExtensions
{
/// <summary>
/// Writes an <see cref="ISerializable"/> object into a <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The <see cref="ISerializable"/> object to be written.</param>
public static void Write(this BinaryWriter writer, ISerializable value)
{
value.Serialize(writer);
}

/// <summary>
/// Writes an <see cref="ISerializable"/> array into a <see cref="BinaryWriter"/>.
/// </summary>
/// <typeparam name="T">The type of the array element.</typeparam>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The <see cref="ISerializable"/> array to be written.</param>
public static void Write<T>(this BinaryWriter writer, IReadOnlyCollection<T> value)
where T : ISerializable
{
writer.WriteVarInt(value.Count);
foreach (T item in value)
{
item.Serialize(writer);
}
}

/// <summary>
/// Writes a <see cref="string"/> into a <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The <see cref="string"/> to be written.</param>
/// <param name="length">The fixed size of the <see cref="string"/>.</param>
public static void WriteFixedString(this BinaryWriter writer, string value, int length)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (value.Length > length)
throw new ArgumentException(null, nameof(value));
var bytes = Utility.StrictUTF8.GetBytes(value);
if (bytes.Length > length)
throw new ArgumentException(null, nameof(value));
writer.Write(bytes);
if (bytes.Length < length)
writer.Write(stackalloc byte[length - bytes.Length]);
}

/// <summary>
/// Writes an <see cref="ISerializable"/> array into a <see cref="BinaryWriter"/>.
/// </summary>
/// <typeparam name="T">The type of the array element.</typeparam>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The <see cref="ISerializable"/> array to be written.</param>
public static void WriteNullableArray<T>(this BinaryWriter writer, T[] value)
where T : class, ISerializable
{
writer.WriteVarInt(value.Length);
foreach (var item in value)
{
var isNull = item is null;
writer.Write(!isNull);
if (isNull) continue;
item.Serialize(writer);
}
}

/// <summary>
/// Writes a byte array into a <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The byte array to be written.</param>
public static void WriteVarBytes(this BinaryWriter writer, ReadOnlySpan<byte> value)
{
writer.WriteVarInt(value.Length);
writer.Write(value);
}

/// <summary>
/// Writes an integer into a <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The integer to be written.</param>
public static void WriteVarInt(this BinaryWriter writer, long value)
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value));
if (value < 0xFD)
{
writer.Write((byte)value);
}
else if (value <= 0xFFFF)
{
writer.Write((byte)0xFD);
writer.Write((ushort)value);
}
else if (value <= 0xFFFFFFFF)
{
writer.Write((byte)0xFE);
writer.Write((uint)value);
}
else
{
writer.Write((byte)0xFF);
writer.Write(value);
}
}

/// <summary>
/// Writes a <see cref="string"/> into a <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="writer">The <see cref="BinaryWriter"/> for writing data.</param>
/// <param name="value">The <see cref="string"/> to be written.</param>
public static void WriteVarString(this BinaryWriter writer, string value)
{
writer.WriteVarBytes(Utility.StrictUTF8.GetBytes(value));
}
}
}
33 changes: 33 additions & 0 deletions src/Neo/Extensions/IO/ISerializableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// ISerializableExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using System.IO;

namespace Neo.Extensions
{
public static class ISerializableExtensions
{
/// <summary>
/// Converts an <see cref="ISerializable"/> object to a byte array.
/// </summary>
/// <param name="value">The <see cref="ISerializable"/> object to be converted.</param>
/// <returns>The converted byte array.</returns>
public static byte[] ToArray(this ISerializable value)
{
using MemoryStream ms = new();
using BinaryWriter writer = new(ms, Utility.StrictUTF8, true);
value.Serialize(writer);
writer.Flush();
return ms.ToArray();
}
}
}
Loading

0 comments on commit b2cbfc0

Please sign in to comment.