2020-12-07 17:00:45 +08:00
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
|
|
|
|
using System.IO;
|
2022-02-11 15:02:25 +08:00
|
|
|
using osu.Framework.Extensions;
|
2020-12-07 17:00:45 +08:00
|
|
|
using osu.Game.IO.Archives;
|
|
|
|
using osu.Game.Utils;
|
|
|
|
using SharpCompress.Common;
|
|
|
|
|
|
|
|
namespace osu.Game.Database
|
|
|
|
{
|
|
|
|
/// <summary>
|
2022-06-16 17:53:13 +08:00
|
|
|
/// An encapsulated import task to be imported to an <see cref="RealmArchiveModelImporter{TModel}"/>.
|
2020-12-07 17:00:45 +08:00
|
|
|
/// </summary>
|
|
|
|
public class ImportTask
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// The path to the file (or filename in the case a stream is provided).
|
|
|
|
/// </summary>
|
|
|
|
public string Path { get; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// An optional stream which provides the file content.
|
|
|
|
/// </summary>
|
2020-12-08 11:52:34 +08:00
|
|
|
public Stream? Stream { get; }
|
2020-12-07 17:00:45 +08:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Construct a new import task from a path (on a local filesystem).
|
|
|
|
/// </summary>
|
|
|
|
public ImportTask(string path)
|
|
|
|
{
|
|
|
|
Path = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2022-06-20 14:38:44 +08:00
|
|
|
/// Construct a new import task from a stream. The provided stream will be disposed after reading.
|
2020-12-07 17:00:45 +08:00
|
|
|
/// </summary>
|
|
|
|
public ImportTask(Stream stream, string filename)
|
|
|
|
{
|
|
|
|
Path = filename;
|
|
|
|
Stream = stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieve an archive reader from this task.
|
|
|
|
/// </summary>
|
|
|
|
public ArchiveReader GetReader()
|
|
|
|
{
|
2021-11-12 15:39:17 +08:00
|
|
|
return Stream != null
|
|
|
|
? getReaderFrom(Stream)
|
|
|
|
: getReaderFrom(Path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Creates an <see cref="ArchiveReader"/> from a stream.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="stream">A seekable stream containing the archive content.</param>
|
|
|
|
/// <returns>A reader giving access to the archive's content.</returns>
|
|
|
|
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).
|
2022-02-11 15:02:25 +08:00
|
|
|
memoryStream = new MemoryStream(stream.ReadAllBytesToArray());
|
2022-06-20 14:29:56 +08:00
|
|
|
stream.Dispose();
|
2021-11-12 15:39:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ZipUtils.IsZipArchive(memoryStream))
|
|
|
|
return new ZipArchiveReader(memoryStream, Path);
|
2020-12-07 17:00:45 +08:00
|
|
|
|
2021-11-12 15:39:17 +08:00
|
|
|
return new LegacyByteArrayReader(memoryStream.ToArray(), Path);
|
2020-12-07 17:00:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Creates an <see cref="ArchiveReader"/> from a valid storage path.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="path">A file or folder path resolving the archive content.</param>
|
|
|
|
/// <returns>A reader giving access to the archive's content.</returns>
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|