Skip to content

Commit 5ef88fb

Browse files
Enable unsafe code. Channel, ChannelService: Don't copy the buffer, instead, have C++ use the memory from C#.
1 parent 09d9c38 commit 5ef88fb

File tree

4 files changed

+109
-21
lines changed

4 files changed

+109
-21
lines changed

Epp Net.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<EnableDynamicLoading>true</EnableDynamicLoading>
1414
<RootNamespace>EppNet</RootNamespace>
1515
<LangVersion>9.0</LangVersion>
16+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1617
</PropertyGroup>
1718
<ItemGroup>
1819
<Compile Remove="packages\Microsoft.NET.Test.Sdk.17.10.0\**" />

Source/Data/BytePayload.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
/// </summary>
1717

1818

19+
using ENet;
1920
using EppNet.Utilities;
2021

2122
using Microsoft.IO;
@@ -474,10 +475,7 @@ public virtual bool TryWrite<T>(T input)
474475

475476
public virtual byte[] Pack()
476477
{
477-
if (Stream == null)
478-
return null;
479-
480-
if (PackedData == null)
478+
if (Stream != null && PackedData != null)
481479
{
482480
this.PackedData = new byte[Stream.Length];
483481
Stream.WriteTo(PackedData);
@@ -518,9 +516,8 @@ public virtual void Dispose()
518516

519517
public string ReadString(int length)
520518
{
521-
Span<byte> buffer = stackalloc byte[length];
519+
Span<byte> buffer = stackalloc byte[Encoder.GetMaxByteCount(length)];
522520
int read = Stream.Read(buffer);
523-
524521
return Encoder.GetString(buffer);
525522
}
526523

Source/Messaging/Channel.cs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
//////////////////////////////////////////////
66

77
using ENet;
8+
using EppNet.Data;
89

910
using EppNet.Data.Datagrams;
1011
using EppNet.Logging;
1112
using EppNet.Utilities;
1213

1314
using System;
1415
using System.Collections.Generic;
16+
using System.IO;
1517
using System.Threading;
1618

1719
namespace EppNet.Messaging
@@ -170,35 +172,82 @@ public void Clear()
170172
}
171173
}
172174

173-
public bool SendTo(Peer peer, byte[] bytes, PacketFlags flags)
175+
/// <summary>
176+
/// Tries to send an <see cref="ArraySegment"/> of bytes to the specified <see cref="Peer"/>
177+
/// with the specified <see cref="PacketFlags"/>.<br/>
178+
/// Length of -1 means the entire buffer will be sent.<br/><br/>
179+
///
180+
/// Return:<br/>
181+
/// - 0 -> Success<br/>
182+
/// - 1 -> Invalid data<br/>
183+
/// - 2 -> An exception occurred<br/>
184+
/// </summary>
185+
/// <param name="peer"></param>
186+
/// <param name="buffer"></param>
187+
/// <param name="flags"></param>
188+
/// <returns></returns>
189+
190+
public int TrySendTo(Peer peer, ArraySegment<byte> buffer, PacketFlags flags = PacketFlags.None)
191+
{
192+
if (buffer.Count < 1)
193+
return 1;
194+
195+
return TrySendTo(peer, buffer.Array, buffer.Offset, buffer.Count, flags);
196+
}
197+
198+
/// <summary>
199+
/// Tries to send a byte array to the specified <see cref="Peer"/>
200+
/// with the specified <see cref="PacketFlags"/>.<br/>
201+
/// Length of -1 means the entire buffer will be sent.<br/><br/>
202+
///
203+
/// Return:<br/>
204+
/// - 0 -> Success<br/>
205+
/// - 1 -> Invalid data<br/>
206+
/// - 2 -> An exception occurred<br/>
207+
/// </summary>
208+
/// <param name="peer"></param>
209+
/// <param name="buffer"></param>
210+
/// <param name="flags"></param>
211+
/// <returns></returns>
212+
213+
public int TrySendTo(Peer peer, byte[] bytes, int offset, int length = -1, PacketFlags flags = PacketFlags.None)
174214
{
175-
// Create an ENet packet
176-
Packet packet = new();
215+
if (bytes == null)
216+
return 1;
217+
218+
Packet packet = default;
177219

178220
try
179221
{
180-
packet.Create(bytes, flags);
222+
unsafe
223+
{
224+
fixed (byte* bufferPtr = bytes)
225+
{
226+
IntPtr nativePtr = (IntPtr)(bufferPtr + offset);
227+
packet.Create(nativePtr, length == -1 ? bytes.Length : length, flags);
228+
}
229+
}
181230

182231
// Send the packet to our ENet peer
183232
if (peer.Send(Id, ref packet))
184233
{
185234
Interlocked.Increment(ref _datagramsReceived);
186-
Interlocked.Add(ref _totalBytesSent, bytes.LongLength);
187-
return true;
235+
Interlocked.Add(ref _totalBytesSent, length);
236+
return 0;
188237
}
189238
}
190239
catch (Exception ex)
191240
{
192-
Notify.Error($"Failed to send Datagram to Peer {peer.ID}. Error {ex.Message}\n{ex.StackTrace}");
241+
Notify.Error($"Failed to send data to Peer {peer.ID}. Error {ex.Message}\n{ex.StackTrace}");
193242
}
194243
finally
195244
{
196245
// No matter what, dispose of this packet.
197246
packet.Dispose();
198247
}
199248

200-
// Failed to send the datagram.
201-
return false;
249+
// An exception occurred.
250+
return 2;
202251
}
203252

