Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using PG.StarWarsGame.Files.MEG.Binary.Metadata.V1;
using PG.StarWarsGame.Files.MEG.Binary.V1;
using PG.StarWarsGame.Files.MEG.Data;
using PG.StarWarsGame.Files.MEG.Files;
using Xunit;

namespace PG.StarWarsGame.Files.MEG.Test.Binary.Construction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using PG.StarWarsGame.Files.MEG.Binary.Size;
using PG.StarWarsGame.Files.MEG.Binary.V1;
using PG.StarWarsGame.Files.MEG.Data;
using PG.StarWarsGame.Files.MEG.Files;
using Xunit;

namespace PG.StarWarsGame.Files.MEG.Test.Binary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using PG.StarWarsGame.Files.Binary;
using PG.StarWarsGame.Files.MEG.Binary;
using PG.StarWarsGame.Files.MEG.Data;
using PG.StarWarsGame.Files.MEG.Files;
using System;
using System.IO;
using System.IO.Abstractions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using PG.Commons.Hashing;
using PG.StarWarsGame.Files.MEG.Data;
using PG.StarWarsGame.Files.MEG.Data.Archives;
using PG.StarWarsGame.Files.MEG.Data.Entries;
using PG.StarWarsGame.Files.MEG.Data.EntryLocations;
using PG.StarWarsGame.Files.MEG.Files;
using PG.StarWarsGame.Files.MEG.Services;
using Xunit;

namespace PG.StarWarsGame.Files.MEG.Test.Data.Entries;

