Skip to content

Commit 4f7e0ae

Browse files
committed
feat(extensions): 添加无长度前缀的字节/字符串读写方法
为 ByteExtensions 和 SpanExtensions 添加以下新方法: - WriteBytesWithoutLength: 直接写入字节数组,不包含长度前缀 - WriteStringWithoutLength: 直接写入字符串,不包含长度前缀 - ReadBytesValue: 按指定长度读取字节数组 - ReadStringValue: 按指定长度读取字符串 支持大端和小端字节序
1 parent de929bd commit 4f7e0ae

4 files changed

Lines changed: 476 additions & 0 deletions

File tree

GameFrameX.Foundation.Extensions/ByteExtensions.BigEndian.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,30 @@ public static void WriteBytesBigEndianValue(this byte[] buffer, byte[] value, re
191191
offset += value.Length;
192192
}
193193

194+
/// <summary>
195+
/// 将字节数组直接写入指定的缓冲区,不包含长度前缀,并更新偏移量。
196+
/// </summary>
197+
/// <param name="buffer">要写入的缓冲区。</param>
198+
/// <param name="value">要写入的字节数组,不能为 null。</param>
199+
/// <param name="offset">要写入值的缓冲区中的偏移量。</param>
200+
/// <exception cref="ArgumentNullException">当 <paramref name="buffer"/> 或 <paramref name="value"/> 为 null 时抛出。</exception>
201+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或缓冲区空间不足时抛出。</exception>
202+
public static void WriteBytesWithoutLengthBigEndian(this byte[] buffer, byte[] value, ref int offset)
203+
{
204+
ArgumentNullException.ThrowIfNull(buffer, nameof(buffer));
205+
ArgumentNullException.ThrowIfNull(value, nameof(value));
206+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
207+
208+
if (offset + value.Length > buffer.Length)
209+
{
210+
throw new ArgumentOutOfRangeException(nameof(offset),
211+
LocalizationService.GetString(LocalizationKeys.Exceptions.BufferTooSmall, offset + value.Length, buffer.Length));
212+
}
213+
214+
value.AsSpan().CopyTo(buffer.AsSpan(offset, value.Length));
215+
offset += value.Length;
216+
}
217+
194218
/// <summary>
195219
/// 将一个字符串以大端字节序写入指定的缓冲区,并更新偏移量。
196220
/// </summary>
@@ -226,6 +250,40 @@ public static void WriteStringBigEndianValue(this byte[] buffer, string value, r
226250
offset += len;
227251
}
228252

253+
/// <summary>
254+
/// 将字符串直接写入指定的缓冲区,不包含长度前缀,并更新偏移量。
255+
/// </summary>
256+
/// <param name="buffer">要写入的缓冲区。</param>
257+
/// <param name="value">要写入的字符串。</param>
258+
/// <param name="offset">要写入值的缓冲区中的偏移量。</param>
259+
/// <exception cref="ArgumentNullException">当 <paramref name="buffer"/> 为 null 时抛出。</exception>
260+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或缓冲区空间不足时抛出。</exception>
261+
public static void WriteStringWithoutLengthBigEndian(this byte[] buffer, string value, ref int offset)
262+
{
263+
ArgumentNullException.ThrowIfNull(buffer, nameof(buffer));
264+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
265+
266+
if (value == null)
267+
{
268+
return;
269+
}
270+
271+
var len = Encoding.UTF8.GetByteCount(value);
272+
273+
if (len == 0)
274+
{
275+
return;
276+
}
277+
278+
if (offset + len > buffer.Length)
279+
{
280+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.BufferTooSmall, offset + len, buffer.Length));
281+
}
282+
283+
Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, offset);
284+
offset += len;
285+
}
286+
229287
#endregion
230288

231289
#region Read BigEndian
@@ -472,5 +530,34 @@ public static string ReadStringBigEndianValue(this byte[] buffer, ref int offset
472530
return value;
473531
}
474532

533+
/// <summary>
534+
/// 从字节数组中以指定偏移量读取指定长度的字符串(大端字节序)。
535+
/// </summary>
536+
/// <param name="buffer">要从中读取数据的字节数组。</param>
537+
/// <param name="offset">读取数据的起始偏移量,此偏移量在读取后会自动增加。</param>
538+
/// <param name="len">要读取的字符串字节长度。</param>
539+
/// <returns>读取的字符串,若读取长度小于等于0或偏移量超出数组长度,返回空字符串。</returns>
540+
/// <exception cref="ArgumentNullException">当 <paramref name="buffer"/> 为 null 时抛出。</exception>
541+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或读取位置超出缓冲区边界时抛出。</exception>
542+
public static string ReadStringBigEndianValue(this byte[] buffer, ref int offset, int len)
543+
{
544+
ArgumentNullException.ThrowIfNull(buffer, nameof(buffer));
545+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
546+
547+
if (len <= 0)
548+
{
549+
return string.Empty;
550+
}
551+
552+
if (offset + len > buffer.Length)
553+
{
554+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.OffsetOutsideBufferBoundsSimple));
555+
}
556+
557+
var value = Encoding.UTF8.GetString(buffer, offset, len);
558+
offset += len;
559+
return value;
560+
}
561+
475562
#endregion
476563
}