204253
/// <summary>

Source/Messaging/ChannelService.cs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,64 @@ public bool Handle(PacketReceivedEvent @event)
3838
return true;
3939
}
4040

41-
public bool TrySendTo(Peer peer, IDatagram datagram, PacketFlags flags)
41+
/// <summary>
42+
/// Tries to send a Datagram to the specified <see cref="Peer"/>
43+
/// with the specified <see cref="PacketFlags"/>.<br/><br/>
44+
///
45+
/// Return:<br/>
46+
/// - 0 -> Success<br/>
47+
/// - 1 -> Invalid data<br/>
48+
/// - 2 -> An exception occurred<br/>
49+
/// - 3 -> Channel not found
50+
/// </summary>
51+
/// <param name="peer"></param>
52+
/// <param name="buffer"></param>
53+
/// <param name="flags"></param>
54+
/// <returns></returns>
55+
56+
public int TrySendTo(Peer peer, Datagram datagram, PacketFlags flags = PacketFlags.None)
4257
{
4358

59+
if (datagram is null)
60+
return 1;
61+
4462
if (!datagram.Written)
4563
datagram.Write();
4664

47-
Channel channel = GetChannelById(datagram.GetChannelID());
48-
return channel?.SendTo(peer, datagram.Pack(), flags) == true;
65+
if (!datagram.Stream.TryGetBuffer(out ArraySegment<byte> buffer))
66+
return 1;
67+
68+
return TrySendDataTo(peer, datagram.ChannelID, buffer.Array, buffer.Offset, buffer.Count, flags);
4969
}
5070

51-
public bool TrySendDataTo(Peer peer, byte channelId, byte[] bytes, PacketFlags flags)
71+
/// <summary>
72+
/// Tries to send a byte array to the specified <see cref="Peer"/>
73+
/// with the specified offset, length, and <see cref="PacketFlags"/>.<br/>
74+
/// Length of -1 means the entire buffer will be sent.<br/><br/>
75+
///
76+
/// Return:<br/>
77+
/// - 0 -> Success<br/>
78+
/// - 1 -> Invalid data<br/>
79+
/// - 2 -> An exception occurred<br/>
80+
/// - 3 -> Channel does not exist
81+
/// </summary>
82+
/// <param name="peer"></param>
83+
/// <param name="buffer"></param>
84+
/// <param name="flags"></param>
85+
/// <returns></returns>
86+
87+
public int TrySendDataTo(Peer peer, byte channelId, byte[] bytes, int offset, int length = -1, PacketFlags flags = PacketFlags.None)
5288
{
5389
Channel channel = GetChannelById(channelId);
54-
return channel?.SendTo(peer, bytes, flags) == true;
90+
91+
if (channel is not null)
92+
return channel.TrySendTo(peer, bytes, offset, length, flags);
93+
94+
return 3;
5595
}
5696

57-
public bool TryAddChannel(byte id) => TryAddChannel(id, out Channel _);
97+
public bool TryAddChannel(byte id)
98+
=> TryAddChannel(id, out Channel _);
5899

59100
public bool TryAddChannel(byte id, out Channel newChannel, ChannelFlags flags = ChannelFlags.None)
60101
{

0 commit comments

Comments
 (0)