Expand Down Expand Up @@ -38,8 +42,40 @@ protected override MegDataEntryLocationReference CreateLocation(int seed)
{
unchecked
{
return new MegDataEntryLocationReference(_megFile,
return new MegDataEntryLocationReference(_megFile,
MegDataEntryTest.CreateEntry("path", DefaultCrc, (uint)seed, (uint)seed));
}
}

[Fact]
public void GetData_ReturnsReferencedEntryContent()
{
var source = ServiceProvider.GetRequiredService<IMegService>().LoadArchive(MegTestConstants.ContentMegFileV1);

var reference = new MegDataEntryReference(new MegDataEntryLocationReference(source, source.Archive[0]));

using var stream = reference.GetData();
Assert.Equal(MegTestConstants.CampaignFilesContent, ReadAllBytes(stream));
}

[Fact]
public void GetData_EntryNotInSource_Throws()
{
var source = ServiceProvider.GetRequiredService<IMegService>().LoadArchive(MegTestConstants.ContentMegFileV1);

var reference = new MegDataEntryReference(
new MegDataEntryLocationReference(source, MegDataEntryTest.CreateEntry("not/in/archive.xml")));

Assert.Throws<EntryNotInMegException>(reference.GetData);
}

private static byte[] ReadAllBytes(Stream stream)
{
using (stream)
{
using var ms = new MemoryStream();
stream.CopyTo(ms);
return ms.ToArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using PG.StarWarsGame.Files.MEG.Data;
using PG.StarWarsGame.Files.MEG.Data.Archives;
using PG.StarWarsGame.Files.MEG.Data.EntryLocations;
using PG.StarWarsGame.Files.MEG.Files;
using PG.StarWarsGame.Files.MEG.Services;
using PG.StarWarsGame.Files.MEG.Test.Data.Entries;
using Xunit;

Expand Down Expand Up @@ -86,4 +89,36 @@ public void Exists()
Assert.True(locationExists.Exists);
Assert.False(locationNotExists.Exists);
}

[Fact]
public void GetData_ReturnsReferencedEntryContent()
{
var source = ServiceProvider.GetRequiredService<IMegService>().LoadArchive(MegTestConstants.ContentMegFileV1);

var reference = new MegDataEntryLocationReference(source, source.Archive[0]);

using var stream = reference.GetData();
Assert.Equal(MegTestConstants.CampaignFilesContent, ReadAllBytes(stream));
}

[Fact]
public void GetData_EntryNotInSource_Throws()
{
var source = ServiceProvider.GetRequiredService<IMegService>().LoadArchive(MegTestConstants.ContentMegFileV1);

var reference =
new MegDataEntryLocationReference(source, MegDataEntryTest.CreateEntry("not/in/archive.xml"));

Assert.Throws<EntryNotInMegException>(reference.GetData);
}

private static byte[] ReadAllBytes(Stream stream)
{
using (stream)
{
using var ms = new MemoryStream();
stream.CopyTo(ms);
return ms.ToArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Security.Cryptography;
using PG.StarWarsGame.Files.MEG.Data;
using PG.StarWarsGame.Files.MEG.Files;
using Xunit;

namespace PG.StarWarsGame.Files.MEG.Test.Files;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c) Alamo Engine Tools and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

using System;
using PG.Commons.Hashing;
using PG.StarWarsGame.Files.MEG.Data.EntryLocations;
using System;
using System.IO;

namespace PG.StarWarsGame.Files.MEG.Data.Entries;

Expand All @@ -30,6 +31,16 @@ public MegDataEntryReference(MegDataEntryLocationReference location) : base(loca
{
}

/// <summary>
/// Gets a read-only stream over the referenced location data.
/// </summary>
/// <returns>A read-only stream containing the entry's data.</returns>
/// <exception cref="EntryNotInMegException"><see cref="MegDataEntryBase{T}.Location"/> does not point to a valid entry.</exception>
public Stream GetData()
{
return Location.GetData();
}

/// <inheritdoc />
public bool Equals(MegDataEntryReference? other)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using PG.StarWarsGame.Files.MEG.Data.Entries;
using PG.StarWarsGame.Files.MEG.Files;

Expand Down Expand Up @@ -40,6 +41,16 @@ public MegDataEntryLocationReference(IMegDataSource source, MegDataEntry dataEnt
DataEntry = dataEntry ?? throw new ArgumentNullException(nameof(dataEntry));
}

/// <summary>
/// Gets a read-only stream over the referenced entry data.
/// </summary>
/// <returns>A read-only stream containing the entry's data.</returns>
/// <exception cref="EntryNotInMegException"><see cref="DataEntry"/> is not contained in <see cref="Source"/>.</exception>
public Stream GetData()
{
return Source.GetData(DataEntry);
}

/// <inheritdoc />
public bool Equals(MegDataEntryLocationReference? other)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using PG.StarWarsGame.Files.MEG.Binary.Size;
using PG.StarWarsGame.Files.MEG.Files;
using PG.StarWarsGame.Files.MEG.Services.Builder.Normalization;
using PG.StarWarsGame.Files.MEG.Services.Builder.Validation;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.Text;
using AnakinRaW.CommonUtilities.Testing;
using AnakinRaW.CommonUtilities.Testing.Extensions;
Expand Down Expand Up @@ -31,7 +30,7 @@ public void LoadFile_ArgumentException_Throws()
{
Assert.Throws<ArgumentException>(() => _mtdService.LoadFile(""));
Assert.Throws<ArgumentNullException>(() => _mtdService.LoadFile((string)null!));
Assert.Throws<ArgumentNullException>(() => _mtdService.LoadFile((FileSystemStream)null!));
Assert.Throws<ArgumentNullException>(() => _mtdService.LoadFile((Stream)null!));
Assert.Throws<ArgumentNullException>(() => _mtdService.LoadModel((Stream)null!));
Assert.Throws<ArgumentNullException>(() => _mtdService.LoadModel((byte[])null!));
}
Expand Down Expand Up @@ -85,6 +84,53 @@ public void LoadFile_StreamStaysOpen(byte[] data, IList<MtdEntryInformationConta
fs.Position = 0;
}

[Theory]
[MemberData(nameof(MtdTestData.ValidMtdData), MemberType = typeof(MtdTestData))]
public void LoadFile_FileStream_SetsAbsolutePathAndNotInMeg(byte[] data, IList<MtdEntryInformationContainer> files)
{
FileSystem.Initialize().WithFile("test.mtd").Which(m => m.HasBytesContent(data));

using var fs = FileSystem.File.OpenRead("test.mtd");

var mtdFile = _mtdService.LoadFile(fs);

CompareFileWithExpected(files, mtdFile);

Assert.False(mtdFile.FileInformation.IsInsideMeg);
Assert.Equal(FileSystem.Path.GetFullPath("test.mtd"), mtdFile.FilePath);
Assert.Equal(FileSystem.Path.GetFullPath("test.mtd"), mtdFile.FileInformation.FilePath);
}

[Theory]
[MemberData(nameof(MtdTestData.ValidMtdData), MemberType = typeof(MtdTestData))]
public void LoadFile_MegStream_KeepsEntryPathAndMarksInMeg(byte[] data, IList<MtdEntryInformationContainer> files)
{
const string entryPath = "data/textures/test.mtd";

using var megStream = new TestMegDataStream(entryPath, data);

var mtdFile = _mtdService.LoadFile(megStream);

CompareFileWithExpected(files, mtdFile);

// The MEG entry path is kept verbatim and must not be turned into an absolute file-system path.
Assert.True(mtdFile.FileInformation.IsInsideMeg);
Assert.Equal(entryPath, mtdFile.FilePath);
Assert.Equal(entryPath, mtdFile.FileInformation.FilePath);
}

[Theory]
[MemberData(nameof(MtdTestData.ValidMtdData), MemberType = typeof(MtdTestData))]
public void LoadFile_StreamWithoutPathInformation_Throws(byte[] data, IList<MtdEntryInformationContainer> files)
{
_ = files;

// A plain stream is neither a file stream nor an IMegFileDataStream, so no path can be determined.
using var stream = new MemoryStream(data);

Assert.Throws<InvalidOperationException>(() => _mtdService.LoadFile(stream));
}

[Fact]
public void LoadModel_FocMtd()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System;
using System.IO;
using System.IO.Abstractions;
using PG.Commons.Data;
using PG.StarWarsGame.Files.Binary;
using PG.StarWarsGame.Files.MTD.Data;
using PG.StarWarsGame.Files.MTD.Files;
Expand All @@ -27,14 +27,15 @@ public interface IMtdService
IMtdFile LoadFile(string filePath);

/// <summary>
/// Loads an MTD file stream into a <see cref="IMtdFile"/>.
/// Loads an MTD stream into a <see cref="IMtdFile"/>.
/// </summary>
/// <param name="fileStream">The MTD file stream.</param>
/// <param name="stream">The MTD file stream.</param>
/// <returns>A representation of the MTD file.</returns>
/// <exception cref="NotSupportedException"><paramref name="fileStream"/> is not readable or seekable.</exception>
/// <exception cref="BinaryCorruptedException"><paramref name="fileStream"/> is not a valid MTD file.</exception>
/// <exception cref="ArgumentNullException"><paramref name="fileStream"/> is <see langword="null"/>.</exception>
IMtdFile LoadFile(FileSystemStream fileStream);
/// <exception cref="NotSupportedException"><paramref name="stream"/> is not readable or seekable.</exception>
/// <exception cref="BinaryCorruptedException"><paramref name="stream"/> is not a valid MTD file.</exception>
/// <exception cref="ArgumentNullException"><paramref name="stream"/> is <see langword="null"/>.</exception>
/// <exception cref="InvalidOperationException"><paramref name="stream"/> is not a file stream or an <see cref="IMegFileDataStream"/>.</exception>
IMtdFile LoadFile(Stream stream);

/// <summary>
/// Loads MTD data from a stream into a <see cref="IMegaTextureDirectory"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.IO;
using System.IO.Abstractions;
using AnakinRaW.CommonUtilities;
using Microsoft.Extensions.DependencyInjection;
using PG.Commons.Services;
Expand All @@ -27,19 +26,19 @@ public IMtdFile LoadFile(string filePath)
return LoadFile(fs);
}

public IMtdFile LoadFile(FileSystemStream fileStream)
public IMtdFile LoadFile(Stream stream)
{
if (fileStream == null)
throw new ArgumentNullException(nameof(fileStream));

var model = ReadModel(fileStream);
if (stream == null)
throw new ArgumentNullException(nameof(stream));

var filePath = fileStream.GetFilePath(out var isInMeg);
var filePath = stream.GetFilePath(out var isInMeg);

// If the .MTD file is not embedded in a MEG, we want the absolute path.
if (!isInMeg)
filePath = FileSystem.Path.GetFullPath(filePath);

var model = ReadModel(stream);

var megFileInfo = new MtdFileInformation { FilePath = filePath, IsInsideMeg = isInMeg};

return new MtdFile(model, megFileInfo, Services);
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "4.0",
"version": "4.1",
"assemblyVersion": {
"precision": "major"
},
Expand Down
Loading