mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-04-15 05:32:29 +03:00
117 lines
4.7 KiB
C#
117 lines
4.7 KiB
C#
using System.IO;
|
|
using System.Text;
|
|
using Syroot.BinaryData;
|
|
|
|
namespace Syroot.Worms.OnlineWorms.Server.Net
|
|
{
|
|
/// <summary>
|
|
/// Represents a stream formatting data for being sent or received from <see cref="Packet"/> instances.
|
|
/// </summary>
|
|
internal class PacketStream : Stream
|
|
{
|
|
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
|
|
|
private static readonly Encoding _win949Encoding;
|
|
|
|
private readonly Stream _baseStream;
|
|
private bool _disposed;
|
|
|
|
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
|
|
|
static PacketStream()
|
|
{
|
|
#if NETCOREAPP2_1
|
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
|
#endif
|
|
_win949Encoding = Encoding.GetEncoding(949);
|
|
}
|
|
|
|
internal PacketStream(Stream baseStream)
|
|
{
|
|
_baseStream = baseStream;
|
|
}
|
|
|
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
|
|
|
public override bool CanRead => _baseStream.CanRead;
|
|
public override bool CanSeek => _baseStream.CanSeek;
|
|
public override bool CanWrite => _baseStream.CanWrite;
|
|
public override long Length => _baseStream.Length;
|
|
public override long Position
|
|
{
|
|
get => _baseStream.Position;
|
|
set => _baseStream.Position = value;
|
|
}
|
|
|
|
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
|
|
|
public override void Flush() => _baseStream.Flush();
|
|
public override int Read(byte[] buffer, int offset, int count) => _baseStream.Read(buffer, offset, count);
|
|
public override long Seek(long offset, SeekOrigin origin) => _baseStream.Seek(offset, origin);
|
|
public override void SetLength(long value) => _baseStream.SetLength(value);
|
|
public override void Write(byte[] buffer, int offset, int count) => _baseStream.Write(buffer, offset, count);
|
|
|
|
// ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
|
|
if (disposing)
|
|
_baseStream.Dispose();
|
|
|
|
_disposed = true;
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Reads <paramref name="count"/> number of bytes to the given <paramref name="buffer"/>, starting at the
|
|
/// specified <paramref name="offset"/>, and returns the number of bytes read. Since this method ensures that
|
|
/// the requested number of bytes is always read, it always returns <paramref name="count"/>, and otherwise
|
|
/// throws an <see cref="IOException"/> if the required bytes could not be read.
|
|
/// </summary>
|
|
/// <param name="buffer">The byte array to write the read data to.</param>
|
|
/// <param name="offset">The offset into <paramref name="buffer"/> at which to start writing data.</param>
|
|
/// <param name="count">The number of bytes to read into <paramref name="buffer"/>.</param>
|
|
/// <exception cref="IOException">The requested number of bytes could not be read.</exception>
|
|
internal void ReadAll(byte[] buffer, int offset, int count)
|
|
{
|
|
int totalRead = 0;
|
|
while (totalRead < count)
|
|
{
|
|
// Read returns 0 only when the underlying socket is closed, otherwise it blocks.
|
|
int read = _baseStream.Read(buffer, offset + totalRead, count - totalRead);
|
|
if (read == 0)
|
|
throw new IOException("The underlying stream has closed, 0 bytes were retrieved.");
|
|
totalRead += read;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads a 2-byte length-prefixed, Windows-949 enoded string.
|
|
/// </summary>
|
|
/// <returns>The read value.</returns>
|
|
internal string ReadString()
|
|
{
|
|
return _baseStream.ReadString(StringCoding.Int16CharCount, _win949Encoding);
|
|
}
|
|
|
|
internal byte[] ReadToEnd()
|
|
{
|
|
return _baseStream.ReadBytes((int)(Length - Position));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Writes a 2-byte length-prefixed, Windows-949 encoded string.
|
|
/// </summary>
|
|
/// <param name="value">The value to write.</param>
|
|
internal void WriteString(string value)
|
|
{
|
|
_baseStream.WriteString(value, StringCoding.Int16CharCount, _win949Encoding);
|
|
}
|
|
}
|
|
}
|