Skip to content

Commit ffc9396

Browse files
committed
wip
1 parent be9d275 commit ffc9396

File tree

68 files changed

+10778
-350
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+10778
-350
lines changed

src/Entity/StringValue.cs

+29-2
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77
// File name: StringValue.cs
88
// Repository: https://github.com/sisk-http/core
99

10+
using System.Runtime.CompilerServices;
11+
1012
namespace Sisk.Core.Entity;
1113

1214
/// <summary>
1315
/// Represents an instance that hosts a string value and allows conversion to common types.
1416
/// </summary>
1517
/// <definition>
16-
/// public class StringValue
18+
/// public struct StringValue
1719
/// </definition>
1820
/// <type>
1921
/// Class
2022
/// </type>
21-
public class StringValue
23+
public struct StringValue
2224
{
2325
private readonly string? _ref;
2426
private readonly string argName;
@@ -105,6 +107,20 @@ public string GetString()
105107
return _ref!;
106108
}
107109

110+
/// <summary>
111+
/// Gets a <see cref="char"/> from this <see cref="StringValue"/>. This method will throw an <see cref="NullReferenceException"/> if
112+
/// the value stored in this instance is null.
113+
/// </summary>
114+
/// <returns>An non-null char value.</returns>
115+
public char GetChar()
116+
{
117+
ThrowIfNull();
118+
if (_ref!.Length != 1)
119+
throw new FormatException(string.Format(SR.ValueItem_CastException, _ref, argName, "char"));
120+
121+
return _ref[0];
122+
}
123+
108124
/// <summary>
109125
/// Gets a <see cref="Int32"/> from this <see cref="StringValue"/>.
110126
/// </summary>
@@ -257,6 +273,17 @@ public Guid GetGuid()
257273
}
258274
}
259275

276+
/// <summary>
277+
/// Gets an not null value from the specified <typeparamref name="T"/>.
278+
/// </summary>
279+
/// <typeparam name="T">The type to convert the value to.</typeparam>
280+
public T Get<T>() where T : struct
281+
{
282+
ThrowIfNull();
283+
object result = Internal.Parseable.ParseInternal<T>(_ref!);
284+
return Unsafe.Unbox<T>(result);
285+
}
286+
260287
void ThrowIfNull()
261288
{
262289
if (IsNull)

src/Ext/CircularBuffer.cs

+26-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
using System.Collections;
1111

12-
namespace System;
12+
namespace Sisk.Core.Entity;
1313

1414
/// <summary>
1515
/// Represents an thread-safe, fixed-capacity circular buffer that stores elements of <typeparamref name="T"/>.
@@ -18,7 +18,7 @@ namespace System;
1818
/// <nodoc/>
1919
public class CircularBuffer<T> : IEnumerable<T>
2020
{
21-
readonly T[] items;
21+
T[] items;
2222

2323
int capacity = 0;
2424

@@ -51,12 +51,36 @@ public void Add(T item)
5151
}
5252
}
5353

54+
/// <summary>
55+
/// Clears the circular buffer contents and recreates the array.
56+
/// </summary>
57+
public void Clear()
58+
{
59+
items = new T[capacity];
60+
}
61+
62+
/// <summary>
63+
/// Changes the capacity of elements in this circular buffer to the specified new size.
64+
/// </summary>
65+
/// <param name="capacity">The new size for this circular buffer.</param>
66+
public void Resize(int capacity)
67+
{
68+
if (capacity <= 0) throw new ArgumentException("Capacity cannot be less or equals to zero.");
69+
Array.Resize(ref items, capacity);
70+
this.capacity = capacity;
71+
}
72+
5473
/// <summary>
5574
/// Returns an array representation of this <see cref="CircularBuffer{T}"/> items in their defined
5675
/// positions within the capacity.
5776
/// </summary>
5877
public T[] ToArray() => items;
5978

79+
/// <summary>
80+
/// Creates an new <see cref="ReadOnlySpan{T}"/> over the circular buffer.
81+
/// </summary>
82+
public ReadOnlySpan<T> ToSpan() => new ReadOnlySpan<T>(items);
83+
6084
/// <summary>
6185
/// Gets the current capacity of this <see cref="CircularBuffer{T}"/>.
6286
/// </summary>

src/Http/Handlers/HttpServerHandler.cs

+28
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,34 @@ protected virtual void OnServerStarting(HttpServer server) { }
4949
protected virtual void OnServerStarted(HttpServer server) { }
5050
internal void InvokeOnServerStarted(HttpServer server) => OnServerStarted(server);
5151

