Skip to content

Commit

Permalink
Work on new Zily protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
Aeliux committed Aug 19, 2023
1 parent 81a0fab commit 2437a4a
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 84 deletions.
4 changes: 0 additions & 4 deletions src/Zily.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@
</PropertyGroup>

<ItemGroup>
<Compile Remove="StreamWrapper.cs" />
<Compile Remove="ZilyPipeClientStream.cs" />
<Compile Remove="ZilyPipeServerStream.cs" />
<Compile Remove="ZilyPipeStream.cs" />
<Compile Remove="ZilyStream.cs" />
<Compile Remove="ZilyTextWriter.cs" />
</ItemGroup>

Expand All @@ -40,11 +38,9 @@
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="StreamWrapper.cs" />
<None Include="ZilyPipeClientStream.cs" />
<None Include="ZilyPipeServerStream.cs" />
<None Include="ZilyPipeStream.cs" />
<None Include="ZilyStream.cs" />
<None Include="ZilyTextWriter.cs" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion src/ZilyHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private ZilyHeader(int flag, string text, byte[] unicode_text)
/// <returns>
/// A new instance of the <see cref="ZilyHeader"/>.
/// </returns>
public virtual ZilyHeader Parse(Stream stream)
public static ZilyHeader Parse(Stream stream)
{
int flag;
string text = null;
Expand Down
10 changes: 10 additions & 0 deletions src/ZilyHeaderFlag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,15 @@ public class ZilyHeaderFlag
/// Indicates a potential abnormal state.
/// </summary>
public const int Warn = 3;

/// <summary>
/// Indicates an established connection.
/// </summary>
public const int Connected = 4;

/// <summary>
/// Indicates an refused connection.
/// </summary>
public const int Disconnected = 5;
}
}
13 changes: 13 additions & 0 deletions src/ZilySide.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ public class ZilySide : Side
{
int last_request;

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

The field 'ZilySide.last_request' is never used

Check warning on line 10 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

The field 'ZilySide.last_request' is never used

/// <summary>
/// Gets the proper flag for disconnect message.
/// </summary>
public virtual int DisconnectFlag => ZilyHeaderFlag.Disconnected;

internal ZilyStream zs;

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on windows

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on ubuntu

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Debug on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

Check warning on line 17 in src/ZilySide.cs

View workflow job for this annotation

GitHub Actions / build / Build Release on macos

Field 'ZilySide.zs' is never assigned to, and will always have its default value null

/// <summary>
/// Initializes a new instance of the <see cref="ZilySide"/>.
/// </summary>
Expand Down Expand Up @@ -68,6 +75,12 @@ public virtual void ParseHeader(ZilyHeader header)
case ZilyHeaderFlag.Fail:
// Throw an exception with the error message.
throw new ZilyException(header.Text);
case ZilyHeaderFlag.Connected:
zs.IsOnline = true;
break;
case ZilyHeaderFlag.Disconnected:
zs.IsOnline = false;
break;
default:
// Throw an exception because the response is unknown.
throw new ArgumentException("Invalid response.");
Expand Down
162 changes: 83 additions & 79 deletions src/ZilyStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System.Linq;
using Serilog;
using System.Threading;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

namespace SAPTeam.Zily
{
Expand All @@ -13,19 +15,19 @@ namespace SAPTeam.Zily
public partial class ZilyStream : Stream
{
/// <summary>
/// Gets the protocol version.
/// Gets the underlying <see cref="System.IO.Stream"/>.
/// </summary>
public static Version API = new Version(2, 0);
public Stream Stream { get; }

/// <summary>
/// Gets the stream protocol version.
/// Gets the underlying <see cref="ISide"/> that parses the incoming responses.
/// </summary>
public Version StreamVersion { get; private set; }
public ZilySide Side { get; }

/// <summary>
/// Gets the underlying <see cref="System.IO.Stream"/>.
/// Gets or sets a value indicating whether this connection is online
/// </summary>
public Stream Stream { get; }
public bool IsOnline { get; set; }

private readonly UnicodeEncoding streamEncoding;

Expand All @@ -40,10 +42,13 @@ public partial class ZilyStream : Stream
/// <param name="stream">
/// An instance of <see cref="System.IO.Stream"/> with ability to read, write or both.
/// </param>
/// <param name="side">
/// The <see cref="ZilySide"/> that parses the receiving responses.
/// </param>
/// <param name="logger">
/// The application's logger. by default it uses the <see cref="Log.Logger"/>.
/// </param>
public ZilyStream(Stream stream, ILogger logger = null)
public ZilyStream(Stream stream, ZilySide side, ILogger logger = null)
{
if (logger == null)
{
Expand All @@ -53,62 +58,12 @@ public ZilyStream(Stream stream, ILogger logger = null)
logger.Debug("Initializing a new Zily session");

Stream = stream;
Side = side;
streamEncoding = new UnicodeEncoding();
this.logger = logger;
}

/// <summary>
/// Creates a header.
/// </summary>
/// <param name="flag">
/// The header flag.
/// </param>
/// <param name="length">
/// Length of bytes that will be sent.
/// </param>
/// <returns>
/// An array of the header bytes.
/// </returns>
public byte[] CreateHeader(HeaderFlag flag, int length)
{
if (length > ushort.MaxValue)
{
throw new ArgumentException("Length is too long.");
}

return !flag.IsParameterless() ? new byte[]
{
(byte)flag,
(byte)(length / 256),
(byte)(length & 255)
} : new byte[] { (byte)flag };
}

/// <summary>
/// Reads the header from the stream.
/// </summary>
/// <returns>
/// The header flag and Length of the text (argument) for that flag.
/// </returns>
public (HeaderFlag flag, int length) ReadHeader()
{
HeaderFlag flag;

while (true)
{
int data = ReadByte();
if (data != -1)
{
flag = (HeaderFlag)data;
break;
}
}

int length = flag.IsParameterless() ? 0 : Math.Max(0, (ReadByte() * 256) + ReadByte());

return (flag, length);
}

/*
/// <summary>
/// Receives sent data and then parses it.
/// </summary>
Expand Down Expand Up @@ -319,23 +274,24 @@ public string ReadString(int length)
return streamEncoding.GetString(buffer);
}
*/

/// <summary>
/// Creates a header with the given flag and text then writes it beside the given <paramref name="text"/> to the stream.
/// Writes the given <see cref="ZilyHeader"/> to the stream.
/// </summary>
/// <param name="flag">
/// The header flag.
/// </param>
/// <param name="text">
/// The text (argument) for the header flag.
/// <param name="header">
/// An instance of the <see cref="ZilyHeader"/> with outgoing data.
/// </param>
public void WriteCommand(HeaderFlag flag, string text = null)
public void WriteCommand(ZilyHeader header)
{
logger.Debug("Writing data with flag {flag} and message \"{text}\"", flag, text != null ? text.Replace("\n", "") : null);
byte[] body = text != null ? streamEncoding.GetBytes(text) : new byte[0];
byte[] header = CreateHeader(flag, body.Length);
byte[] buffer = header.Concat(body).ToArray();
if (!IsOnline)
{
throw new ZilyException("Zily is not connected.");
}

logger.Debug("Writing data with flag {flag} and message \"{text}\"", header.Flag, header.Text != null ? header.Text.Replace("\n", "") : null);

Byte[] buffer = header.ToByteArray();
Write(buffer, 0, buffer.Length);

if (Stream is MemoryStream)
Expand All @@ -351,19 +307,67 @@ public void WriteCommand(HeaderFlag flag, string text = null)
}

/// <summary>
/// Sends a command to the stream, then waits for receiving response and parses it.
/// Writes the given <see cref="ZilyHeader"/> to the stream, then waits for the response.
/// </summary>
/// <param name="flag">
/// The header flag. Header flags are stored in the <see cref="HeaderFlag"/>.
/// <param name="header">
/// An instance of the <see cref="ZilyHeader"/> with outgoing data.
/// </param>
/// <param name="text">
/// The text (argument) for the requested action or response to a request.
public void Send(ZilyHeader header)
{
WriteCommand(header);
ZilyHeader header2 = ZilyHeader.Parse(Stream);
Side.ParseHeader(header2);
}

/// <summary>
/// Listens to all incoming requests.
/// </summary>
/// <param name="cancellationToken">
/// A token for terminating the listener.
/// </param>
public void Send(HeaderFlag flag, string text = null)
/// <param name="suppressLogger">
/// Determines whether the logger should be stopped during listening.
/// </param>
public void Listen(CancellationToken cancellationToken, bool suppressLogger = true)
{
logger.Information("Staring listener");
ILogger _logger = null;
if (suppressLogger)
{
_logger = logger;
logger = Serilog.Core.Logger.None;
}

while (!cancellationToken.IsCancellationRequested)
{
try
{
var header = ZilyHeader.Parse(Stream);
Side.ParseHeader(header);
}
catch (IOException)
{
break;
}
}

if (suppressLogger)
{
logger = _logger;
}

logger.Information("Listener has stopped");
}

/// <inheritdoc/>
public override void Close()
{
WriteCommand(flag, text);
var header = ReadHeader();
ParseResponse(header);
logger.Information("Closing connection");
if (IsOnline)
{
WriteCommand(new ZilyHeader(Side.DisconnectFlag));
IsOnline = false;
}
}
}
}

0 comments on commit 2437a4a

Please sign in to comment.