Skip to content

Commit

Permalink
cleanup unnecessary code.
Browse files Browse the repository at this point in the history
fix xml doc.
upgrade to .net 6.0 rc1.
update readme.md.
fix netstandard2.0 WithCancellation extension method.
  • Loading branch information
mkjeff committed Sep 20, 2021
1 parent 05aacc5 commit d4253a7
Show file tree
Hide file tree
Showing 29 changed files with 171 additions and 237 deletions.
95 changes: 78 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to com

**Getting started**

1. ## Install nuget package
## Install nuget package
> dotnet add package Secs4Net --version 2.0.0-rc4.0
2. ## Configure .NET dependency injection

## Configure .NET dependency injection
```cs
public void ConfigureServices(IServiceCollection services)
{
Expand All @@ -28,9 +29,9 @@ SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to com
{
// implement ISecsGemLogger methods
}
```

```
3. ## Basic usage
## Basic usage
```cs
try
{
Expand Down Expand Up @@ -90,7 +91,8 @@ SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to com
// device reply S9Fx
}
```
4. ## Handle primary messages

## Handle primary messages
```cs
await foreach (var e in secsGem.GetPrimaryMessageAsync(cancellationToken))
{
Expand All @@ -103,7 +105,7 @@ SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to com
};
```

5. ## Creates `Item` via LINQ
## Creates `Item` via LINQ
```cs
using static Secs4Net.Item;

Expand Down Expand Up @@ -136,17 +138,16 @@ SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to com
L()))));
```

6. ## `Item` is mutable with restrict.
> Basic rule: The `Item.Count` has been fixed while the item was created.

That means you can only overwrite values on existing memory.
String Item is still immutable, coz C# `string` is immutable as well.
## Modify `Item` in restrict.
> Basic rule: The `Item.Count` has been fixed while the item was created.

7. ## Reuse pooled array for large item values
You can only overwrite values on existing memory. String Item is immutable, coz C# `string` is immutable as well.

All unmanaged data Item can created from `IMemoryOwner<T>` or `Memory<T>`.
## Reuse array for large item values
All unmanaged data Item can created from `IMemoryOwner<T>` or `Memory<T>`.

The following sample uses the implementation of `IMemoryOwner<T>` from [`Microsoft.Toolkit.HighPerformance`](https://docs.microsoft.com/en-us/windows/communitytoolkit/high-performance/memoryowner) that has been referenced internally by secs4net..
The following sample uses the implementation of `IMemoryOwner<T>` from [`Microsoft.Toolkit.HighPerformance`](https://docs.microsoft.com/en-us/windows/communitytoolkit/high-performance/memoryowner) that has been referenced internally by secs4net..
```cs
var largeArrayOwner = MemoryOwner<int>.Allocate(size: 65535);

Expand All @@ -167,8 +168,68 @@ SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to com
using var s6f12 = await secsGem.SendAsync(s6f11);

```
> `IMemoryOwner<T>`, `Item` and `SecsMessage` have implemented `IDisposable` don't forget to Dispose it when they don't need anymore.
> `IMemoryOwner<T>`, `Item` and `SecsMessage` have implemented `IDisposable` don't forget to Dispose it when they don't need anymore.
Otherwise, the array will not return to the pool till GC collects.

> Since the max encoded bytes length in a single non-List Item was `16,777,215`(3 bytes), we split raw data into separated items.
> Since the max encoded bytes length in a single non-List Item was `16,777,215`(3 bytes), we split raw data into separated items.
In that case, creating the Items from sliced `Memory<T>` is more efficient.

## LINQPad
If you like to use LINQPad to dump `Item` object in a simplified format, you probably need a [custom dump method](http://www.linqpad.net/CustomizingDump.aspx) method. Adjust your LINQPad **My Extensions** file as follow
```cs
static object ToDump(object obj)
{
var objType = obj.GetType();
if (Type.GetType("Secs4Net.Item,Secs4Net") is { } itemType && objType.IsSubclassOf(itemType))
{
return Dump(obj);
}
return obj;
}

static object Dump(dynamic item)
{
return (int)item.Format switch
{
(int)SecsFormat.List => new { item.Format, Values = OnDemandList(item), },
(int)SecsFormat.ASCII => new { item.Format, Values = item.GetString() },
(int)SecsFormat.JIS8 => new { item.Format, Values = item.GetString() },
(int)SecsFormat.Binary => new { item.Format, Values = OnDemandMemory<byte>(item) },
(int)SecsFormat.Boolean => new { item.Format, Values = OnDemandMemory<bool>(item) },
(int)SecsFormat.I8 => new { item.Format, Values = OnDemandMemory<long>(item) },
(int)SecsFormat.I1 => new { item.Format, Values = OnDemandMemory<sbyte>(item) },
(int)SecsFormat.I2 => new { item.Format, Values = OnDemandMemory<short>(item) },
(int)SecsFormat.I4 => new { item.Format, Values = OnDemandMemory<int>(item) },
(int)SecsFormat.F8 => new { item.Format, Values = OnDemandMemory<double>(item)},
(int)SecsFormat.F4 => new { item.Format, Values = OnDemandMemory<float>(item) },
(int)SecsFormat.U8 => new { item.Format, Values = OnDemandMemory<ulong>(item) },
(int)SecsFormat.U1 => new { item.Format, Values = OnDemandMemory<byte>(item) },
(int)SecsFormat.U2 => new { item.Format, Values = OnDemandMemory<ushort>(item)},
(int)SecsFormat.U4 => new { item.Format, Values = OnDemandMemory<uint>(item) },
_ => $"Unsupported Format: {item.Format}",
};

static object OnDemandList(dynamic item) => Util.OnDemand($"[{item.Count}]", () => item.Items);
static object OnDemandMemory<T>(dynamic item) => Util.OnDemand($"[{item.Count}]", () => item.GetMemory<T>());
}