GameFrameX.Foundation.Extensions/ByteExtensions.LittleEndian.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,30 @@ public static void WriteBytesLittleEndianValue(this byte[] buffer, byte[] value,
191191
offset += value.Length;
192192
}
193193

194+
/// <summary>
195+
/// 将字节数组直接写入指定的缓冲区,不包含长度前缀,并更新偏移量。
196+
/// </summary>
197+
/// <param name="buffer">要写入的缓冲区。</param>
198+
/// <param name="value">要写入的字节数组,不能为 null。</param>
199+
/// <param name="offset">要写入值的缓冲区中的偏移量。</param>
200+
/// <exception cref="ArgumentNullException">当 <paramref name="buffer"/> 或 <paramref name="value"/> 为 null 时抛出。</exception>
201+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或缓冲区空间不足时抛出。</exception>
202+
public static void WriteBytesWithoutLengthLittleEndian(this byte[] buffer, byte[] value, ref int offset)
203+
{
204+
ArgumentNullException.ThrowIfNull(buffer, nameof(buffer));
205+
ArgumentNullException.ThrowIfNull(value, nameof(value));
206+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
207+
208+
if (offset + value.Length > buffer.Length)
209+
{
210+
throw new ArgumentOutOfRangeException(nameof(offset),
211+
LocalizationService.GetString(LocalizationKeys.Exceptions.BufferTooSmall, offset + value.Length, buffer.Length));
212+
}
213+
214+
value.AsSpan().CopyTo(buffer.AsSpan(offset, value.Length));
215+
offset += value.Length;
216+
}
217+
194218
/// <summary>
195219
/// 将一个字符串以小端字节序写入指定的缓冲区,并更新偏移量。
196220
/// </summary>
@@ -226,6 +250,40 @@ public static void WriteStringLittleEndianValue(this byte[] buffer, string value
226250
offset += len;
227251
}
228252

253+
/// <summary>
254+
/// 将字符串直接写入指定的缓冲区,不包含长度前缀,并更新偏移量。
255+
/// </summary>
256+
/// <param name="buffer">要写入的缓冲区。</param>
257+
/// <param name="value">要写入的字符串。</param>
258+
/// <param name="offset">要写入值的缓冲区中的偏移量。</param>
259+
/// <exception cref="ArgumentNullException">当 <paramref name="buffer"/> 为 null 时抛出。</exception>
260+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或缓冲区空间不足时抛出。</exception>
261+
public static void WriteStringWithoutLengthLittleEndian(this byte[] buffer, string value, ref int offset)
262+
{
263+
ArgumentNullException.ThrowIfNull(buffer, nameof(buffer));
264+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
265+
266+
if (value == null)
267+
{
268+
return;
269+
}
270+
271+
var len = Encoding.UTF8.GetByteCount(value);
272+
273+
if (len == 0)
274+
{
275+
return;
276+
}
277+
278+
if (offset + len > buffer.Length)
279+
{
280+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.BufferTooSmall, offset + len, buffer.Length));
281+
}
282+
283+
Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, offset);
284+
offset += len;
285+
}
286+
229287
#endregion
230288

231289
#region Read LittleEndian
@@ -472,5 +530,34 @@ public static string ReadStringLittleEndianValue(this byte[] buffer, ref int off
472530
return value;
473531
}
474532

533+
/// <summary>
534+
/// 从字节数组中以指定偏移量读取指定长度的字符串(小端字节序)。
535+
/// </summary>
536+
/// <param name="buffer">要从中读取数据的字节数组。</param>
537+
/// <param name="offset">读取数据的起始偏移量,此偏移量在读取后会自动增加。</param>
538+
/// <param name="len">要读取的字符串字节长度。</param>
539+
/// <returns>读取的字符串,若读取长度小于等于0或偏移量超出数组长度,返回空字符串。</returns>
540+
/// <exception cref="ArgumentNullException">当 <paramref name="buffer"/> 为 null 时抛出。</exception>
541+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或读取位置超出缓冲区边界时抛出。</exception>
542+
public static string ReadStringLittleEndianValue(this byte[] buffer, ref int offset, int len)
543+
{
544+
ArgumentNullException.ThrowIfNull(buffer, nameof(buffer));
545+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
546+
547+
if (len <= 0)
548+
{
549+
return string.Empty;
550+
}
551+
552+
if (offset + len > buffer.Length)
553+
{
554+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.OffsetOutsideBufferBoundsSimple));
555+
}
556+
557+
var value = Encoding.UTF8.GetString(buffer, offset, len);
558+
offset += len;
559+
return value;
560+
}
561+
475562
#endregion
476563
}

