Skip to content

Commit

Permalink
[BMSPT-283] fixed BCF21 version, added proces stream fns to bcf build…
Browse files Browse the repository at this point in the history
…er and converter, fixed and extended tests, extended readme
  • Loading branch information
BalintBende committed Sep 5, 2024
1 parent 9b8583f commit 6e81181
Show file tree
Hide file tree
Showing 30 changed files with 391 additions and 272 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,42 @@ worker.ToBcf(bcf, BcfVersionEnum.Bcf30, outputStream, token);
await outputStream.FlushAsync();
```

#### Stream processing with delegate callbacks
The converters support processing BCF file streams with delegate-based callback
functions. This allows for the incremental construction of an in-memory BCF
representation, where a delegate function is invoked after each part of the BCF
is processed. It allows a more equal memory usage.

To use this feature, the user must create a custom delegate class which
implements the `IBcfBuilderDelegate` interface. This interface defines the
callback methods that will be triggered after each part of the BCF is built.

Implement custom delegate class:
```csharp
public class BcfBuilderDelegate : IBcfBuilderDelegate {
public IBcfBuilderDelegate.OnMarkupCreated<IMarkup>
MarkupCreated { get; } = Console.WriteLine;

public IBcfBuilderDelegate.OnExtensionsCreated<IExtensions>
ExtensionsCreated { get; } = Console.WriteLine;

public IBcfBuilderDelegate.OnProjectCreated<IProject>
ProjectCreated { get; } = Console.WriteLine;

public IBcfBuilderDelegate.OnDocumentCreated<IDocumentInfo>
DocumentCreatedCreated { get; } = Console.WriteLine;
}
```

Process BCF stream:
```csharp
var bcfBuilderDelegate = new BcfBuilderDelegate();
builder = new BcfBuilder();
builder.SetDelegate(bcfBuilderDelegate);
await using var stream = new FileStream(source, FileMode.Open, FileAccess.Read);
await builder.ProcessStream(stream);
```

## File Structure

The structure of the BCF is per [the standard][3]. There is, however, no
Expand Down
45 changes: 18 additions & 27 deletions bcf-toolkit.sln.DotSettings.user
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">/Users/balintbende/Library/Caches/JetBrains/Rider2024.1/resharper-host/temp/Rider/vAny/CoverageData/_bcf-toolkit.-1315391344/Snapshot/snapshot.utdcvr</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=00488d9b_002Ddfb9_002D47fc_002Da7da_002D60da862eab61/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from Solution #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=14575ace_002D843e_002D446c_002Daad2_002Da5b832d528be/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="BuildBcfFromV30StreamTest" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::Tests.WorkerTests.BuildBcfFromV30StreamTest&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=4dc5af78_002D6a8f_002D4f5b_002D8833_002Df0ff81e0c049/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution #3" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=c860e8d9_002Dc3a5_002D4900_002Dbc91_002Da8dce4945409/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String>


<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=64259359_002Daf01_002D4100_002Db5a8_002D06c7d51d9f83/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="BuildMaximumInformationBcfFromStreamTest" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::tests.Builder.Bcf21.BcfBuilderTests.BuildMaximumInformationBcfFromStreamTest&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String>


<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=7d7fd643_002Dccec_002D4fc7_002D8938_002D22e83b255cb0/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="BuildEmptyBcfFromStream" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::tests.Builder.Bcf21.BcfBuilderTests.BuildEmptyBcfFromStream&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String>



Expand All @@ -40,21 +22,30 @@



<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=87607a24_002D24bc_002D46e1_002Da035_002D28c18ba9b643/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String>







<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=b2d5c176_002Dc751_002D42d4_002Da842_002D3ad7ad02438d/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="WorkerTests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::Tests.WorkerTests&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String>




















Expand Down
13 changes: 12 additions & 1 deletion src/bcf-toolkit/Builder/Bcf21/BcfBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ public partial class BcfBuilder : IBcfBuilder<
ProjectExtensionBuilder>,
IDefaultBuilder<BcfBuilder> {
private readonly Bcf _bcf = new();


public BcfBuilder() {
SetVersion();
}

public BcfBuilder AddMarkup(Action<MarkupBuilder> builder) {
var markup =
(Markup)BuilderUtils.BuildItem<MarkupBuilder, IMarkup>(builder);
Expand All @@ -28,6 +32,13 @@ public BcfBuilder SetProject(Action<ProjectExtensionBuilder> builder) {
return this;
}

public BcfBuilder SetVersion() {
_bcf.Version = new VersionBuilder()
.WithDefaults()
.Build();
return this;
}

public BcfBuilder WithDefaults() {
this.AddMarkup(m => m.WithDefaults());
return this;
Expand Down
28 changes: 12 additions & 16 deletions src/bcf-toolkit/Builder/Bcf21/BcfBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,32 @@
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using BcfToolkit.Builder.Interfaces;
using BcfToolkit.Model;
using BcfToolkit.Model.Bcf21;
using BcfToolkit.Utils;
using Interfaces_IBcfBuilderDelegate = BcfToolkit.Builder.Interfaces.IBcfBuilderDelegate;

namespace BcfToolkit.Builder.Bcf21;

public partial class BcfBuilder {
private readonly Interfaces_IBcfBuilderDelegate? _delegate;
public BcfBuilder(Interfaces_IBcfBuilderDelegate builderDelegate = null) {
private IBcfBuilderDelegate? _delegate;

public void SetDelegate(IBcfBuilderDelegate? builderDelegate) {
this._delegate = builderDelegate;

_bcf.Version = new VersionBuilder()
.WithDefaults()
.Build();
}
public async Task ProcessStream(Stream source) {

public Task ProcessStream(Stream source) {
if (_delegate is null) {
Console.WriteLine("IBcfBuilderDelegate is not set.");
return;
return Task.CompletedTask;
}

// await BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(source, _delegate.MarkupCreated);
var tasks = new List<Task> {
BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(source, _delegate.MarkupCreated),
BcfExtensions.ParseProject<ProjectExtension>(source, _delegate.ProjectCreated)
};

// var extensions = await BcfExtensions.ParseExtensions<Extensions>(source);
// _delegate.ExtensionsCreated(extensions);
//
// _bcf.Project = await BcfExtensions.ParseProject<ProjectInfo>(source);
// _bcf.Document = await BcfExtensions.ParseDocuments<DocumentInfo>(source);
return Task.WhenAll(tasks);
}

public async Task<Bcf> BuildInMemoryFromStream(Stream source) {
Expand Down
1 change: 0 additions & 1 deletion src/bcf-toolkit/Builder/Bcf21/VisibilityBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using BcfToolkit.Builder.Bcf21.Interfaces;
using BcfToolkit.Model;
using BcfToolkit.Model.Bcf21;
using BcfToolkit.Model.Interfaces;

Expand Down
4 changes: 2 additions & 2 deletions src/bcf-toolkit/Builder/Bcf30/BcfBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public partial class BcfBuilder : IBcfBuilder<
ExtensionsBuilder,
DocumentInfoBuilder>,
IDefaultBuilder<BcfBuilder> {

private readonly Bcf _bcf = new();

public BcfBuilder() {
SetVersion();
}
Expand Down
40 changes: 21 additions & 19 deletions src/bcf-toolkit/Builder/Bcf30/BcfBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,35 @@
namespace BcfToolkit.Builder.Bcf30;

public partial class BcfBuilder {

private IBcfBuilderDelegate? _delegate;

public void SetDelegate(IBcfBuilderDelegate? builderDelegate) {
this._delegate = builderDelegate;
}
public async Task ProcessStream(Stream source) {

public Task ProcessStream(Stream source) {
if (_delegate is null) {
Console.WriteLine("IBcfBuilderDelegate is not set.");
return;
return Task.CompletedTask;
}

await BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(
source,
_delegate.MarkupCreated);

// var extensions = await BcfExtensions.ParseExtensions<Extensions>(source);
// _delegate.ExtensionsCreated(extensions);
//
// _bcf.Project = await BcfExtensions.ParseProject<ProjectInfo>(source);
// _bcf.Document = await BcfExtensions.ParseDocuments<DocumentInfo>(source);
// var extensions = await BcfExtensions.ParseExtensions<Extensions>(source);
var tasks = new List<Task> {
BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(
source,
_delegate.MarkupCreated),
BcfExtensions.ParseExtensions<Extensions>(
source,
_delegate.ExtensionsCreated),
BcfExtensions.ParseProject<ProjectInfo>(
source,
_delegate.ProjectCreated),
BcfExtensions.ParseDocuments<DocumentInfo>(
source,
_delegate.DocumentCreatedCreated)
};

// _bcf.Project = await BcfExtensions.ParseProject<ProjectInfo>(source);
// _bcf.Document = await BcfExtensions.ParseDocuments<DocumentInfo>(source);
return Task.WhenAll(tasks);
}

//
Expand All @@ -46,8 +49,7 @@ await BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(
/// <param name="source">The file stream.</param>
/// <returns>Returns the built object.</returns>
public async Task<Bcf> BuildInMemoryFromStream(Stream source) {
_bcf.Markups =
await BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(source);
_bcf.Markups = await BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(source);
_bcf.Extensions = await BcfExtensions.ParseExtensions<Extensions>(source);
_bcf.Project = await BcfExtensions.ParseProject<ProjectInfo>(source);
_bcf.Document = await BcfExtensions.ParseDocuments<DocumentInfo>(source);
Expand Down
8 changes: 4 additions & 4 deletions src/bcf-toolkit/Builder/Interfaces/IBcfBuilderDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ namespace BcfToolkit.Builder.Interfaces;
public interface IBcfBuilderDelegate {
public delegate void OnMarkupCreated<in TMarkup>(TMarkup markup)
where TMarkup : IMarkup;

public delegate void OnProjectCreated<in TProjectInfo>(
TProjectInfo projectInfo)
where TProjectInfo : IProject;

public delegate void OnExtensionsCreated<in TExtensions>(
TExtensions extensions)
where TExtensions : IExtensions;

public delegate void OnDocumentCreated<in TDocumentInfo>(
TDocumentInfo documentInfo)
where TDocumentInfo : IDocumentInfo;

public OnMarkupCreated<IMarkup> MarkupCreated { get; }
public OnExtensionsCreated<IExtensions> ExtensionsCreated { get; }
public OnProjectCreated<IProject> ProjectCreated { get; }
Expand Down
18 changes: 10 additions & 8 deletions src/bcf-toolkit/Converter/Bcf21/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
using BcfToolkit.Builder.Bcf21;
using BcfToolkit.Builder.Interfaces;
using BcfToolkit.Utils;
using BcfToolkit.Model;
using BcfToolkit.Model.Bcf21;
Expand All @@ -19,7 +20,7 @@ namespace BcfToolkit.Converter.Bcf21;
/// </summary>
public class Converter : IConverter {
private BcfBuilder _builder = new();

/// <summary>
/// Defines the converter function, which must be used for converting the
/// BCF object to the targeted version.
Expand Down Expand Up @@ -57,7 +58,7 @@ private readonly Dictionary<
};

public async Task BcfToJson(Stream source, string targetPath) {
var bcf = await _builder.BuildInMemoryFromStream(source);
var bcf = await _builder.BuildInMemoryFromStream(source);
await FileWriter.WriteBcfToJson(bcf, targetPath);
}

Expand Down Expand Up @@ -144,17 +145,18 @@ public Task ToBcf(IBcf bcf, string target) {
public Task ToJson(IBcf bcf, string target) {
return FileWriter.WriteBcfToJson((Bcf)bcf, target);
}

public async Task<T> BcfFromStream<T>(Stream stream) {
var bcf = await _builder.BuildInMemoryFromStream(stream);
var targetVersion = BcfVersion.TryParse(typeof(T));
var converterFn = _converterFn[targetVersion];
return (T)converterFn(bcf);
}

public async Task ProcessStream(Stream stream) {
// var targetVersion = BcfVersion.TryParse(typeof(T));
_builder.Set
await _builder.ProcessStream(stream);

public Task ProcessStream(
Stream stream,
IBcfBuilderDelegate builderDelegate) {
_builder.SetDelegate(builderDelegate);
return _builder.ProcessStream(stream);
}
}
6 changes: 3 additions & 3 deletions src/bcf-toolkit/Converter/Bcf21/FileWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static void SerializeAndWriteBcfToStream(
}

var topicFolder = $"{guid}";

zip.CreateEntryFromObject($"{topicFolder}/markup.bcf", markup);

foreach (var viewpoint in markup.Viewpoints) {
Expand Down Expand Up @@ -194,13 +194,13 @@ public static async Task<string> SerializeAndWriteBcfToFolder(
topicFolder,
"markup.bcf",
markup));

foreach (var viewpoint in markup.Viewpoints) {
writeTasks.Add(BcfExtensions.SerializeAndWriteXmlFile(
topicFolder,
viewpoint.Viewpoint,
viewpoint.VisualizationInfo));

var snapshotFileName = viewpoint.Snapshot;
var snapshotBase64String = viewpoint.SnapshotData?.Data;
if (string.IsNullOrEmpty(snapshotFileName) || snapshotBase64String == null)
Expand Down
2 changes: 1 addition & 1 deletion src/bcf-toolkit/Converter/Bcf21/SchemaConverterToBcf30.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static Model.Bcf30.Bcf Convert(Model.Bcf21.Bcf from) {

return builder.Build();
}

// public static async Task ProcessStream(Stream stream) {
// var del = new BcfBuilderDelegate();
// var fromBuilder = new BcfToolkit.Builder.Bcf21.BcfBuilder(del);
Expand Down
Loading

0 comments on commit 6e81181

Please sign in to comment.