52+
/// <summary>
53+
/// Method that is called before the <see cref="HttpServer"/> stop, when it is
54+
/// stopping from listening requests.
55+
/// </summary>
56+
/// <param name="server">The Http server entity which is stopping.</param>
57+
/// <definition>
58+
/// protected virtual void OnServerStopping(HttpServer server)
59+
/// </definition>
60+
/// <type>
61+
/// Virtual method
62+
/// </type>
63+
protected virtual void OnServerStopping(HttpServer server) { }
64+
internal void InvokeOnServerStopping(HttpServer server) => OnServerStopping(server);
65+
66+
/// <summary>
67+
/// Method that is called after the <see cref="HttpServer"/> is stopped, meaning
68+
/// it has stopped from listening to requests.
69+
/// </summary>
70+
/// <param name="server">The Http server entity which has stopped.</param>
71+
/// <definition>
72+
/// protected virtual void OnServerStopped(HttpServer server)
73+
/// </definition>
74+
/// <type>
75+
/// Virtual method
76+
/// </type>
77+
protected virtual void OnServerStopped(HttpServer server) { }
78+
internal void InvokeOnServerStopped(HttpServer server) => OnServerStopped(server);
79+
5280
/// <summary>
5381
/// Method that is called when an <see cref="Router"/> is binded to the Http server.
5482
/// </summary>

src/Http/Handlers/HttpServerHandlerRepository.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// Repository: https://github.com/sisk-http/core
99

1010
using Sisk.Core.Routing;
11+
using System.Reflection.Metadata;
12+
using System.Runtime.CompilerServices;
13+
using System.Runtime.InteropServices;
1114

1215
namespace Sisk.Core.Http.Handlers;
1316

@@ -28,7 +31,12 @@ public void RegisterHandler(HttpServerHandler handler)
2831

2932
private void CallEvery(Action<HttpServerHandler> action)
3033
{
31-
foreach (HttpServerHandler handler in handlers)
34+
Span<HttpServerHandler> hspan = CollectionsMarshal.AsSpan<HttpServerHandler>(handlers);
35+
ref HttpServerHandler hpointer = ref MemoryMarshal.GetReference(hspan);
36+
for (int i = 0; i < hspan.Length; i++)
37+
{
38+
HttpServerHandler handler = Unsafe.Add(ref hpointer, i);
39+
3240
try
3341
{
3442
action(handler);
@@ -41,6 +49,7 @@ private void CallEvery(Action<HttpServerHandler> action)
4149
}
4250
else throw;
4351
}
52+
}
4453
}
4554

4655
internal void ServerStarting(HttpServer val) => CallEvery(handler => handler.InvokeOnServerStarting(val));
@@ -50,4 +59,6 @@ private void CallEvery(Action<HttpServerHandler> action)
5059
internal void HttpRequestOpen(HttpRequest val) => CallEvery(handler => handler.InvokeOnHttpRequestOpen(val));
5160
internal void HttpRequestClose(HttpServerExecutionResult val) => CallEvery(handler => handler.InvokeOnHttpRequestClose(val));
5261
internal void Exception(Exception val) => CallEvery(handler => handler.InvokeOnException(val));
62+
internal void Stopping(HttpServer val) => CallEvery(handler => handler.InvokeOnServerStopping(val));
63+
internal void Stopped(HttpServer val) => CallEvery(handler => handler.InvokeOnServerStopped(val));
5364
}

src/Http/HttpRequest.cs

+4-18
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,7 @@ public T GetContextBag<T>() where T : notnull
609609
/// <type>
610610
/// Method
611611
/// </type>
612-
[Obsolete("This method is deprecated and will be removed in later versions. Use Query[queryKeyName] instead.")]
613-
public string? GetQueryValue(string queryKeyName) => Query[queryKeyName];
612+
public string? GetQueryValue(string queryKeyName) => Query[queryKeyName].Value;
614613

