diff --git a/.docfx/Dockerfile.docfx b/.docfx/Dockerfile.docfx index 65b45464c..d66eaab59 100644 --- a/.docfx/Dockerfile.docfx +++ b/.docfx/Dockerfile.docfx @@ -1,4 +1,4 @@ -ARG NGINX_VERSION=1.29.4-alpine +ARG NGINX_VERSION=1.29.5-alpine FROM --platform=$BUILDPLATFORM nginx:${NGINX_VERSION} AS base RUN rm -rf /usr/share/nginx/html/* diff --git a/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt index f51a821fa..0fcc64de1 100644 --- a/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt index ce201931a..47f607226 100644 --- a/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt index 3e6bdf67a..f71eee89f 100644 --- a/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt index f51a821fa..0fcc64de1 100644 --- a/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt index 90816b1fe..91b21cd6d 100644 --- a/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt b/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt index b68b28ab3..f67548e25 100644 --- a/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Core/PackageReleaseNotes.txt b/.nuget/Cuemon.Core/PackageReleaseNotes.txt index 9a6dbdd68..b965b466e 100644 --- a/.nuget/Cuemon.Core/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Core/PackageReleaseNotes.txt @@ -1,3 +1,14 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  +# Improvements +- OPTIMIZED StreamDecoratorExtensions class in the Cuemon.IO namespace to reduce memory allocations and improve throughput of InvokeToByteArray by eliminating redundant buffer copies for non-MemoryStream inputs (allocation ratio reduced from ~2x to ~1x for typical payload sizes) +- OPTIMIZED StreamDecoratorExtensions class in the Cuemon.IO namespace to cache Length access and avoid repeated virtual calls on seekable streams +- OPTIMIZED StreamDecoratorExtensions class in the Cuemon.IO namespace to return Array.Empty() for zero-length seekable streams to avoid unnecessary MemoryStream allocation +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt b/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt b/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt index 7ab29b5c1..efaf92e88 100644 --- a/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Data/PackageReleaseNotes.txt b/.nuget/Cuemon.Data/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Data/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Data/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt b/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt index f51a821fa..0fcc64de1 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt index fcfe6c936..b74b0dd6c 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt index 0ffcff9b8..0e7a9569c 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt index f51a821fa..0fcc64de1 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt index 61894afa5..ee4cb0cc8 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt index 69b021a55..1c01acc4b 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt index 94702133e..072feb0e9 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt index c585a6399..27d7803ae 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10 and .NET 9 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10 and .NET 9   diff --git a/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt index 8ad2e3567..f4f2860ea 100644 --- a/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt index 9fa1f66d6..edf11189b 100644 --- a/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt index 418efc05a..0f4ba1bff 100644 --- a/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt index 0b442770a..a41fc4d5b 100644 --- a/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9, .NET Standard 2.1 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9, .NET Standard 2.1 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt index 6f726f4c9..6aea75c8b 100644 --- a/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt index 6a13da61f..d7997b406 100644 --- a/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt index 62d0e6973..602e0cca2 100644 --- a/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.IO/PackageReleaseNotes.txt b/.nuget/Cuemon.IO/PackageReleaseNotes.txt index cf32854f0..9d8ffa82e 100644 --- a/.nuget/Cuemon.IO/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.IO/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Net/PackageReleaseNotes.txt b/.nuget/Cuemon.Net/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Net/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Net/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt b/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt b/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt index 6ca36d8ed..2fac31787 100644 --- a/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt b/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt index cab0250b3..b8a289f55 100644 --- a/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Threading/PackageReleaseNotes.txt b/.nuget/Cuemon.Threading/PackageReleaseNotes.txt index 495b11908..78bbebdac 100644 --- a/.nuget/Cuemon.Threading/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Threading/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/.nuget/Cuemon.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Xml/PackageReleaseNotes.txt index 905bff1d3..a04b2f1f9 100644 --- a/.nuget/Cuemon.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.2.1 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 10.2.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0   diff --git a/CHANGELOG.md b/CHANGELOG.md index 08da81d72..0246c9fc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder. +## [10.2.1] - 2026-02-12 + +This is a service update that focuses on package dependencies; however, it also includes a small performance optimization to reduce allocations and improve throughput when working with streams. + +### Changed + +- `StreamDecoratorExtensions` class in the Cuemon.IO namespace to reduce memory allocations and improve throughput of InvokeToByteArray by eliminating redundant buffer copies for non-MemoryStream inputs (allocation ratio reduced from ~2x to ~1x for typical payload sizes) +- `StreamDecoratorExtensions` class in the Cuemon.IO namespace to cache Length access and avoid repeated virtual calls on seekable streams +- `StreamDecoratorExtensions` class in the Cuemon.IO namespace to return Array.Empty() for zero-length seekable streams to avoid unnecessary MemoryStream allocation + + ## [10.2.0] - 2026-02-09 This is a minor release that introduces support for UN M.49 statistical regions and countries. diff --git a/Directory.Packages.props b/Directory.Packages.props index 06cf8b3a4..f3d20ef04 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -22,31 +22,31 @@ - + - - - - - + + + + + - + - - - - - + + + + + - - - - - + + + + + diff --git a/reports/tuning/Cuemon.IO.StreamDecoratorExtensionsBenchmark-report-github.md b/reports/tuning/Cuemon.IO.StreamDecoratorExtensionsBenchmark-report-github.md new file mode 100644 index 000000000..bd460fc48 --- /dev/null +++ b/reports/tuning/Cuemon.IO.StreamDecoratorExtensionsBenchmark-report-github.md @@ -0,0 +1,50 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.7840/25H2/2025Update/HudsonValley2) +12th Gen Intel Core i9-12900KF 3.20GHz, 1 CPU, 24 logical and 16 physical cores +.NET SDK 10.0.200-preview.0.26103.119 + [Host] : .NET 10.0.3 (10.0.3, 10.0.326.7603), X64 RyuJIT x86-64-v3 + Job-LDLMHG : .NET 10.0.3 (10.0.3, 10.0.326.7603), X64 RyuJIT x86-64-v3 + Job-IOAYXE : .NET 9.0.13 (9.0.13, 9.0.1326.6317), X64 RyuJIT x86-64-v3 + +PowerPlanMode=00000000-0000-0000-0000-000000000000 IterationTime=250ms MaxIterationCount=20 +MinIterationCount=15 WarmupCount=1 + +``` +| Method | Runtime | Count | Mean | Error | StdDev | Median | Min | Max | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|------------------------------------- |---------- |------ |------------:|-----------:|-----------:|------------:|------------:|------------:|------:|--------:|-------:|-------:|----------:|------------:| +| **'CopyStream (changePosition=true)'** | **.NET 10.0** | **256** | **70.56 ns** | **19.563 ns** | **22.529 ns** | **74.00 ns** | **29.17 ns** | **99.49 ns** | **1.12** | **0.57** | **0.0259** | **-** | **408 B** | **1.00** | +| 'CopyStream (changePosition=false)' | .NET 10.0 | 256 | 48.59 ns | 5.681 ns | 6.542 ns | 49.07 ns | 24.94 ns | 57.00 ns | 0.77 | 0.31 | 0.0259 | - | 408 B | 1.00 | +| | | | | | | | | | | | | | | | +| 'CopyStream (changePosition=true)' | .NET 9.0 | 256 | 54.17 ns | 6.250 ns | 7.197 ns | 55.64 ns | 33.46 ns | 63.79 ns | 1.02 | 0.23 | 0.0260 | - | 408 B | 1.00 | +| 'CopyStream (changePosition=false)' | .NET 9.0 | 256 | 54.97 ns | 2.748 ns | 3.165 ns | 54.89 ns | 48.28 ns | 61.78 ns | 1.04 | 0.19 | 0.0260 | - | 408 B | 1.00 | +| | | | | | | | | | | | | | | | +| **'CopyStream (changePosition=true)'** | **.NET 10.0** | **4096** | **311.85 ns** | **52.996 ns** | **58.905 ns** | **332.68 ns** | **147.71 ns** | **354.11 ns** | **1.06** | **0.40** | **0.2706** | **0.0041** | **4248 B** | **1.00** | +| 'CopyStream (changePosition=false)' | .NET 10.0 | 4096 | 327.24 ns | 40.391 ns | 43.218 ns | 337.80 ns | 171.19 ns | 370.11 ns | 1.11 | 0.39 | 0.2706 | 0.0041 | 4248 B | 1.00 | +| | | | | | | | | | | | | | | | +| 'CopyStream (changePosition=true)' | .NET 9.0 | 4096 | 375.06 ns | 16.791 ns | 19.337 ns | 379.24 ns | 336.36 ns | 407.30 ns | 1.00 | 0.07 | 0.2707 | 0.0041 | 4248 B | 1.00 | +| 'CopyStream (changePosition=false)' | .NET 9.0 | 4096 | 299.68 ns | 79.786 ns | 91.881 ns | 341.66 ns | 154.84 ns | 409.62 ns | 0.80 | 0.24 | 0.2705 | 0.0037 | 4248 B | 1.00 | +| | | | | | | | | | | | | | | | +| **'CopyStream (changePosition=true)'** | **.NET 10.0** | **65536** | **5,870.30 ns** | **858.025 ns** | **953.692 ns** | **6,142.83 ns** | **3,289.88 ns** | **7,048.91 ns** | **1.04** | **0.29** | **4.1638** | **0.8285** | **65688 B** | **1.00** | +| 'CopyStream (changePosition=false)' | .NET 10.0 | 65536 | 4,998.91 ns | 839.566 ns | 966.846 ns | 5,327.16 ns | 2,805.62 ns | 6,099.40 ns | 0.88 | 0.26 | 4.1641 | 0.8198 | 65688 B | 1.00 | +| | | | | | | | | | | | | | | | +| 'CopyStream (changePosition=true)' | .NET 9.0 | 65536 | 5,023.54 ns | 777.246 ns | 895.078 ns | 5,215.58 ns | 2,821.88 ns | 6,140.23 ns | 1.04 | 0.30 | 4.1554 | 0.8243 | 65688 B | 1.00 | +| 'CopyStream (changePosition=false)' | .NET 9.0 | 65536 | 4,998.30 ns | 541.256 ns | 623.311 ns | 5,091.74 ns | 2,789.15 ns | 5,666.28 ns | 1.03 | 0.26 | 4.1587 | 0.8209 | 65688 B | 1.00 | +| | | | | | | | | | | | | | | | +| **'InvokeToByteArray (MemoryStream)'** | **.NET 10.0** | **256** | **34.79 ns** | **4.475 ns** | **4.974 ns** | **35.70 ns** | **14.61 ns** | **37.62 ns** | **1.04** | **0.35** | **0.0219** | **-** | **344 B** | **1.00** | +| 'InvokeToByteArray (BufferedStream)' | .NET 10.0 | 256 | 73.07 ns | 14.378 ns | 16.557 ns | 79.54 ns | 37.82 ns | 84.94 ns | 2.19 | 0.84 | 0.0301 | - | 472 B | 1.37 | +| | | | | | | | | | | | | | | | +| 'InvokeToByteArray (MemoryStream)' | .NET 9.0 | 256 | 39.04 ns | 3.740 ns | 4.001 ns | 39.69 ns | 24.52 ns | 43.05 ns | 1.01 | 0.18 | 0.0239 | - | 376 B | 1.00 | +| 'InvokeToByteArray (BufferedStream)' | .NET 9.0 | 256 | 87.96 ns | 16.035 ns | 18.466 ns | 95.27 ns | 43.67 ns | 102.16 ns | 2.29 | 0.58 | 0.0320 | - | 504 B | 1.34 | +| | | | | | | | | | | | | | | | +| **'InvokeToByteArray (MemoryStream)'** | **.NET 10.0** | **4096** | **322.25 ns** | **66.218 ns** | **73.602 ns** | **354.52 ns** | **152.79 ns** | **363.42 ns** | **1.09** | **0.49** | **0.2668** | **-** | **4184 B** | **1.00** | +| 'InvokeToByteArray (BufferedStream)' | .NET 10.0 | 4096 | 297.18 ns | 94.936 ns | 109.328 ns | 311.07 ns | 158.72 ns | 468.64 ns | 1.01 | 0.54 | 0.2746 | 0.0038 | 4312 B | 1.03 | +| | | | | | | | | | | | | | | | +| 'InvokeToByteArray (MemoryStream)' | .NET 9.0 | 4096 | 159.67 ns | 4.739 ns | 5.457 ns | 160.28 ns | 150.51 ns | 171.16 ns | 1.00 | 0.05 | 0.2685 | - | 4216 B | 1.00 | +| 'InvokeToByteArray (BufferedStream)' | .NET 9.0 | 4096 | 171.81 ns | 5.168 ns | 5.745 ns | 169.39 ns | 164.60 ns | 182.14 ns | 1.08 | 0.05 | 0.2769 | 0.0042 | 4344 B | 1.03 | +| | | | | | | | | | | | | | | | +| **'InvokeToByteArray (MemoryStream)'** | **.NET 10.0** | **65536** | **2,157.83 ns** | **85.576 ns** | **95.117 ns** | **2,143.63 ns** | **2,037.13 ns** | **2,342.61 ns** | **1.00** | **0.06** | **4.1645** | **-** | **65624 B** | **1.00** | +| 'InvokeToByteArray (BufferedStream)' | .NET 10.0 | 65536 | 2,817.96 ns | 123.719 ns | 137.513 ns | 2,783.18 ns | 2,640.20 ns | 3,114.92 ns | 1.31 | 0.08 | 4.1821 | 0.8276 | 65752 B | 1.00 | +| | | | | | | | | | | | | | | | +| 'InvokeToByteArray (MemoryStream)' | .NET 9.0 | 65536 | 2,064.38 ns | 140.796 ns | 150.650 ns | 2,006.75 ns | 1,902.78 ns | 2,439.56 ns | 1.00 | 0.10 | 4.1599 | - | 65656 B | 1.00 | +| 'InvokeToByteArray (BufferedStream)' | .NET 9.0 | 65536 | 2,787.27 ns | 62.413 ns | 66.781 ns | 2,808.76 ns | 2,670.49 ns | 2,905.25 ns | 1.36 | 0.10 | 4.1763 | 0.8308 | 65784 B | 1.00 | diff --git a/src/Cuemon.Core/Extensions/IO/StreamDecoratorExtensions.cs b/src/Cuemon.Core/Extensions/IO/StreamDecoratorExtensions.cs index 293eb9cd5..bfd217a4c 100644 --- a/src/Cuemon.Core/Extensions/IO/StreamDecoratorExtensions.cs +++ b/src/Cuemon.Core/Extensions/IO/StreamDecoratorExtensions.cs @@ -26,16 +26,17 @@ public static void CopyStream(this IDecorator decorator, Stream destinat Validator.ThrowIfNull(decorator); var source = decorator.Inner; long lastPosition = 0; - if (changePosition && source.CanSeek) + var canSeekSource = source.CanSeek; + if (changePosition && canSeekSource) { lastPosition = source.Position; - if (source.CanSeek) { source.Position = 0; } + source.Position = 0; } source.CopyTo(destination, bufferSize); destination.Flush(); - if (changePosition && source.CanSeek) { source.Position = lastPosition; } + if (changePosition && canSeekSource) { source.Position = lastPosition; } if (changePosition && destination.CanSeek) { destination.Position = 0; } } @@ -59,18 +60,41 @@ public static byte[] InvokeToByteArray(this IDecorator decorator, int bu return s.ToArray(); } - using (var memoryStream = new MemoryStream(new byte[decorator.Inner.Length])) + var source = decorator.Inner; + var canSeek = source.CanSeek; + var oldPosition = 0L; + + if (canSeek) + { + oldPosition = source.Position; + source.Position = 0; + } + + var length = canSeek ? source.Length : 0L; + + if (canSeek && length == 0) + { + source.Position = oldPosition; + return Array.Empty(); + } + + var memoryStream = length > 0 && length <= int.MaxValue + ? new MemoryStream((int)length) + : new MemoryStream(); + + using (memoryStream) { - var oldPosition = decorator.Inner.Position; - if (decorator.Inner.CanSeek) + source.CopyTo(memoryStream, bufferSize); + if (canSeek) { - decorator.Inner.Position = 0; + source.Position = oldPosition; } - decorator.Inner.CopyTo(memoryStream, bufferSize); - if (decorator.Inner.CanSeek) + if (memoryStream.TryGetBuffer(out var segment) && + segment.Offset == 0 && + segment.Count == segment.Array.Length) { - decorator.Inner.Position = oldPosition; + return segment.Array; } return memoryStream.ToArray(); @@ -85,4 +109,4 @@ public static byte[] InvokeToByteArray(this IDecorator decorator, int bu } } } -} \ No newline at end of file +} diff --git a/src/Cuemon.Core/Globalization/UnM49DataContainer.cs b/src/Cuemon.Core/Globalization/UnM49DataContainer.cs index 302843638..9daef7c16 100644 --- a/src/Cuemon.Core/Globalization/UnM49DataContainer.cs +++ b/src/Cuemon.Core/Globalization/UnM49DataContainer.cs @@ -29,14 +29,8 @@ internal UnM49DataContainer() var regions = new List(); var countries = new List(); - using (var stream = Decorator.Enclose(typeof(StatisticalRegionInfo).Assembly).GetManifestResources(resourceName) - .Single().Value) + using (var stream = Decorator.Enclose(typeof(StatisticalRegionInfo).Assembly).GetManifestResources(resourceName).Single().Value) { - if (stream == null) - { - throw new InvalidOperationException($"Embedded resource '{resourceName}' not found."); - } - using (var reader = new StreamReader(stream)) { // Skip header line diff --git a/test/Cuemon.Core.Tests/Cuemon.Core.Tests.csproj b/test/Cuemon.Core.Tests/Cuemon.Core.Tests.csproj index 874f5e619..ac0aa6943 100644 --- a/test/Cuemon.Core.Tests/Cuemon.Core.Tests.csproj +++ b/test/Cuemon.Core.Tests/Cuemon.Core.Tests.csproj @@ -29,7 +29,6 @@ - diff --git a/test/Cuemon.Core.Tests/Extensions/IO/StreamDecoratorExtensionsTest.cs b/test/Cuemon.Core.Tests/Extensions/IO/StreamDecoratorExtensionsTest.cs new file mode 100644 index 000000000..807409064 --- /dev/null +++ b/test/Cuemon.Core.Tests/Extensions/IO/StreamDecoratorExtensionsTest.cs @@ -0,0 +1,195 @@ +using System; +using System.IO; +using Codebelt.Extensions.Xunit; +using Xunit; + +namespace Cuemon.IO +{ + /// + /// Tests for the class. + /// + public class StreamDecoratorExtensionsTest : Test + { + public StreamDecoratorExtensionsTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void CopyStream_ShouldThrowArgumentNullException_WhenDecoratorIsNull() + { + IDecorator decorator = null; + Assert.Throws(() => decorator.CopyStream(Stream.Null)); + } + + [Fact] + public void CopyStream_ShouldCopyContentToDestination() + { + var data = "Hello, World!"u8.ToArray(); + using var source = new MemoryStream(data); + using var destination = new MemoryStream(); + + Decorator.Enclose(source).CopyStream(destination); + + Assert.Equal(data.Length, destination.Length); + Assert.Equal(data, destination.ToArray()); + } + + [Fact] + public void CopyStream_ShouldResetSourcePositionAfterCopy_WhenChangePositionIsTrue() + { + var data = "Some test data"u8.ToArray(); + using var source = new MemoryStream(data); + source.Position = 5; + + using var destination = new MemoryStream(); + + Decorator.Enclose(source).CopyStream(destination, changePosition: true); + + Assert.Equal(5, source.Position); + Assert.Equal(0, destination.Position); + Assert.Equal(data.Length, destination.Length); + } + + [Fact] + public void CopyStream_ShouldNotResetSourcePosition_WhenChangePositionIsFalse() + { + var data = "Some test data"u8.ToArray(); + using var source = new MemoryStream(data); + source.Position = 5; + + using var destination = new MemoryStream(); + + Decorator.Enclose(source).CopyStream(destination, changePosition: false); + + Assert.Equal(data.Length, source.Position); + Assert.Equal(data.Length - 5, destination.Length); + } + + [Fact] + public void CopyStream_ShouldCopyEntireStream_WhenSourcePositionIsAtEnd() + { + var data = "End of stream"u8.ToArray(); + using var source = new MemoryStream(data); + source.Position = source.Length; + + using var destination = new MemoryStream(); + + Decorator.Enclose(source).CopyStream(destination, changePosition: true); + + Assert.Equal(data.Length, destination.Length); + Assert.Equal(data, destination.ToArray()); + } + + [Fact] + public void CopyStream_ShouldSetDestinationPositionToZero_WhenChangePositionIsTrue() + { + var data = "Position test"u8.ToArray(); + using var source = new MemoryStream(data); + using var destination = new MemoryStream(); + + Decorator.Enclose(source).CopyStream(destination, changePosition: true); + + Assert.Equal(0, destination.Position); + } + + [Fact] + public void CopyStream_ShouldRespectCustomBufferSize() + { + var data = "Buffer size test data with more content to exceed small buffer"u8.ToArray(); + using var source = new MemoryStream(data); + using var destination = new MemoryStream(); + + Decorator.Enclose(source).CopyStream(destination, bufferSize: 4); + + Assert.Equal(data.Length, destination.Length); + Assert.Equal(data, destination.ToArray()); + } + + [Fact] + public void InvokeToByteArray_ShouldThrowArgumentNullException_WhenDecoratorIsNull() + { + IDecorator decorator = null; + Assert.Throws(() => decorator.InvokeToByteArray()); + } + + [Fact] + public void InvokeToByteArray_ShouldConvertMemoryStreamToByteArray() + { + var data = "MemoryStream test"u8.ToArray(); + using var stream = new MemoryStream(data); + + var result = Decorator.Enclose(stream).InvokeToByteArray(leaveOpen: true); + + Assert.Equal(data, result); + } + + [Fact] + public void InvokeToByteArray_ShouldDisposeStream_WhenLeaveOpenIsFalse() + { + var data = "Dispose test"u8.ToArray(); + var stream = new MemoryStream(data); + + Decorator.Enclose(stream).InvokeToByteArray(leaveOpen: false); + + Assert.Throws(() => stream.ReadByte()); + } + + [Fact] + public void InvokeToByteArray_ShouldNotDisposeStream_WhenLeaveOpenIsTrue() + { + var data = "Leave open test"u8.ToArray(); + using var stream = new MemoryStream(data); + + Decorator.Enclose(stream).InvokeToByteArray(leaveOpen: true); + + stream.Position = 0; + Assert.Equal(data[0], stream.ReadByte()); + } + + [Fact] + public void InvokeToByteArray_ShouldConvertNonMemoryStreamToByteArray() + { + var data = "Non-MemoryStream data"u8.ToArray(); + using var fileStream = new BufferedStream(new MemoryStream(data)); + + var result = Decorator.Enclose(fileStream).InvokeToByteArray(leaveOpen: true); + + Assert.Equal(data, result); + } + + [Fact] + public void InvokeToByteArray_ShouldPreservePosition_ForNonMemoryStream() + { + var data = "Position preservation test"u8.ToArray(); + using var inner = new MemoryStream(data); + using var stream = new BufferedStream(inner); + stream.Position = 5; + + var result = Decorator.Enclose(stream).InvokeToByteArray(leaveOpen: true); + + Assert.Equal(5, stream.Position); + Assert.Equal(data, result); + } + + [Fact] + public void InvokeToByteArray_ShouldHandleEmptyStream() + { + using var stream = new MemoryStream(); + + var result = Decorator.Enclose(stream).InvokeToByteArray(leaveOpen: true); + + Assert.Empty(result); + } + + [Fact] + public void InvokeToByteArray_ShouldRespectCustomBufferSize() + { + var data = "Buffer size test with enough data"u8.ToArray(); + using var stream = new BufferedStream(new MemoryStream(data)); + + var result = Decorator.Enclose(stream).InvokeToByteArray(bufferSize: 8, leaveOpen: true); + + Assert.Equal(data, result); + } + } +} diff --git a/testenvironments.json b/testenvironments.json index 8691403f1..325127a3a 100644 --- a/testenvironments.json +++ b/testenvironments.json @@ -9,7 +9,7 @@ { "name": "Docker-Ubuntu", "type": "docker", - "dockerImage": "gimlichael/ubuntu-testrunner:net8.0.417-9.0.309-10.0.102" + "dockerImage": "codebeltnet/ubuntu-testrunner:net8.0.418-9.0.311-10.0.103" } ] } diff --git a/tuning/Cuemon.Core.Benchmarks/Extensions/IO/StreamDecoratorExtensionsBenchmark.cs b/tuning/Cuemon.Core.Benchmarks/Extensions/IO/StreamDecoratorExtensionsBenchmark.cs new file mode 100644 index 000000000..28582526b --- /dev/null +++ b/tuning/Cuemon.Core.Benchmarks/Extensions/IO/StreamDecoratorExtensionsBenchmark.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; + +namespace Cuemon.IO +{ + [MemoryDiagnoser] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + public class StreamDecoratorExtensionsBenchmark + { + [Params(256, 4096, 65536)] + public int Count { get; set; } + + private byte[] _payload; + + [GlobalSetup] + public void Setup() + { + var random = new Random(1337); + _payload = new byte[Count]; + random.NextBytes(_payload); + } + + [Benchmark(Baseline = true, Description = "CopyStream (changePosition=true)")] + [BenchmarkCategory("CopyStream")] + public int CopyStream_ChangePositionTrue() + { + using (var source = new MemoryStream(_payload, writable: false)) + using (var destination = new MemoryStream(_payload.Length)) + { + Decorator.Enclose(source).CopyStream(destination, bufferSize: 81920, changePosition: true); + return (int)destination.Length; + } + } + + [Benchmark(Description = "CopyStream (changePosition=false)")] + [BenchmarkCategory("CopyStream")] + public int CopyStream_ChangePositionFalse() + { + using (var source = new MemoryStream(_payload, writable: false)) + using (var destination = new MemoryStream(_payload.Length)) + { + Decorator.Enclose(source).CopyStream(destination, bufferSize: 81920, changePosition: false); + return (int)destination.Length; + } + } + + [Benchmark(Baseline = true, Description = "InvokeToByteArray (MemoryStream)")] + [BenchmarkCategory("InvokeToByteArray")] + public int InvokeToByteArray_MemoryStream() + { + using (var source = new MemoryStream(_payload, writable: false)) + { + var result = Decorator.Enclose(source).InvokeToByteArray(bufferSize: 81920, leaveOpen: true); + return result.Length; + } + } + + [Benchmark(Description = "InvokeToByteArray (BufferedStream)")] + [BenchmarkCategory("InvokeToByteArray")] + public int InvokeToByteArray_BufferedStream() + { + using (var memory = new MemoryStream(_payload, writable: false)) + using (var source = new BufferedStream(memory, bufferSize: 16384)) + { + var result = Decorator.Enclose(source).InvokeToByteArray(bufferSize: 81920, leaveOpen: true); + return result.Length; + } + } + } +}