-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSerializerUtils.cs
115 lines (99 loc) · 3.96 KB
/
SerializerUtils.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// The Sisk Framework source code
// Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
//
// The code below is licensed under the MIT license as
// of the date of its publication, available at
//
// File name: SerializerUtils.cs
// Repository: https://github.com/sisk-http/core
using System.Runtime.CompilerServices;
using System.Text;
namespace Sisk.Ssl;
static class SerializerUtils {
[MethodImpl ( MethodImplOptions.AggressiveInlining )]
public static string DecodeString ( ReadOnlySpan<byte> data ) => Encoding.UTF8.GetString ( data );
[MethodImpl ( MethodImplOptions.AggressiveInlining )]
public static byte [] EncodeString ( string data ) => Encoding.UTF8.GetBytes ( data );
public static bool WaitUntilHasData ( Stream stream, TimeSpan timeout ) {
while (stream.ReadByte () == -1) {
Thread.Sleep ( 1 );
}
return true;
}
public static ReadOnlySpan<byte> ReadUntil ( Span<byte> buffer, Stream inputStream, int intercept ) {
int current, size = 0;
while (inputStream.CanRead && ((current = inputStream.ReadByte ()) >= 0)) {
if (current == intercept) {
return buffer [ 0..size ];
}
else if (size > buffer.Length - 1) {
throw new OutOfMemoryException ();
}
else {
buffer [ size ] = (byte) current;
}
size++;
}
return Array.Empty<byte> ();
}
public static void CopyBlocking ( Stream input, Stream output ) {
AutoResetEvent rs = new AutoResetEvent ( false );
CopyBlocking ( input, output, rs );
rs.WaitOne ();
}
public static void CopyBlocking ( Stream input, Stream output, EventWaitHandle waitEvent ) {
byte [] buffer = new byte [ 8192 ];
AsyncCallback callback = null!;
callback = ar => {
int bytesRead = input.EndRead ( ar );
output.Write ( buffer, 0, bytesRead );
if (bytesRead > 0) {
input.BeginRead ( buffer, 0, buffer.Length, callback, null );
}
else {
output.Flush ();
waitEvent.Set ();
}
};
input.BeginRead ( buffer, 0, buffer.Length, callback, null );
}
public static void CopyUntilBlocking ( Stream input, Stream output, byte [] eof, EventWaitHandle waitEvent ) {
byte [] buffer = new byte [ 8192 ];
AsyncCallback callback = null!;
callback = ar => {
int bytesRead = input.EndRead ( ar );
output.Write ( buffer, 0, bytesRead );
ReadOnlySpan<byte> writtenSpan = buffer [ 0..bytesRead ];
if (bytesRead > 0 && !writtenSpan.EndsWith ( eof )) {
input.BeginRead ( buffer, 0, buffer.Length, callback, null );
}
else {
output.Flush ();
waitEvent.Set ();
}
};
input.BeginRead ( buffer, 0, buffer.Length, callback, null );
}
public static bool CopyStream ( Stream input, Stream output, long bytes, CancellationToken cancel ) {
byte [] buffer = new byte [ 81920 ];
long written = 0;
int inputReadAlloc = (int) Math.Min ( Int32.MaxValue, bytes );
int read;
while (written < bytes && (read = input.Read ( buffer, 0, Math.Min ( buffer.Length, inputReadAlloc ) )) > 0 && !cancel.IsCancellationRequested) {
output.Write ( buffer, 0, read );
written += read;
}
return written == bytes;
}
public static void CopyUntil ( Stream input, Stream output, byte [] eof ) {
Span<byte> buffer = stackalloc byte [ 81920 ];
int read;
while ((read = input.Read ( buffer )) > 0) {
output.Write ( buffer.ToArray (), 0, read );
ReadOnlySpan<byte> writtenSpan = buffer [ 0..read ];
if (writtenSpan.EndsWith ( eof )) {
break;
}
}
}
}