Skip to content

Commit 2d22fe8

Browse files
committed
We now use CFNCSVConverterOptions to specify all options for a CFNCSVConverter which makes code more readable and is more compatible with DI.
1 parent 98feaa4 commit 2d22fe8

File tree

5 files changed

+65
-48
lines changed

5 files changed

+65
-48
lines changed

CFNReader.Tests/CFNCSVConverterTests.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ public class CFNCSVConverterTests
77
public async Task CFNCSVConverter_Converts_Correctly()
88
{
99
var fromtime = TimeSpan.FromSeconds(10.5);
10-
var csvconverter = new CFNCSVConverter(
11-
channels: [Channel.AccumulatedCapacity, Channel.VBusVoltage],
12-
predicate: (dp) => dp.Time >= fromtime,
13-
separator: "!",
14-
includeUnit: true,
15-
limitDataPoints: 2
16-
);
10+
var csvconverter = new CFNCSVConverter(new CFNCSVConverterOptions()
11+
{
12+
Channels = [Channel.AccumulatedCapacity, Channel.VBusVoltage],
13+
Predicate = (dp) => dp.Time >= fromtime,
14+
Separator = "!",
15+
IncludeUnit = true,
16+
LimitDataPoints = 2
17+
});
1718

1819
using var testfile = File.OpenRead("Testfiles/test.cfn");
1920
using var csvfile = new MemoryStream();

CFNReader/CFNCSVConverter.cs

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,44 @@
1-
using System;
1+
using Microsoft.Extensions.Options;
2+
using System;
23
using System.Collections.Generic;
3-
using System.Globalization;
44
using System.IO;
55
using System.Linq;
6-
using System.Text;
76
using System.Threading;
87
using System.Threading.Tasks;
98

109
namespace CFNReader;
1110

12-
public class CFNCSVConverter(
13-
IEnumerable<Channel>? channels = null,
14-
Func<Datapoint, bool>? predicate = null,
15-
IFormatProvider? formatProvider = null,
16-
string separator = ";",
17-
Encoding? encoding = null,
18-
string timeFormat = "G",
19-
string valueFormat = "N4",
20-
bool includeHeader = true,
21-
bool includeTime = true,
22-
bool includeUnit = false,
23-
int limitDataPoints = int.MaxValue
24-
)
11+
public class CFNCSVConverter(IOptions<CFNCSVConverterOptions> options)
2512
{
26-
private readonly IEnumerable<Channel>? _channels = channels;
27-
private readonly Func<Datapoint, bool> _predicate = predicate ?? (_ => true);
28-
private readonly IFormatProvider _formatprovider = formatProvider ?? CultureInfo.InvariantCulture;
29-
private readonly string _separator = separator;
30-
private readonly Encoding _encoding = encoding ?? Encoding.UTF8;
31-
private readonly string _timeformat = timeFormat;
32-
private readonly string _valueformat = valueFormat;
33-
private readonly bool _includeheader = includeHeader;
34-
private readonly bool _includetime = includeTime;
35-
private readonly bool _includeunit = includeUnit;
36-
private readonly int _maxdatapoints = limitDataPoints;
13+
private readonly CFNCSVConverterOptions _options = options?.Value ?? throw new ArgumentNullException(nameof(options));
14+
15+
public CFNCSVConverter(CFNCSVConverterOptions options)
16+
: this(Options.Create(options)) { }
3717

3818
public async Task ConvertToCSVAsync(Stream cnfStream, Stream csvStream, CancellationToken cancellationToken = default)
3919
{
4020
var cfnreader = new CFNStreamReader(cnfStream);
4121

4222
var fileinfo = await cfnreader.ReadFileInfoAsync(cancellationToken);
4323

44-
var exportchannels = (_channels ?? fileinfo.Channels.Keys).Where(fileinfo.Channels.ContainsKey).ToArray();
24+
var exportchannels = (_options.Channels ?? fileinfo.Channels.Keys).Where(fileinfo.Channels.ContainsKey).ToArray();
4525

46-
using var sw = new StreamWriter(csvStream, _encoding, -1, true);
26+
using var sw = new StreamWriter(csvStream, _options.Encoding, -1, true);
4727

48-
if (_includeheader)
28+
if (_options.IncludeHeader)
4929
{
50-
await sw.WriteLineAsync(string.Join(_separator, GetHeaderNames(exportchannels)));
30+
await sw.WriteLineAsync(string.Join(_options.Separator, GetHeaderNames(exportchannels)));
5131
}
5232

53-
await foreach (var dp in cfnreader.ReadDatapointsAsync(fileinfo, cancellationToken).Where(_predicate).Take(_maxdatapoints))
33+
await foreach (var dp in cfnreader.ReadDatapointsAsync(fileinfo, cancellationToken).Where(_options.Predicate).Take(_options.LimitDataPoints))
5434
{
55-
await sw.WriteLineAsync(string.Join(_separator, GetValues(exportchannels, dp)));
35+
await sw.WriteLineAsync(string.Join(_options.Separator, GetValues(exportchannels, dp)));
5636
}
5737
}
5838

5939
private IEnumerable<string> GetHeaderNames(Channel[] channels)
6040
{
61-
if (_includetime)
41+
if (_options.IncludeTime)
6242
{
6343
yield return nameof(Datapoint.Time);
6444
}
@@ -70,9 +50,9 @@ private IEnumerable<string> GetHeaderNames(Channel[] channels)
7050

7151
private IEnumerable<string> GetValues(Channel[] channels, Datapoint datapoint)
7252
{
73-
if (_includetime)
53+
if (_options.IncludeTime)
7454
{
75-
yield return datapoint.Time.ToString(_timeformat, _formatprovider);
55+
yield return datapoint.Time.ToString(_options.TimeFormat, _options.FormatProvider);
7656
}
7757
foreach (var channel in channels)
7858
{
@@ -81,5 +61,5 @@ private IEnumerable<string> GetValues(Channel[] channels, Datapoint datapoint)
8161
}
8262

8363
private string FormatValue(UnitValue value)
84-
=> $"{value.Value.ToString(_valueformat, _formatprovider)}{(_includeunit ? value.Unit : string.Empty)}";
64+
=> $"{value.Value.ToString(_options.ValueFormat, _options.FormatProvider)}{(_options.IncludeUnit ? value.Unit : string.Empty)}";
8565
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.Text;
5+
6+
namespace CFNReader;
7+
8+
public record CFNCSVConverterOptions
9+
{
10+
public IEnumerable<Channel> Channels { get; init; } = DefaultChannels;
11+
public Func<Datapoint, bool> Predicate { get; init; } = DefaultPredicate;
12+
public IFormatProvider? FormatProvider { get; init; } = DefaultFormatProvider;
13+
public string Separator { get; init; } = DefaultSeparator;
14+
public Encoding? Encoding { get; init; } = DefaultEncoding;
15+
public string TimeFormat { get; init; } = DefaultTimeFormat;
16+
public string ValueFormat { get; init; } = DefaultValueFormat;
17+
public bool IncludeHeader { get; init; } = DefaultIncludeHeader;
18+
public bool IncludeTime { get; init; } = DefaultIncludeTime;
19+
public bool IncludeUnit { get; init; } = DefaultIncludeUnit;
20+
public int LimitDataPoints { get; init; } = DefaultLimitDataPoints;
21+
22+
public static readonly CFNCSVConverterOptions Default = new();
23+
24+
public static readonly IEnumerable<Channel> DefaultChannels = [Channel.VBusVoltage, Channel.VBusCurrent];
25+
public static readonly Func<Datapoint, bool> DefaultPredicate = _ => true;
26+
public static readonly IFormatProvider DefaultFormatProvider = CultureInfo.InvariantCulture;
27+
public const string DefaultSeparator = ";";
28+
public static readonly Encoding DefaultEncoding = Encoding.UTF8;
29+
public const string DefaultTimeFormat = "G";
30+
public const string DefaultValueFormat = "N4";
31+
public const bool DefaultIncludeHeader = true;
32+
public const bool DefaultIncludeTime = true;
33+
public const bool DefaultIncludeUnit = false;
34+
public const int DefaultLimitDataPoints = int.MaxValue;
35+
}

CFNReader/CFNReader.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@
2828
</ItemGroup>
2929

3030
<ItemGroup>
31+
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.3" />
3132
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
32-
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
33-
<PackageReference Include="PolySharp" Version="1.14.1">
33+
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.3" />
34+
<PackageReference Include="PolySharp" Version="1.15.0">
3435
<PrivateAssets>all</PrivateAssets>
3536
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3637
</PackageReference>
37-
<PackageReference Include="System.Memory" Version="4.5.5" />
38+
<PackageReference Include="System.Memory" Version="4.6.0" />
3839
</ItemGroup>
3940

4041
<ItemGroup>

CFNReader/CFNStreamReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private static async Task<double[]> ReadDataAsync(Stream stream, byte[] buffer,
6565
var bytesread = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
6666
return bytesread != buffer.Length
6767
? throw new MalformedRecordException(typeof(UnitValue[]), stream.Position, buffer.Length, bytesread)
68-
: Enumerable.Range(0, count).Select(i => BitConverter.ToDouble(buffer, i * _doublesize)).ToArray();
68+
: [.. Enumerable.Range(0, count).Select(i => BitConverter.ToDouble(buffer, i * _doublesize))];
6969
}
7070

7171
private Task<HeaderRecord> ReadHeaderAsync(CancellationToken cancellationToken = default)

0 commit comments

Comments
 (0)