Skip to content

Commit

Permalink
refactor extensions + optimized byte[] search (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Oshi41 committed Dec 27, 2024
1 parent 3bfb012 commit 19c2f62
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 24 deletions.
19 changes: 0 additions & 19 deletions source/NetCoreServer/Extensions.cs

This file was deleted.

2 changes: 0 additions & 2 deletions source/NetCoreServer/HttpRequest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Net;
using System.Text;

Expand Down
1 change: 0 additions & 1 deletion source/NetCoreServer/HttpResponse.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Text;

namespace NetCoreServer;
Expand Down
1 change: 1 addition & 0 deletions source/NetCoreServer/SslClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using NetCoreServer.extensions;

namespace NetCoreServer;

Expand Down
1 change: 1 addition & 0 deletions source/NetCoreServer/SslSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Net.Sockets;
using System.Text;
using System.Threading;
using NetCoreServer.extensions;

namespace NetCoreServer;

Expand Down
1 change: 1 addition & 0 deletions source/NetCoreServer/TcpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Net.Sockets;
using System.Text;
using System.Threading;
using NetCoreServer.extensions;

namespace NetCoreServer;

Expand Down
1 change: 1 addition & 0 deletions source/NetCoreServer/TcpSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Net.Sockets;
using System.Text;
using System.Threading;
using NetCoreServer.extensions;

namespace NetCoreServer;

Expand Down
3 changes: 1 addition & 2 deletions source/NetCoreServer/WebSocket.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using System;
using System.Text;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using System.Net.Sockets;
using NetCoreServer.extensions;

namespace NetCoreServer;

Expand Down
12 changes: 12 additions & 0 deletions source/NetCoreServer/extensions/SocketExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Net.Sockets;

namespace NetCoreServer.extensions;

public static class SocketExtensions
{
public static void SetupSocket(this Socket socket, int keepAliveTime, int keepAliveInterval,
int keepAliveRetryCount)
{
// TODO implement for net standard 2.0
}
}
75 changes: 75 additions & 0 deletions source/NetCoreServer/extensions/SpanExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace NetCoreServer.extensions;

public static class SpanExtensions
{
private static readonly ReadOnlyMemory<byte> HttpNewLineBreak = "\r\n\r\n"u8.ToArray();

private static readonly FieldInfo f_List_items =
typeof(List<byte>).GetField("_items", BindingFlags.Instance | BindingFlags.NonPublic);

private static readonly FieldInfo f_Queue_array = typeof(Queue<byte>)
.GetField("_array", BindingFlags.Instance | BindingFlags.NonPublic);

private static readonly FieldInfo f_Queue_head = typeof(Queue<byte>)
.GetField("_head", BindingFlags.Instance | BindingFlags.NonPublic);

private static readonly FieldInfo f_Queue_tail = typeof(Queue<byte>)
.GetField("_tail", BindingFlags.Instance | BindingFlags.NonPublic);

/// <inheritdoc cref="HttpNewLineIndex(System.Span{byte})"/>
public static int HttpNewLineIndex(this ReadOnlySpan<byte> bytes) => bytes.LastIndexOf(HttpNewLineBreak.Span);

/// <summary>
/// Searches last index of HTTP new line break (CR-LF-CR-LF).
/// </summary>
/// <param name="bytes">Bytes data span</param>
/// <returns>-1 if line break was not found, zero-based index otherwise</returns>
public static int HttpNewLineIndex(this Span<byte> bytes) => bytes.LastIndexOf(HttpNewLineBreak.Span);

/// <summary>
/// Convert to <see cref="Span{T}"/><br/><br/>
/// <b>WARNING!</b><br/>
/// Utilize reflection, use with wisdom!
/// </summary>
/// <param name="bytes"></param>
public static Span<byte> AsSpan(this List<byte> bytes)
{
return (f_List_items.GetValue(bytes) as byte[]).AsSpan(0, bytes.Count);
}

/// <summary>
/// Convert to <see cref="Span{T}"/><br/><br/>
/// <b>WARNING!</b><br/>
/// Utilize reflection, use with wisdom!
/// </summary>
/// <remarks>
/// <see cref="Queue{T}"/> is not a really great way to retreive <see cref="Span{T}"/>. It
/// </remarks>
/// <param name="bytes">Bytes data</param>
public static Span<byte> AsSpan(this Queue<byte> bytes)
{
var array = (f_Queue_array.GetValue(bytes) as byte[]);
var head = (int)(f_Queue_head.GetValue(bytes));
var tail = (int)(f_Queue_tail.GetValue(bytes));

// easy condition
if (head < tail)
{
return array.AsSpan(head, bytes.Count);
}

return bytes.AsEnumerable().AsSpanDangerous();
}

/// <summary>
/// Convert to <see cref="Span{T}"/><br/>
/// </summary>
/// <remarks>Creates new array which may be very expensive</remarks>
/// <param name="bytes">Bytes data</param>
public static Span<byte> AsSpanDangerous(this IEnumerable<byte> bytes) => bytes.ToArray().AsSpan();
}
11 changes: 11 additions & 0 deletions source/NetCoreServer/extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Linq;

namespace NetCoreServer.extensions;

public static class StringExtensions
{
// todo optimize
public static string RemoveWhiteSpace(this string self) => string.IsNullOrEmpty(self)
? self
: new string(self.Where(c => !char.IsWhiteSpace(c)).ToArray());
}
Loading

0 comments on commit 19c2f62

Please sign in to comment.