diff --git a/src/Archive/ReadOnlyZipArchiveFolder.cs b/src/Archive/ReadOnlyZipArchiveFolder.cs index 6b67933..5debebe 100644 --- a/src/Archive/ReadOnlyZipArchiveFolder.cs +++ b/src/Archive/ReadOnlyZipArchiveFolder.cs @@ -89,21 +89,23 @@ internal ReadOnlyZipArchiveFolder(ZipArchive archive, string name, ReadOnlyZipAr /// public string Name { get; } - /// + /// + /// Gets the relative path from the root of the archive. + /// public string Path { get; } /// - /// A folder that represents the root of the archive. + /// Gets the folder that represents the root of the archive. /// public IFolder RootFolder { get; } /// - /// The file that this archive originated from. + /// Gets the file that this archive originated from. /// public IFile? SourceFile { get; } /// - /// The instance used to explore the archive. + /// Gets the instance used to explore the archive. /// public ZipArchive? Archive { get; protected set; } diff --git a/src/Extensions/CopyAndMoveExtensions.cs b/src/Extensions/CopyAndMoveExtensions.cs index bcb89b3..b163df9 100644 --- a/src/Extensions/CopyAndMoveExtensions.cs +++ b/src/Extensions/CopyAndMoveExtensions.cs @@ -15,7 +15,7 @@ public static partial class ModifiableFolderExtensions /// The folder where the copy is created. /// The file to be copied into this folder. /// true if the destination file can be overwritten; otherwise, false. - /// The cancellation token to observe. + /// A token that can be used to cancel the ongoing operation. public static async Task CreateCopyOfAsync(this IModifiableFolder destinationFolder, T fileToCopy, bool overwrite = default, CancellationToken cancellationToken = default) where T : IFile { @@ -68,7 +68,7 @@ public static async Task CreateCopyOfAsync(this IModifiableFolder /// The file being moved into this folder. /// The folder that is being moved from. /// true if the destination file can be overwritten; otherwise, false. - /// The cancellation token to observe. + /// A token that can be used to cancel the ongoing operation. public static async Task MoveFromAsync(this IModifiableFolder destinationFolder, T fileToMove, IModifiableFolder source, bool overwrite = default, CancellationToken cancellationToken = default) where T : IFile, IStorableChild { diff --git a/src/Extensions/IFastFileCopy.cs b/src/Extensions/IFastFileCopy.cs index 1b0da78..ce59c98 100644 --- a/src/Extensions/IFastFileCopy.cs +++ b/src/Extensions/IFastFileCopy.cs @@ -15,7 +15,8 @@ public interface IFastFileCopy : IModifiableFolder /// Creates a copy of the provided file within this folder. /// /// The file to be copied into this folder. - /// true if the destination file can be overwritten; otherwise, false. - /// The cancellation token to observe. - public Task CreateCopyOfAsync(T fileToCopy, bool overwrite = default, CancellationToken cancellationToken = default); + /// If there is an existing destination file, true will overwrite it; otherwise false and the existing file is opened. + /// A token that can be used to cancel the ongoing operation. + /// The newly created (or opened if existing) file. + Task CreateCopyOfAsync(T fileToCopy, bool overwrite = default, CancellationToken cancellationToken = default); } diff --git a/src/Extensions/IFastFileMove.cs b/src/Extensions/IFastFileMove.cs index b2a8c9b..e1d3b31 100644 --- a/src/Extensions/IFastFileMove.cs +++ b/src/Extensions/IFastFileMove.cs @@ -16,7 +16,8 @@ public interface IFastFileMove : IModifiableFolder /// /// The file being moved into this folder. /// The folder that is being moved from. - /// true if the destination file can be overwritten; otherwise, false. - /// The cancellation token to observe. - public Task MoveFromAsync(T fileToMove, IModifiableFolder source, bool overwrite = default, CancellationToken cancellationToken = default); + /// If there is an existing destination file, true will overwrite it; otherwise false and the existing file is opened. + /// A token that can be used to cancel the ongoing operation. + /// The newly created (or opened if existing) file. + Task MoveFromAsync(T fileToMove, IModifiableFolder source, bool overwrite = default, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/Extensions/IFastGetFirstItemByName.cs b/src/Extensions/IFastGetFirstItemByName.cs index 304f7d0..90b33ad 100644 --- a/src/Extensions/IFastGetFirstItemByName.cs +++ b/src/Extensions/IFastGetFirstItemByName.cs @@ -14,7 +14,7 @@ public interface IFastGetFirstByName : IFolder /// Retrieves the first item which has the provided . /// /// The of the storable item to retrieve. - /// The cancellation token to observe. - /// - public Task GetFirstByNameAsync(string name, CancellationToken cancellationToken = default); + /// A token that can be used to cancel the ongoing operation. + /// The first with the requested . + Task GetFirstByNameAsync(string name, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/Extensions/IFastGetItem.cs b/src/Extensions/IFastGetItem.cs index e5b63b2..5639df2 100644 --- a/src/Extensions/IFastGetItem.cs +++ b/src/Extensions/IFastGetItem.cs @@ -15,6 +15,6 @@ public interface IFastGetItem : IFolder /// /// The of the storable item to retrieve. /// The cancellation token to observe. - /// - public Task GetItemAsync(string id, CancellationToken cancellationToken = default); + /// An instance of with the requested . + Task GetItemAsync(string id, CancellationToken cancellationToken = default); } diff --git a/src/Extensions/IFastGetItemRecursive.cs b/src/Extensions/IFastGetItemRecursive.cs index dbf042f..1ecb332 100644 --- a/src/Extensions/IFastGetItemRecursive.cs +++ b/src/Extensions/IFastGetItemRecursive.cs @@ -15,6 +15,6 @@ public interface IFastGetItemRecursive : IFolder /// The of the item to crawl. /// A token to cancel the ongoing operation. /// A named item was specified in a folder, but the item wasn't found. - /// - public Task GetItemRecursiveAsync(string id, CancellationToken cancellationToken = default); + /// An instance of with the requested . + Task GetItemRecursiveAsync(string id, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/Extensions/IFastGetRoot.cs b/src/Extensions/IFastGetRoot.cs index 9ebd61e..c2b6d9a 100644 --- a/src/Extensions/IFastGetRoot.cs +++ b/src/Extensions/IFastGetRoot.cs @@ -10,6 +10,6 @@ public interface IFastGetRoot : IStorableChild /// /// Retrieves the root of this storable item. If this item IS the root, null will be returned instead. /// - /// The root of this storable item - public Task GetRootAsync(); + /// The root parent folder for this storage instance. if any. + Task GetRootAsync(); } diff --git a/src/HttpFile.cs b/src/HttpFile.cs index dc39b23..0c7c3f4 100644 --- a/src/HttpFile.cs +++ b/src/HttpFile.cs @@ -54,12 +54,12 @@ public HttpFile(string uri, HttpClient httpClient) } /// - /// The message handler to use for making HTTP requests. + /// Gets the message handler to use for making HTTP requests. /// public HttpClient Client { get; init; } /// - /// The http address to GET for the file content. + /// Gets the http address to GET for the file content. /// public Uri Uri { get; } diff --git a/src/IFile.cs b/src/IFile.cs index 50ab4e1..7973a91 100644 --- a/src/IFile.cs +++ b/src/IFile.cs @@ -5,12 +5,15 @@ namespace OwlCore.Storage; /// -/// The minimal functional requirements for a file. +/// The simplest possible representation of a file. /// public interface IFile : IStorable { /// - /// Opens a new stream to the file. + /// Opens a new stream to the resource. /// - public Task OpenStreamAsync(FileAccess accessMode = FileAccess.Read, CancellationToken cancellationToken = default); + /// A value that specifies the operations that can be performed on the file. + /// A token that can be used to cancel the ongoing operation. + /// A stream that provides access to this file, with the specified . + Task OpenStreamAsync(FileAccess accessMode = FileAccess.Read, CancellationToken cancellationToken = default); } diff --git a/src/IFolder.cs b/src/IFolder.cs index 87480b9..d11eb18 100644 --- a/src/IFolder.cs +++ b/src/IFolder.cs @@ -4,12 +4,15 @@ namespace OwlCore.Storage; /// -/// The minimal functional requirements for a folder. +/// The simplest possible representation of a folder. /// public interface IFolder : IStorable { /// /// Retrieves the folders in this directory. /// - public IAsyncEnumerable GetItemsAsync(StorableType type = StorableType.All, CancellationToken cancellationToken = default); + /// The type of items to retrieve. + /// A token that can be used to cancel the ongoing operation. + /// An async enumerable that yields the requested items. + IAsyncEnumerable GetItemsAsync(StorableType type = StorableType.All, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/IFolderWatcher.cs b/src/IFolderWatcher.cs index 216adea..926c940 100644 --- a/src/IFolderWatcher.cs +++ b/src/IFolderWatcher.cs @@ -9,7 +9,7 @@ namespace OwlCore.Storage; public interface IFolderWatcher : INotifyCollectionChanged, IDisposable, IAsyncDisposable { /// - /// The folder being watched for changes. + /// Gets the folder being watched for changes. /// - public IMutableFolder Folder { get; } + IMutableFolder Folder { get; } } \ No newline at end of file diff --git a/src/IModifiableFolder.cs b/src/IModifiableFolder.cs index be317df..230802d 100644 --- a/src/IModifiableFolder.cs +++ b/src/IModifiableFolder.cs @@ -13,23 +13,26 @@ public interface IModifiableFolder : IMutableFolder /// Deletes the provided storable item from this folder. /// /// The item to be removed from this folder. - /// The cancellation token to observe. + /// A token that can be used to cancel the ongoing operation. /// The item was not found in the provided folder. - public Task DeleteAsync(IStorableChild item, CancellationToken cancellationToken = default); + /// A that represents the asynchronous operation. + Task DeleteAsync(IStorableChild item, CancellationToken cancellationToken = default); /// /// Creates a new folder with the desired name inside this folder. /// /// The name of the new folder. /// true if the destination file can be overwritten; otherwise, false. - /// The cancellation token to observe. - public Task CreateFolderAsync(string name, bool overwrite = default, CancellationToken cancellationToken = default); + /// A token that can be used to cancel the ongoing operation. + /// The newly created (or opened if existing) folder. + Task CreateFolderAsync(string name, bool overwrite = default, CancellationToken cancellationToken = default); /// /// Creates a new file with the desired name inside this folder. /// /// The name of the new file. /// true if the destination file can be overwritten; otherwise, false. - /// The cancellation token to observe. - public Task CreateFileAsync(string name, bool overwrite = default, CancellationToken cancellationToken = default); + /// A token that can be used to cancel the ongoing operation. + /// The newly created (or opened if existing) file. + Task CreateFileAsync(string name, bool overwrite = default, CancellationToken cancellationToken = default); } diff --git a/src/IMutableFolder.cs b/src/IMutableFolder.cs index 4632555..61d8b06 100644 --- a/src/IMutableFolder.cs +++ b/src/IMutableFolder.cs @@ -11,6 +11,6 @@ public interface IMutableFolder : IFolder /// /// Asynchronously retrieves a disposable object which can notify of changes to the folder. /// - /// A Task representing the asynchronous operation. The result is a disposable object which can notify of changes to the folder. - public Task GetFolderWatcherAsync(CancellationToken cancellationToken = default); + /// A disposable object which can notify of changes to the folder. + Task GetFolderWatcherAsync(CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/IStorable.cs b/src/IStorable.cs index e644117..d72e41b 100644 --- a/src/IStorable.cs +++ b/src/IStorable.cs @@ -1,24 +1,26 @@ namespace OwlCore.Storage; /// -/// The absolute minimum requirements for all storable items. +/// Represents an item that can be stored or retrieved from a storage source. /// public interface IStorable { /// - /// A unique and consistent identifier for this file or folder. This dedicated resource identifier is used to identify the exact file you're pointing to. + /// Gets a unique identifier for this item that is consistent across reruns. /// /// - /// Uri paths, especially those from cloud storage, can change regularly (e.g. when re-authenticating), and some files/folders aren't even addressable, meaning paths can't be used as a reliable content identifier. - /// Also, custom and especially cloud file systems often use a predictable or custom ID as the primary-key in a flat or near-flat database table of files and folders. This also means that names aren't guaranteed to be unique within a folder. + /// Custom and (especially cloud) file systems often use a flat or near-flat database and a predictable or custom ID as the primary-key, which can be used as an Id. + /// Paths that are unique to the local file system can be used as an Id. + /// Uri-based resource paths that change (e.g. when re-authenticating) should not be used as an Id. + /// Names aren't guaranteed to be non-empty or unique within or across folders, and should not be used as an Id. /// /// - /// Instead, since the underlying implementation knows the requirements, it can supply what data it has as long as it uniquely and consistently identifies the content. + /// The implementation can use any string data available to produce this ID, so long as it identifies this specific resource across runs. /// - public string Id { get; } + string Id { get; } /// - /// The name of the file or folder, with the extension (if any). + /// Gets the name of the item, with the extension (if any). /// - public string Name { get; } + string Name { get; } } \ No newline at end of file diff --git a/src/IStorableChild.cs b/src/IStorableChild.cs index f175041..4464052 100644 --- a/src/IStorableChild.cs +++ b/src/IStorableChild.cs @@ -11,5 +11,7 @@ public interface IStorableChild : IStorable /// /// Gets the containing folder for this item, if any. /// - public Task GetParentAsync(CancellationToken cancellationToken = default); + /// A token that can be used to cancel the ongoing operation. + /// The containing parent folder, if any. + Task GetParentAsync(CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/IStorageProperty.cs b/src/IStorageProperty.cs index b79109f..bf6368d 100644 --- a/src/IStorageProperty.cs +++ b/src/IStorageProperty.cs @@ -14,10 +14,10 @@ public interface IStorageProperty : IDisposable /// /// Gets the current property value. /// - public T Value { get; } + T Value { get; } /// /// Raised when the is updated. /// - public event EventHandler ValueUpdated; + event EventHandler? ValueUpdated; } \ No newline at end of file diff --git a/src/Internal/LazySeekStream.cs b/src/Internal/LazySeekStream.cs index 1112765..545a12c 100644 --- a/src/Internal/LazySeekStream.cs +++ b/src/Internal/LazySeekStream.cs @@ -8,8 +8,8 @@ namespace OwlCore.Storage; /// internal class LazySeekStream : Stream { - private Stream _originalStream; - private MemoryStream _memoryStream; + private readonly Stream _originalStream; + private readonly MemoryStream _memoryStream; /// /// Creates a new instance of . diff --git a/src/Memory/MemoryFolder.cs b/src/Memory/MemoryFolder.cs index a09920d..f04bbce 100644 --- a/src/Memory/MemoryFolder.cs +++ b/src/Memory/MemoryFolder.cs @@ -35,7 +35,7 @@ public MemoryFolder(string id, string name) public string Name { get; } /// - /// The parent folder, if any. + /// Gets the parent folder, if any. /// public MemoryFolder? Parent { get; internal set; } diff --git a/src/OwlCore.Storage.csproj b/src/OwlCore.Storage.csproj index 4b9c89f..b686c1d 100644 --- a/src/OwlCore.Storage.csproj +++ b/src/OwlCore.Storage.csproj @@ -14,7 +14,7 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb Arlo Godfrey - 0.9.2 + 0.9.3 OwlCore The most flexible file system abstraction, ever. Built in partnership with the UWP Community. @@ -23,6 +23,11 @@ LICENSE.txt logo.png +--- 0.9.3 --- +[Improvements] +The DirectoryInfo for SystemFolder is now exposed as a public Info property. +General pass adding missing xmldoc comments to interfaces. + --- 0.9.2 --- [Improvements] The stream returned by HttpFile.OpenStreamAsync() now includes the value of the Content-Length header as the stream Length. diff --git a/src/StreamFile.cs b/src/StreamFile.cs index fe3e3ef..7ff32c9 100644 --- a/src/StreamFile.cs +++ b/src/StreamFile.cs @@ -12,7 +12,7 @@ namespace OwlCore.Storage; public class StreamFile : IFile { /// - /// The stream being accessed for this file. + /// Gets the stream being accessed for this file. /// public Stream Stream { get; } diff --git a/src/SystemIO/SystemFile.cs b/src/SystemIO/SystemFile.cs index 95d982d..f58b4ab 100644 --- a/src/SystemIO/SystemFile.cs +++ b/src/SystemIO/SystemFile.cs @@ -47,11 +47,13 @@ public SystemFile(FileInfo info) /// public string Name => _name ??= System.IO.Path.GetFileName(Path); - /// + /// + /// Gets the path of the file on disk. + /// public string Path { get; } /// - /// The file info for the . + /// Gets the underlying for this folder. /// public FileInfo Info => _info ??= new(Path); diff --git a/src/SystemIO/SystemFolder.cs b/src/SystemIO/SystemFolder.cs index d32ec9a..4717eb0 100644 --- a/src/SystemIO/SystemFolder.cs +++ b/src/SystemIO/SystemFolder.cs @@ -1,5 +1,4 @@ -using OwlCore.Storage.Memory; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; @@ -15,7 +14,7 @@ namespace OwlCore.Storage.SystemIO; /// public class SystemFolder : IModifiableFolder, IChildFolder, IFastFileCopy, IFastFileMove, IFastGetItem, IFastGetItemRecursive, IFastGetFirstByName, IFastGetRoot { - private readonly DirectoryInfo _directoryInfo; + private DirectoryInfo? _info; /// /// Creates a new instance of . @@ -29,13 +28,13 @@ public SystemFolder(string path) /// /// Creates a new instance of . /// - /// The directory to use. - public SystemFolder(DirectoryInfo directoryInfo) + /// The directory to use. + public SystemFolder(DirectoryInfo info) { - _directoryInfo = directoryInfo; + _info = info; // For consistency, always remove the trailing directory separator. - Path = directoryInfo.FullName.TrimEnd(System.IO.Path.PathSeparator, System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); + Path = info.FullName.TrimEnd(System.IO.Path.PathSeparator, System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); if (!Directory.Exists(Path)) throw new FileNotFoundException($"Directory not found at path {Path}"); @@ -44,13 +43,20 @@ public SystemFolder(DirectoryInfo directoryInfo) Name = System.IO.Path.GetFileName(Path) ?? throw new ArgumentException($"Could not determine directory name from path {Path}"); } + /// + /// Gets the underlying for this folder. + /// + public DirectoryInfo Info => _info ??= new DirectoryInfo(Path); + /// public string Id { get; } /// public string Name { get; } - /// + /// + /// Gets the path of the folder on disk. + /// public string Path { get; } /// @@ -259,7 +265,7 @@ public Task CreateFileAsync(string name, bool overwrite = false, Can /// public Task GetRootAsync() { - return Task.FromResult(new SystemFolder(_directoryInfo.Root)); + return Task.FromResult(new SystemFolder(Info.Root)); } private static bool IsFile(string path) => System.IO.Path.GetFileName(path) is { } str && str != string.Empty && File.Exists(path);