GameFrameX.Foundation.Extensions/SpanExtensions.BigEndian.cs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,37 @@ public static void WriteStringValue(this Span<byte> buffer, string value, ref in
254254
WriteBytesWithoutLength(buffer, bytes, ref offset);
255255
}
256256

257+
/// <summary>
258+
/// 将字符串直接写入指定的缓冲区,不包含长度前缀,并更新偏移量。
259+
/// </summary>
260+
/// <param name="buffer">要写入的字节跨度。</param>
261+
/// <param name="value">要写入的字符串。</param>
262+
/// <param name="offset">读写操作的起始位置,写入后会自动增加相应字节数。</param>
263+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或缓冲区空间不足时抛出。</exception>
264+
public static void WriteStringWithoutLength(this Span<byte> buffer, string value, ref int offset)
265+
{
266+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
267+
268+
if (value == null)
269+
{
270+
return;
271+
}
272+
273+
if (string.IsNullOrEmpty(value))
274+
{
275+
return;
276+
}
277+
278+
var bytes = Encoding.UTF8.GetBytes(value);
279+
280+
if (offset + bytes.Length > buffer.Length)
281+
{
282+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.BufferTooSmall, offset + bytes.Length, buffer.Length));
283+
}
284+
285+
WriteBytesWithoutLength(buffer, bytes, ref offset);
286+
}
287+
257288
#endregion
258289

259290
#region Read BigEndian
@@ -483,5 +514,60 @@ public static string ReadStringValue(this Span<byte> buffer, ref int offset)
483514
return value;
484515
}
485516

517+
/// <summary>
518+
/// 从指定偏移量开始读取指定长度的字节数组。
519+
/// </summary>
520+
/// <param name="buffer">要读取的字节跨度。</param>
521+
/// <param name="offset">读写操作的起始位置,读取后会自动增加相应字节数。</param>
522+
/// <param name="len">需要读取的字节数组长度。</param>
523+
/// <returns>返回从缓冲区读取的字节数组,如果长度小于等于0则返回空数组。</returns>
524+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或超出缓冲区边界时抛出。</exception>
525+
public static byte[] ReadBytesValue(this Span<byte> buffer, ref int offset, int len)
526+
{
527+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
528+
529+
if (len <= 0)
530+
{
531+
return Array.Empty<byte>();
532+
}
533+
534+
if (offset + len > buffer.Length)
535+
{
536+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.OffsetOutsideBufferBoundsSimple));
537+
}
538+
539+
var data = new byte[len];
540+
buffer.Slice(offset, len).CopyTo(data);
541+
offset += len;
542+
return data;
543+
}
544+
545+
/// <summary>
546+
/// 从指定偏移量开始读取指定长度的字符串。
547+
/// </summary>
548+
/// <param name="buffer">要读取的字节跨度。</param>
549+
/// <param name="offset">读写操作的起始位置,读取后会自动增加相应字节数。</param>
550+
/// <param name="len">要读取的字符串字节长度。</param>
551+
/// <returns>返回读取的字符串,使用 UTF-8 解码,如果长度小于等于0则返回空字符串。</returns>
552+
/// <exception cref="ArgumentOutOfRangeException">当 <paramref name="offset"/> 为负数或超出缓冲区边界时抛出。</exception>
553+
public static string ReadStringValue(this Span<byte> buffer, ref int offset, int len)
554+
{
555+
ArgumentOutOfRangeException.ThrowIfNegative(offset, nameof(offset));
556+
557+
if (len <= 0)
558+
{
559+
return string.Empty;
560+
}
561+
562+
if (offset + len > buffer.Length)
563+
{
564+
throw new ArgumentOutOfRangeException(nameof(offset), LocalizationService.GetString(LocalizationKeys.Exceptions.OffsetOutsideBufferBoundsSimple));
565+
}
566+
567+
var value = Encoding.UTF8.GetString(buffer.Slice(offset, len));
568+
offset += len;
569+
return value;
570+
}
571+
486572
#endregion
487573
}

0 commit comments

Comments
 (0)