diff --git a/WindivertDotnet/WinDivertPacket.cs b/WindivertDotnet/WinDivertPacket.cs
index 0acc00c..cd9eee9 100644
--- a/WindivertDotnet/WinDivertPacket.cs
+++ b/WindivertDotnet/WinDivertPacket.cs
@@ -1,5 +1,6 @@
using Microsoft.Win32.SafeHandles;
using System;
+using System.Buffers;
using System.ComponentModel;
using System.Diagnostics;
using System.Net.Sockets;
@@ -13,6 +14,9 @@ namespace WindivertDotnet
[DebuggerDisplay("Length = {Length}, Capacity = {Capacity}")]
public class WinDivertPacket : SafeHandleZeroOrMinusOneIsInvalid
{
+ ///
+ /// 有效数据的长度
+ ///
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int length;
@@ -24,7 +28,7 @@ public class WinDivertPacket : SafeHandleZeroOrMinusOneIsInvalid
///
/// 获取有效数据视图
///
- public Span Span => this.GetSpan(this.length);
+ public Span Span => this.GetSpan(0, this.length);
///
/// 获取或设置有效数据的长度
@@ -60,18 +64,18 @@ public WinDivertPacket(int capacity = 0xFFFF + 40)
///
public void Clear()
{
- this.GetSpan(this.Capacity).Clear();
+ this.GetSpan(0, this.Capacity).Clear();
}
///
- /// 将指定的数据复制到packet缓冲区
+ /// 创建缓冲区写入对象
///
- /// 数据
+ /// 缓冲区偏移量
///
- public void SetBuffer(Span span)
+ ///
+ public IBufferWriter CreateBufferWriter(int offset = 0)
{
- this.Length = span.Length;
- span.CopyTo(this.Span);
+ return new BufferWriter(this, offset);
}
///
@@ -87,11 +91,23 @@ protected override bool ReleaseHandle()
///
/// 获取span
///
- ///
+ ///
+ ///
///
- private unsafe Span GetSpan(int length)
+ private unsafe Span GetSpan(int offset, int sizeHint)
{
- return new Span(this.handle.ToPointer(), length);
+ if (offset > this.Capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset));
+ }
+
+ if (this.Capacity - offset < sizeHint)
+ {
+ throw new ArgumentOutOfRangeException(nameof(sizeHint));
+ }
+
+ var pointer = (byte*)this.handle.ToPointer() + offset;
+ return new Span(pointer, sizeHint);
}
///
@@ -187,5 +203,43 @@ public unsafe WinDivertParseResult GetParseResult()
NextLength = nextLength
};
}
+
+
+ private class BufferWriter : IBufferWriter
+ {
+ private int index;
+ private readonly WinDivertPacket packet;
+
+ public BufferWriter(WinDivertPacket packet, int offset)
+ {
+ if (offset >= packet.Capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset));
+ }
+
+ this.index = offset;
+ this.packet = packet;
+ }
+
+ public void Advance(int count)
+ {
+ this.index += count;
+ this.packet.Length = this.index;
+ }
+
+ public Span GetSpan(int sizeHint = 0)
+ {
+ if (sizeHint == 0)
+ {
+ sizeHint = this.packet.Capacity - this.index;
+ }
+ return this.packet.GetSpan(this.index, sizeHint);
+ }
+
+ public Memory GetMemory(int sizeHint = 0)
+ {
+ throw new NotSupportedException();
+ }
+ }
}
}