// You can also define namespaces, non-static classes, enums, etc.
enum SecsFormat
{
List = 0b_0000_00,
Binary = 0b_0010_00,
Boolean = 0b_0010_01,
ASCII = 0b_0100_00,
JIS8 = 0b_0100_01,
I8 = 0b_0110_00,
I1 = 0b_0110_01,
I2 = 0b_0110_10,
I4 = 0b_0111_00,
F8 = 0b_1000_00,
F4 = 0b_1001_00,
U8 = 0b_1010_00,
U1 = 0b_1010_01,
U2 = 0b_1010_10,
U4 = 0b_1011_00,
}
```
8 changes: 4 additions & 4 deletions samples/DeviceWorkerService/DeviceWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
await foreach (var m in _secsGem.GetPrimaryMessageAsync(stoppingToken))
await foreach (var e in _secsGem.GetPrimaryMessageAsync(stoppingToken))
{
using var primaryMessage = m.PrimaryMessage;
_logger.LogInformation($"Received primary message: {primaryMessage.ToString()}");
using var primaryMessage = e.PrimaryMessage;
_logger.LogInformation($"Received primary message: {primaryMessage}");
try
{
using var secondaryMessage = new SecsMessage(primaryMessage.S, (byte)(primaryMessage.F + 1))
{
SecsItem = primaryMessage.SecsItem,
};
await m.TryReplyAsync(secondaryMessage, stoppingToken);
await e.TryReplyAsync(secondaryMessage, stoppingToken);
}
catch (Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion samples/DeviceWorkerService/DeviceWorkerService.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0-preview.7.*" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0-rc.1.*" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Secs4Net.Json/Secs4Net.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="6.0.0-preview.7.*" />
<PackageReference Include="System.Text.Json" Version="6.0.0-rc.1.*" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
12 changes: 9 additions & 3 deletions src/Secs4Net.Sml/SmlReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ public static class SmlReader
{
public static async IAsyncEnumerable<SecsMessage> ToSecsMessages(this TextReader reader)
{
var stack = new Stack<List<Item>>();
while (reader.Peek() != -1)
{
yield return await reader.ToSecsMessageAsync();
yield return await reader.ToSecsMessageAsync(stack);
stack.Clear();
}
}

Expand All @@ -28,7 +30,12 @@ public static SecsMessage ToSecsMessage(this string str)
return sr.ToSecsMessage();
}

public static async Task<SecsMessage> ToSecsMessageAsync(this TextReader sr)
public static Task<SecsMessage> ToSecsMessageAsync(this TextReader sr)
{
return sr.ToSecsMessageAsync(new Stack<List<Item>>());
}

private static async Task<SecsMessage> ToSecsMessageAsync(this TextReader sr, Stack<List<Item>> stack)
{
var line = await sr.ReadLineAsync();
#if NET
Expand All @@ -37,7 +44,6 @@ public static async Task<SecsMessage> ToSecsMessageAsync(this TextReader sr)
var (name, s, f, replyExpected) = ParseFirstLine(line.AsSpan());
#endif

var stack = new Stack<List<Item>>();
Item? rootItem = null;

#if NET
Expand Down
8 changes: 0 additions & 8 deletions src/Secs4Net/AsyncHelper.cs

This file was deleted.

114 changes: 0 additions & 114 deletions src/Secs4Net/ChunkedSpan.cs

This file was deleted.

32 changes: 2 additions & 30 deletions src/Secs4Net/Extensions/ExtensionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,6 @@ namespace Secs4Net.Extensions;

public static class SecsExtension
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ChunkedSpan<T> Chunk<T>(ref this Span<T> span, int count) => new(span, count);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ChunkedReadOnlySpan<T> Chunk<T>(ref this ReadOnlySpan<T> span, int count) => new(span, count);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ChunkedMemory<T> Chunk<T>(this Memory<T> memory, int count) => new(memory, count);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ChunkedReadOnlyMemory<T> Chunk<T>(this ReadOnlyMemory<T> memory, int count) => new(memory, count);

public static IEnumerable<Memory<T>> AsEnumerable<T>(this ChunkedMemory<T> source)
{
foreach (var m in source)
{
yield return m;
}
}

public static IEnumerable<ReadOnlyMemory<T>> AsEnumerable<T>(this ChunkedReadOnlyMemory<T> source)
{
foreach (var m in source)
{
yield return m;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetName(this SecsFormat format)
{
Expand Down Expand Up @@ -74,7 +46,7 @@ public static unsafe Span<byte> AsBytes<T>(this ref T value) where T : unmanaged

internal static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
{
var tcs = ValueTaskCompletionSource<object?>.Create();
var tcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);

// This disposes the registration as soon as one of the tasks trigger
using (cancellationToken.Register(static state => ((TaskCompletionSource<object?>)state!).TrySetResult(null), tcs))
Expand All @@ -92,7 +64,7 @@ internal static async Task WithCancellation(this Task task, CancellationToken ca

internal static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
var tcs = ValueTaskCompletionSource<object?>.Create();
var tcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);

// This disposes the registration as soon as one of the tasks trigger
using (cancellationToken.Register(static state => ((TaskCompletionSource<object?>)state!).TrySetResult(null), tcs))
Expand Down
Loading

0 comments on commit d4253a7

Please sign in to comment.