615614
/// <summary>
616615
/// Gets the value stored from the <see cref="Query"/> and converts it to the given type.
@@ -619,32 +618,19 @@ public T GetContextBag<T>() where T : notnull
619618
/// <param name="queryKeyName">The name of the URL parameter. The search is ignore-case.</param>
620619
/// <param name="defaultValue">The default value that will be returned if the item is not found in the query.</param>
621620
/// <definition>
622-
/// // in .NET 6
623621
/// public T GetQueryValue{{T}}(string queryKeyName, T defaultValue = default) where T : struct
624-
///
625-
/// // in .NET 7+
626-
/// public T GetQueryValue{{T}}(string queryKeyName, T defaultValue = default) where T : struct, IParsable{{T}}
627622
/// </definition>
628623
/// <type>
629624
/// Method
630625
/// </type>
631-
[Obsolete("This method is deprecated and will be removed in later versions. Use Query[queryKeyName] instead.")]
632-
#if NET6_0
633626
public T GetQueryValue<T>(string queryKeyName, T defaultValue = default) where T : struct
634-
#elif NET7_0_OR_GREATER
635-
public T GetQueryValue<T>(string queryKeyName, T defaultValue = default) where T : struct, IParsable<T>
636-
#endif
637627
{
638-
string? value = Query[queryKeyName].MaybeNull()?.GetString();
639-
if (value == null) return defaultValue;
628+
StringValue value = Query[queryKeyName];
629+
if (value.IsNull) return defaultValue;
640630

641631
try
642632
{
643-
#if NET6_0
644-
return (T)Parseable.ParseInternal<T>(value);
645-
#elif NET7_0_OR_GREATER
646-
return T.Parse(value, null);
647-
#endif
633+
return value.Get<T>();
648634
}
649635
catch (Exception)
650636
{

src/Http/HttpResponse.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// File name: HttpResponse.cs
88
// Repository: https://github.com/sisk-http/core
99

10+
using Sisk.Core.Entity;
1011
using Sisk.Core.Routing;
1112
using System.Collections.Specialized;
1213
using System.Net;
@@ -106,15 +107,15 @@ public static HttpResponse CreateRedirectResponse(RouteAction action)
106107
public HttpStatusCode Status { get => (HttpStatusCode)StatusInformation.StatusCode; set => StatusInformation = new HttpStatusInformation(value); }
107108

108109
/// <summary>
109-
/// Gets a <see cref="NameValueCollection"/> instance of the HTTP response headers.
110+
/// Gets a <see cref="HttpHeaderCollection"/> instance of the HTTP response headers.
110111
/// </summary>
111112
/// <definition>
112-
/// public NameValueCollection Headers { get; }
113+
/// public HttpHeaderCollection Headers { get; }
113114
/// </definition>
114115
/// <type>
115116
/// Property
116117
/// </type>
117-
public NameValueCollection Headers { get; private set; } = new NameValueCollection();
118+
public HttpHeaderCollection Headers { get; private set; } = new HttpHeaderCollection();
118119

119120
/// <summary>
120121
/// Gets or sets the HTTP response body contents.

src/Http/HttpServer.cs

+5-38
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public partial class HttpServer : IDisposable
5858
internal HttpWebSocketConnectionCollection _wsCollection = new HttpWebSocketConnectionCollection();
5959
internal List<string>? listeningPrefixes;
6060
internal HttpServerHandlerRepository handler;
61-
61+
6262
internal AutoResetEvent waitNextEvent = new AutoResetEvent(false);
6363
internal bool isWaitingNextEvent = false;
6464
internal HttpServerExecutionResult? waitingExecutionResult;
@@ -221,36 +221,6 @@ out Router router
221221
/// </type>
222222
public HttpWebSocketConnectionCollection WebSockets { get => _wsCollection; }
223223

224-
/// <summary>
225-
/// Event that is called when this <see cref="HttpServer"/> computes an request and it's response.
226-
/// </summary>
227-
/// <definition>
228-
/// public event ServerExecutionEventHandler? OnConnectionClose;
229-
/// </definition>
230-
/// <remarks>
231-
/// This event is now obsolete and will be removed in later Sisk versions. Use HttpServerHandlers instead.
232-
/// </remarks>
233-
/// <type>
234-
/// Property
235-
/// </type>
236-
[Obsolete("This event is now obsolete and will be removed in later Sisk versions. Use HttpServerHandlers instead.")]
237-
public event ServerExecutionEventHandler? OnConnectionClose;
238-
239-
/// <summary>
240-
/// Event that is called when this <see cref="HttpServer"/> receives an request.
241-
/// </summary>
242-
/// <definition>
243-
/// public event ReceiveRequestEventHandler? OnConnectionOpen;
244-
/// </definition>
245-
/// <remarks>
246-
/// This event is now obsolete and will be removed in later Sisk versions. Use HttpServerHandlers instead.
247-
/// </remarks>
248-
/// <type>
249-
/// Property
250-
/// </type>
251-
[Obsolete("This event is now obsolete and will be removed in later Sisk versions. Use HttpServerHandlers instead.")]
252-
public event ReceiveRequestEventHandler? OnConnectionOpen;
253-
254224
/// <summary>
255225
/// Get Sisk version label.
256226
/// </summary>
@@ -435,8 +405,12 @@ public void Start()
435405
/// </type>
436406
public void Stop()
437407
{
408+
handler.Stopping(this);
438409
_isListening = false;
439410
httpListener.Stop();
411+
412+
UnbindRouters();
413+
handler.Stopped(this);
440414
}
441415

442416
/// <summary>
@@ -454,12 +428,5 @@ public void Dispose()
454428
httpListener.Close();
455429
ServerConfiguration.Dispose();
456430
}
457-
458-
private enum StreamMethodCallback
459-
{
460-
Nothing,
461-
Abort,
462-
Close
463-
}
464431
}
465432
}

src/Http/HttpServerFlags.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public class HttpServerFlags
238238
/// <summary>
239239
/// Determines the maximum amount of time an route can process an request, including running request handlers,
240240
/// reading body and executing the route action. Specify zero for no limit. When the route action running time
241-
/// reaches it's timeout, an <see cref="RequestTimeoutException"/> is thrown.
241+
/// reaches it's timeout, an RequestTimeoutException is thrown.
242242
/// </summary>
243243
/// <docs>
244244
/// <p>
@@ -251,6 +251,7 @@ public class HttpServerFlags
251251
/// <type>
252252
/// Field
253253
/// </type>
254+
[Obsolete("This property was deprecated and will do nothing. It will be removed in later Sisk versions.", true)]
254255
public TimeSpan RouteActionTimeout = TimeSpan.Zero;
255256

256257
/// <summary>

0 commit comments

Comments
 (0)