Skip to content

Commit accb60f

Browse files
committed
Remove CopyToAsync from IImageStream
1 parent abbcaa3 commit accb60f

11 files changed

Lines changed: 64 additions & 83 deletions

File tree

src/Platforms/SecureFolderFS.Maui/AppModels/ImageStream.cs

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using SecureFolderFS.Shared.ComponentModel;
2+
using SecureFolderFS.Storage.Streams;
3+
4+
namespace SecureFolderFS.Maui.AppModels
5+
{
6+
/// <inheritdoc cref="IImageStream"/>
7+
internal sealed class ImageStreamSource : IImageStream
8+
{
9+
/// <summary>
10+
/// Gets the streamed image source.
11+
/// </summary>
12+
public StreamImageSource Source { get; }
13+
14+
/// <inheritdoc/>
15+
public Stream Inner { get; }
16+
17+
public ImageStreamSource(Stream inner)
18+
{
19+
Inner = inner;
20+
Source = new();
21+
Source.Stream = _ => Task.FromResult(inner);
22+
}
23+
24+
/// <inheritdoc/>
25+
public void Dispose()
26+
{
27+
if (Inner is NonDisposableStream nonDisposableStream)
28+
nonDisposableStream.ForceClose();
29+
else
30+
Inner.Dispose();
31+
}
32+
}
33+
}

src/Platforms/SecureFolderFS.Maui/Platforms/Android/ServiceImplementation/AndroidMediaService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ public override async Task<IImageStream> GenerateThumbnailAsync(IFile file, Type
2828
await using var stream = await file.OpenReadAsync(cancellationToken).ConfigureAwait(false);
2929
var imageStream = await ThumbnailHelpers.GenerateImageThumbnailAsync(stream, Constants.Browser.IMAGE_THUMBNAIL_MAX_SIZE).ConfigureAwait(false);
3030

31-
return new ImageStream(imageStream);
31+
return new ImageStreamSource(imageStream);
3232
}
3333

3434
case TypeHint.Media:
3535
{
3636
await using var stream = await file.OpenReadAsync(cancellationToken).ConfigureAwait(false);
3737
var imageStream = await GenerateVideoThumbnailAsync(stream, TimeSpan.FromSeconds(0)).ConfigureAwait(false);
3838

39-
return new ImageStream(imageStream);
39+
return new ImageStreamSource(imageStream);
4040
}
4141

4242
default: throw new InvalidOperationException("The provided file type is invalid.");

src/Platforms/SecureFolderFS.Maui/Platforms/iOS/ServiceImplementation/IOSMediaService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private static async Task<IImageStream> GenerateImageThumbnailAsync(Stream strea
7777
await jpegData.AsStream().CopyToAsync(memoryStream).ConfigureAwait(false);
7878
memoryStream.Position = 0L;
7979

80-
return new ImageStream(new NonDisposableStream(memoryStream));
80+
return new ImageStreamSource(new NonDisposableStream(memoryStream));
8181
}
8282

