// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.IO; using osu.Framework.Extensions; using osu.Game.IO.Archives; using osu.Game.Utils; using SharpCompress.Common; namespace osu.Game.Database { /// /// An encapsulated import task to be imported to an . /// public class ImportTask { /// /// The path to the file (or filename in the case a stream is provided). /// public string Path { get; } /// /// An optional stream which provides the file content. /// public Stream? Stream { get; } /// /// Construct a new import task from a path (on a local filesystem). /// public ImportTask(string path) { Path = path; } /// /// Construct a new import task from a stream. The provided stream will be disposed after reading. /// public ImportTask(Stream stream, string filename) { Path = filename; Stream = stream; } /// /// Retrieve an archive reader from this task. /// public ArchiveReader GetReader() { return Stream != null ? getReaderFrom(Stream) : getReaderFrom(Path); } /// /// Deletes the file that is encapsulated by this . /// public virtual void DeleteFile() { if (File.Exists(Path)) File.Delete(Path); } /// /// Creates an from a stream. /// /// A seekable stream containing the archive content. /// A reader giving access to the archive's content. private ArchiveReader getReaderFrom(Stream stream) { if (!(stream is MemoryStream memoryStream)) { // This isn't used in any current path. May need to reconsider for performance reasons (ie. if we don't expect the incoming stream to be copied out). memoryStream = new MemoryStream(stream.ReadAllBytesToArray()); stream.Dispose(); } if (ZipUtils.IsZipArchive(memoryStream)) return new ZipArchiveReader(memoryStream, Path); return new LegacyByteArrayReader(memoryStream.ToArray(), Path); } /// /// Creates an from a valid storage path. /// /// A file or folder path resolving the archive content. /// A reader giving access to the archive's content. private ArchiveReader getReaderFrom(string path) { if (ZipUtils.IsZipArchive(path)) return new ZipArchiveReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read), System.IO.Path.GetFileName(path)); if (Directory.Exists(path)) return new LegacyDirectoryArchiveReader(path); if (File.Exists(path)) return new LegacyFileArchiveReader(path); throw new InvalidFormatException($"{path} is not a valid archive"); } public override string ToString() => System.IO.Path.GetFileName(Path); } }