8383
private static async Task<IImageStream> GenerateVideoThumbnailAsync(Stream stream, string extension, TimeSpan captureTime)
@@ -132,7 +132,7 @@ private static async Task<IImageStream> GenerateVideoThumbnailAsync(Stream strea
132132
await jpegData.AsStream().CopyToAsync(memoryStream).ConfigureAwait(false);
133133
memoryStream.Position = 0L;
134134

135-
return new ImageStream(new NonDisposableStream(memoryStream));
135+
return new ImageStreamSource(new NonDisposableStream(memoryStream));
136136
}
137137
finally
138138
{

src/Platforms/SecureFolderFS.Maui/ServiceImplementation/BaseMauiMediaService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public virtual Task<IImage> GetImageFromUrlAsync(string url, CancellationToken c
5151
public virtual async Task<IImage> ReadImageFileAsync(IFile file, CancellationToken cancellationToken)
5252
{
5353
var stream = await file.OpenStreamAsync(FileAccess.Read, FileShare.Read, cancellationToken);
54-
return new ImageStream(stream);
54+
return new ImageStreamSource(stream);
5555
}
5656

5757
/// <inheritdoc/>

src/Platforms/SecureFolderFS.Maui/ValueConverters/FileIconConverter.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,24 @@ internal sealed class FileIconConverter : IValueConverter
4747
{
4848
switch (image)
4949
{
50-
case StreamImageModel { Stream.CanRead: true } streamImageModel:
50+
case StreamImageModel { Inner.CanRead: true } streamImageModel:
5151
{
52-
streamImageModel.Stream.TrySetPositionOrAdvance(0L);
52+
streamImageModel.Inner.TrySetPositionOrAdvance(0L);
5353
return new Image()
5454
{
5555
Source = new StreamImageSource()
5656
{
57-
Stream = _ => Task.FromResult(streamImageModel.Stream)
57+
Stream = _ => Task.FromResult(streamImageModel.Inner)
5858
},
5959
Aspect = Aspect.AspectFill,
6060
HorizontalOptions = LayoutOptions.Fill,
6161
VerticalOptions = LayoutOptions.Fill
6262
};
6363
}
6464

65-
case ImageStream { Stream.CanRead: true } imageStream:
65+
case ImageStreamSource { Inner.CanRead: true } imageStream:
6666
{
67-
imageStream.Stream.TrySetPositionOrAdvance(0L);
67+
imageStream.Inner.TrySetPositionOrAdvance(0L);
6868
return new Image()
6969
{
7070
Source = imageStream.Source,

src/Platforms/SecureFolderFS.Maui/ValueConverters/ImageToSourceConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal sealed class ImageToSourceConverter : IValueConverter
1414
{
1515
return value switch
1616
{
17-
ImageStream imageStream => imageStream.Source,
17+
ImageStreamSource imageStream => imageStream.Source,
1818
ImageIcon iconImage => new FontImageSource()
1919
{
2020
Glyph = GetDescription(iconImage.MauiIcon.Icon),

src/Platforms/SecureFolderFS.Uno/ValueConverters/ImageToSourceConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public sealed class ImageToSourceConverter : IValueConverter
1515
return value switch
1616
{
1717
ImageBitmap imageBitmap => imageBitmap.Source,
18-
StreamImageModel imageStream => StreamToImageSource(imageStream.Stream),
18+
StreamImageModel imageStream => StreamToImageSource(imageStream.Inner),
1919
ImageResource resourceImage => new BitmapImage(resourceImage.IsResource
2020
? new Uri($"ms-appx:///{resourceImage.Name}")
2121
: new Uri(resourceImage.Name)),

src/Sdk/SecureFolderFS.Sdk/AppModels/ThumbnailCacheModel.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public ThumbnailCacheModel(int maxEntries)
5656
if (cachedData is null || cachedData.Length == 0)
5757
return null;
5858

59-
return new MemoryStream(cachedData);
59+
return new MemoryStream(cachedData, writable: false);
6060
}
6161
catch
6262
{
@@ -77,9 +77,13 @@ public async Task CacheThumbnailAsync(string cacheKey, IImageStream thumbnailStr
7777
try
7878
{
7979
// Copy thumbnail to byte array
80-
using var memoryStream = new MemoryStream();
81-
await thumbnailStream.CopyToAsync(memoryStream, cancellationToken);
82-
var data = memoryStream.ToArray();
80+
var data = new byte[thumbnailStream.Inner.Length];
81+
var savedPosition = thumbnailStream.Inner.Position;
82+
thumbnailStream.Inner.Position = 0L;
83+
var read = await thumbnailStream.Inner.ReadAsync(data, cancellationToken);
84+
thumbnailStream.Inner.Position = savedPosition;
85+
if (read != data.Length)
86+
return;
8387

8488
await _database.SetValueAsync(cacheKey, data, cancellationToken);
8589
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using System.IO;
2-
using System.Threading;
3-
using System.Threading.Tasks;
42

53
namespace SecureFolderFS.Shared.ComponentModel
64
{
7-
public interface IImageStream : IImage
5+
/// <summary>
6+
/// Represents an image that can be read from a <see cref="Stream"/>.
7+
/// </summary>
8+
public interface IImageStream : IImage, IWrapper<Stream>
89
{
9-
Task CopyToAsync(Stream destination, CancellationToken cancellationToken = default);
1010
}
1111
}

0 commit comments

Comments
 (0)