public void GZipAccess_OpenFromDisk_HasExpectedContent(CompressedArchiveAccessImplementation implementation) { string testResourcePath; using (TestResource.TagalongBinCfgNNGZip.ExtractToTemporaryFile(out testResourcePath)) using (var gzip = CompressedArchiveAccess.Open(testResourcePath, CompressedArchiveAccessMode.Read, implementation)) { var expectedCrc32s = new[] { TestRomResources.TestBinCrc, TestRomResources.TestCfgCrc }; var i = 0; foreach (var entry in gzip.Entries) { using (var entryStream = gzip.OpenEntry(entry)) using (var validationStream = new MemoryStream()) { // Some implementations, e.g. SharpZipLib, inflate the ENTIRE contents of ALL members of a multi-member entry into one giant output, // so we need to read to an intermediate stream, then verify the output. entryStream.CopyTo(validationStream); validationStream.SetLength(entry.Length); var crc = Crc32.OfStream(validationStream); Assert.Equal(expectedCrc32s[i], crc); } ++i; } } }
/// <summary> /// Associates an implementation with a previously registered <see cref="CompressedArchiveFormat"/>. /// </summary> /// <param name="format">The compressed archive format with which to associate an implementation.</param> /// <param name="implementation">The implementation to associate with the compressed archive format</param> /// <param name="makePreferred">If <c>true</c>, <paramref name="implementation"/> becomes the implementation returned by <see cref="GetPreferredCompressedArchiveImplementation(CompressedArchiveFormat)"/>.</param> /// <returns><c>true</c> if <paramref name="implementation"/> was added, <c>false</c> otherwise.</returns> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if <paramref name="format"/> is <see cref="CompressedArchiveFormat.None"/>. Also thrown if the /// value of <paramref name="implementation"/> is <see cref="CompressedArchiveAccessImplementation.Any"/> or <see cref="CompressedArchiveAccessImplementation.None"/>.</exception> /// <exception cref="System.ArgumentException">Thrown if <paramref name="format"/>has not already been registered as an available format, /// either as a format automatically included in the implementation, or registered via /// <see cref="RegisterCompressedArchiveFormat(CompressedArchiveFormat, IEnumerable{string}, IEnumerable{CompressedArchiveAccessImplementation})"/>.</exception> public static bool AddImplementation(this CompressedArchiveFormat format, CompressedArchiveAccessImplementation implementation, bool makePreferred) { if (format == CompressedArchiveFormat.None) { throw new ArgumentOutOfRangeException("format"); } if ((implementation == CompressedArchiveAccessImplementation.None) || (implementation == CompressedArchiveAccessImplementation.Any)) { throw new ArgumentOutOfRangeException("implementation"); } lock (Lock) { IList <CompressedArchiveAccessImplementation> existingImplementationsForFormat; var formatAlreadyRegistered = CompressedArchiveAccessImplementations.Value.TryGetValue(format, out existingImplementationsForFormat); var added = false; if (formatAlreadyRegistered) { added = AddOrUpdateCompressedArchiveFormatData(implementation, makePreferred, existingImplementationsForFormat, (i, e) => e.IndexOf(i)); } else { var message = string.Format(CultureInfo.CurrentCulture, Resources.Strings.CompressedArchiveFormat_FormatIsNotRegisteredError_Format, format); throw new ArgumentException(message, "format"); } return(added); } }
public void ZipArchiveAccess_OpenNonZip_ThrowsInvalidDataException(CompressedArchiveAccessImplementation implementation) { var nonZipResource = TestResource.TextEmbeddedResourceFile; var stream = nonZipResource.OpenResourceForReading(); Assert.Throws <InvalidDataException>(() => CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.Zip, CompressedArchiveAccessMode.Read, implementation)); }
public void GZipAccess_CreateEntryInEmptyStream_Succeeds(CompressedArchiveAccessImplementation implementation) { var stream = new MemoryStream(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)) { Assert.NotNull(gzip.CreateEntry("newEntry")); } }
public void GZipAccess_Format_IsGZip(CompressedArchiveAccessImplementation implementation) { var stream = new MemoryStream(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)) { Assert.Equal(CompressedArchiveFormat.GZip, gzip.Format); } }
public void GZipAccess_IsCompressed_IsTrue(CompressedArchiveAccessImplementation implementation) { var stream = new MemoryStream(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)) { Assert.True(gzip.IsCompressed); } }
public void GZipAccess_OpenWithInvalidMode_ThrowsArgumentOutOfRangeException(CompressedArchiveAccessImplementation implementation) { var gzipResource = TestResource.TagalongBinGZip; using (var stream = gzipResource.OpenResourceForReading()) { Assert.Throws <ArgumentOutOfRangeException>(() => CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, (CompressedArchiveAccessMode)100, implementation)); } }
public void GZipAccess_CreateSecondEntry_ThrowsNotSupportedException(CompressedArchiveAccessImplementation implementation) { var stream = new MemoryStream(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)) { gzip.CreateEntry("newEntry"); Assert.Throws <NotSupportedException>(() => gzip.CreateEntry("newEntry")); } }
public void GZipAccess_WriteRomResourceToGZipFile_ProducesExpectedResult(CompressedArchiveAccessImplementation implementation) { var gzipFileName = TemporaryFile.GenerateUniqueFilePath("tagalong", ".luigi.gz"); using (TemporaryFile.CreateTemporaryFileWithPath(gzipFileName, createEmptyFile: false)) { // Create on-disk GZIP var inputLength = 0L; var fileStream = new FileStream(gzipFileName, FileMode.Create, FileAccess.Write); using (var gzip = CompressedArchiveAccess.Open(fileStream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)) { var testResourceName = "INTV.TestHelpers.Core.Resources.tagalong.luigi"; var newGZipEntryName = "tagalong.luigi"; var entry = gzip.CreateEntry(newGZipEntryName); using (var gzipStream = gzip.Open(entry.Name)) using (var sourceStream = typeof(TestRomResources).Assembly.GetManifestResourceStream(testResourceName)) { sourceStream.CopyTo(gzipStream); inputLength = sourceStream.Length; } } // Now, see if we can extract it! var extractedRomPath = Path.Combine(Path.GetDirectoryName(gzipFileName), Path.GetFileNameWithoutExtension(gzipFileName)); using (TemporaryFile.CreateTemporaryFileWithPath(extractedRomPath, createEmptyFile: false)) { var fileInfo = new FileInfo(gzipFileName); Assert.True(fileInfo.Exists); Assert.True(inputLength > fileInfo.Length); // Compressed we must be! On this, all depends. using (var gzip = CompressedArchiveAccess.Open(gzipFileName, CompressedArchiveAccessMode.Read, implementation)) { Assert.True(gzip.Entries.Any()); var entry = gzip.Entries.Single(); Assert.False(string.IsNullOrEmpty(entry.Name)); using (var outputFileStream = new FileStream(extractedRomPath, FileMode.Create, FileAccess.Write)) using (var gzipStream = gzip.OpenEntry(entry)) { gzipStream.CopyTo(outputFileStream); } } // Verify we have a valid LUIGI and it's got what we expect inside. Trust, but verify! LuigiFileHeader header = null; using (var outputFileStream = new FileStream(extractedRomPath, FileMode.Open, FileAccess.Read)) { header = LuigiFileHeader.Inflate(outputFileStream); } Assert.NotNull(header); Assert.Equal(RomFormat.Bin, header.OriginalRomFormat); Assert.Equal(TestRomResources.TestBinCrc, header.OriginalRomCrc32); } } }
public void GZipAccess_DeleteEntry_ThrowsNotSupportedException(CompressedArchiveAccessImplementation implementation) { var gzipResource = TestResource.TagalongCfgGZip; var entryName = gzipResource.ArchiveContents.First(); var stream = gzipResource.OpenResourceForReading(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Read, implementation)) { Assert.Throws <NotSupportedException>(() => gzip.DeleteEntry(entryName)); } }
/// <summary> /// Register a factory method for a specific implementation and type of compressed archive access type. /// </summary> /// <param name="format">The format for which the factory is being registered.</param> /// <param name="implementation">The implementation for which the factory is being registered.</param> /// <param name="factory">The factory method.</param> /// <returns><c>true</c> if the factory was successfully registered; <c>false</c> otherwise.</returns> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the value of <paramref name="format"/> or <paramref name="implementation"/> is not valid.</exception> public static bool RegisterFactory(CompressedArchiveFormat format, CompressedArchiveAccessImplementation implementation, CompressedArchiveAccessFactory factory) { if (format == CompressedArchiveFormat.None) { var message = string.Format(CultureInfo.CurrentCulture, Resources.Strings.CompressedArchiveAccess_InvalidCompressionFormatTypeErrorMessage_Format, format); throw new ArgumentOutOfRangeException("format", message); } if ((implementation == CompressedArchiveAccessImplementation.None) || (implementation == CompressedArchiveAccessImplementation.Any)) { var message = string.Format(CultureInfo.CurrentCulture, Resources.Strings.CompressedArchiveAccess_InvalidCompressionImplementationTypeErrorMessage_Format, implementation, format); throw new ArgumentOutOfRangeException("implementation", message); } var registered = Factories.Value.TryAdd(new CompressedArchiveIdentifier(format, implementation), factory); return(registered); }
public void GZipAccess_OpenSecondMemberEntry_HasExpectedContents(CompressedArchiveAccessImplementation implementation) { var gzipResource = TestResource.TagalongBinCfgYYGZip; var stream = gzipResource.OpenResourceForReading(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Read, implementation)) { var entry = gzip.Entries.Last(); var crc = 0u; using (var entryStream = gzip.OpenEntry(entry)) { crc = Crc32.OfStream(entryStream, fromStartOfStream: false); } Assert.Equal(gzipResource.ArchiveContents.Last(), entry.Name); Assert.Equal(TestRomResources.TestCfgCrcUnix, crc); } }
public void GZipAccess_OpenSingleMemberFileWithEntryName_HasExpectedContents(CompressedArchiveAccessImplementation implementation) { var gzipResource = TestResource.TagalongBinGZip; var stream = gzipResource.OpenResourceForReading(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Read, implementation)) { var entry = gzip.Entries.Single(); var crc = 0u; using (var entryStream = gzip.Open(entry.Name)) { crc = Crc32.OfStream(entryStream, fromStartOfStream: false); } Assert.Equal(gzipResource.ArchiveContents.First(), entry.Name); Assert.Equal(TestRomResources.TestBinCrc, crc); } }
public void ZipArchiveAccess_OpenEntryForRead_SuccessfullyOpensEntry(CompressedArchiveAccessImplementation implementation) { var zipResource = TestResource.TagalongDirZip; var zipStream = zipResource.OpenResourceForReading(); using (var zipArchive = CompressedArchiveAccess.Open(zipStream, CompressedArchiveFormat.Zip, CompressedArchiveAccessMode.Read, implementation)) { var zipEntry = zipArchive.FindEntry(zipResource.ArchiveContents.First(e => e.EndsWith(".luigi"))); var entries = zipArchive.Entries; Assert.NotNull(zipEntry); Assert.Equal(zipResource.ArchiveContents, entries.Select(e => e.Name)); Assert.True(entries.Any(e => e.IsDirectory)); using (var zipEntryStream = zipArchive.OpenEntry(zipEntry)) { Assert.NotNull(zipEntryStream); VerifyLuigiZipEntry(zipEntryStream); } } }
public void ZipArchiveAccess_OpenForRead_HasExpectedContents(CompressedArchiveAccessImplementation implementation) { var zipResource = TestResource.TagalongZip; var zipStream = zipResource.OpenResourceForReading(); using (var zipArchive = CompressedArchiveAccess.Open(zipStream, CompressedArchiveFormat.Zip, CompressedArchiveAccessMode.Read, implementation)) { var entries = zipArchive.Entries; Assert.True(zipArchive.IsArchive); Assert.True(zipArchive.IsCompressed); Assert.Equal(CompressedArchiveFormat.Zip, zipArchive.Format); Assert.Equal(zipResource.ArchiveContents.Count(), entries.Count()); Assert.Equal(zipResource.ArchiveContents, entries.Select(e => e.Name)); Assert.All(entries, e => Assert.True(e.Length > 0)); Assert.All(entries, e => Assert.True(e.Length > 0)); Assert.All(entries, e => Assert.True(e.LastModificationTime.Year > 1978)); Assert.All(entries, e => Assert.False(e.IsDirectory)); } }
public void GZipAccess_WriteRomResourceToGZip_ProducesExpectedResult(CompressedArchiveAccessImplementation implementation) { var inputCrc = 0u; var inputLength = 0L; // Create in-memory GZIP var newMemoryStream = new MemoryStream(); var copyMemoryStream = new MemoryStream(); using (var gzip = CompressedArchiveAccess.Open(newMemoryStream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)) { var testResourceName = "INTV.TestHelpers.Core.Resources.tagalong.luigi"; var newGZipEntryName = "tagalong.luigi"; var entry = gzip.CreateEntry(newGZipEntryName); using (var gzipStream = gzip.Open(entry.Name)) using (var sourceStream = typeof(TestRomResources).Assembly.GetManifestResourceStream(testResourceName)) { sourceStream.CopyTo(gzipStream); inputCrc = Crc32.OfStream(sourceStream); inputLength = sourceStream.Length; } // Now, rewind and see if we can extract it! newMemoryStream.Seek(0, SeekOrigin.Begin); newMemoryStream.CopyTo(copyMemoryStream); } using (var gzip = CompressedArchiveAccess.Open(copyMemoryStream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Read, implementation)) { Assert.True(inputLength > copyMemoryStream.Length); // let's assume some kind of compression happened! Assert.True(gzip.Entries.Any()); var entry = gzip.Entries.Single(); Assert.False(string.IsNullOrEmpty(entry.Name)); using (var gzipStream = gzip.OpenEntry(entry)) { var extractedEntryCrc = Crc32.OfStream(gzipStream, fromStartOfStream: false); Assert.Equal(inputCrc, extractedEntryCrc); } } }
public static TestCompressedArchiveAccess Create( Stream stream, CompressedArchiveAccessMode mode, CompressedArchiveFormat format, CompressedArchiveAccessImplementation implementation, string firstEntryName = null, bool isArchive = true, bool isCompressed = true) { var testArchiveAccess = new TestCompressedArchiveAccess() { Mode = mode, _format = format, Implementation = implementation }; testArchiveAccess._isArchive = isArchive; testArchiveAccess._isCompressed = isCompressed; if (!string.IsNullOrWhiteSpace(firstEntryName)) { testArchiveAccess.CreateAndAddEntry(firstEntryName); } return(testArchiveAccess); }
public void CompressedArchiveFormat_GetPreferredCompressedArchiveImplementation_ReturnsExpectedPreferredImplementation(CompressedArchiveFormat format, CompressedArchiveAccessImplementation expectedPreferredImplementation) { var preferredImplementation = format.GetPreferredCompressedArchiveImplementation(); Assert.Equal(expectedPreferredImplementation, preferredImplementation); }
private static void VerifyNumberOfEntries(string testZipFilePath, int expectedNumberOfEntries, CompressedArchiveAccessImplementation implementation) { using (var zipArchive = CompressedArchiveAccess.Open(testZipFilePath, CompressedArchiveAccessMode.Read, implementation)) { var numberOfEntries = zipArchive.Entries.Count(); Assert.Equal(expectedNumberOfEntries, numberOfEntries); } }
private static void VerifyTestZipContents(string testZipFilePath, string zipTestEntryName, string zipTestEntryContent, CompressedArchiveAccessImplementation implementation) { using (var tempFile = TemporaryFile.CreateTemporaryFileWithPath(testZipFilePath, createEmptyFile: false)) using (var zipArchive = CompressedArchiveAccess.Open(testZipFilePath, CompressedArchiveAccessMode.Read, implementation)) { var entries = zipArchive.Entries; Assert.True(entries.Any(e => e.IsDirectory)); var fileEntryStream = zipArchive.Open(zipTestEntryName); using (var streamReader = new StreamReader(fileEntryStream, Encoding.UTF8)) { var entryContent = streamReader.ReadToEnd(); Assert.Equal(zipTestEntryContent, entryContent); } } }
public void ZipArchiveAccess_DeleteAnEntryFromExistingZipArchive_RemovesEntry(CompressedArchiveAccessImplementation implementation) { var numberOfEntriesToCreate = 4; var zipTestEntryNameFormat = "testEntry_{0}"; var zipTestEntryContentFormat = "Here is some text to write for {0}!"; var testZipFilePath = TemporaryFile.GenerateUniqueFilePath("ZipTest", ".zip"); var zipStream = new FileStream(testZipFilePath, FileMode.Create, FileAccess.ReadWrite); // SharpZipLib requires ReadWrite, .NET works with Write only. using (var zipArchive = CompressedArchiveAccess.Open(zipStream, CompressedArchiveFormat.Zip, CompressedArchiveAccessMode.Create, implementation)) { for (var i = 0; i < numberOfEntriesToCreate; ++i) { var entryName = string.Format(CultureInfo.CurrentCulture, zipTestEntryNameFormat, i); var entry = zipArchive.CreateEntry(entryName); using (var zipEntryStream = zipArchive.OpenEntry(entry)) { var zipTestEntryContent = string.Format(CultureInfo.CurrentCulture, zipTestEntryContentFormat, entryName); var textToWrite = Encoding.UTF8.GetBytes(zipTestEntryContent); zipEntryStream.Write(textToWrite, 0, textToWrite.Length); } } } VerifyNumberOfEntries(testZipFilePath, numberOfEntriesToCreate, implementation); var numberOfEntriesToDelete = 2; using (var zipArchive = CompressedArchiveAccess.Open(testZipFilePath, CompressedArchiveAccessMode.Update, implementation)) { var entriesToDelete = zipArchive.Entries.Take(numberOfEntriesToDelete).Select(e => e.Name).ToList(); foreach (var entry in entriesToDelete) { zipArchive.DeleteEntry(entry); } } using (var tempFile = TemporaryFile.CreateTemporaryFileWithPath(testZipFilePath, createEmptyFile: false)) { VerifyNumberOfEntries(testZipFilePath, numberOfEntriesToCreate - numberOfEntriesToDelete, implementation); } }
public void ZipArchiveAccess_CreateNewZip_SuccessfullyAddDirectoryAndFileEntries(CompressedArchiveAccessImplementation implementation) { var zipTestEntryName = @"test\entry"; var zipTestEntryContent = "Here is some text to write!"; var testZipFilePath = TemporaryFile.GenerateUniqueFilePath("ZipTest", ".zip"); var zipStream = new FileStream(testZipFilePath, FileMode.Create, FileAccess.ReadWrite); // SharpZipLib requires ReadWrite, .NET works with Write only. using (var zipArchive = CompressedArchiveAccess.Open(zipStream, CompressedArchiveFormat.Zip, CompressedArchiveAccessMode.Create, implementation)) { var zipDirectoryEntryName = Path.GetDirectoryName(zipTestEntryName) + Path.DirectorySeparatorChar; var zipDirectoryEntry = zipArchive.CreateEntry(zipDirectoryEntryName); var zipEntry = zipArchive.CreateEntry(zipTestEntryName); using (var zipEntryStream = zipArchive.OpenEntry(zipEntry)) { var textToWrite = Encoding.UTF8.GetBytes(zipTestEntryContent); zipEntryStream.Write(textToWrite, 0, textToWrite.Length); } } Assert.True(File.Exists(testZipFilePath)); VerifyTestZipContents(testZipFilePath, zipTestEntryName, zipTestEntryContent, implementation); }
public void CompressedArchiveFormat_AddInvalidImplementationToFormat_ThrowsArgumentOutOfRangeException(CompressedArchiveAccessImplementation implementation) { var exception = Assert.Throws <ArgumentOutOfRangeException>(() => CompressedArchiveFormat.BZip2.AddImplementation(implementation, makePreferred: false)); Assert.Equal(exception.ParamName, "implementation"); }
public void GZipAccess_CreateEntryWhenOpenInDecompressMode_ThrowsInvalidOperationException(CompressedArchiveAccessImplementation implementation) { var gzipResource = TestResource.TagalongCfgGZip; var stream = gzipResource.OpenResourceForReading(); using (var gzip = CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Read, implementation)) { Assert.Throws <InvalidOperationException>(() => gzip.CreateEntry("derp")); } }
/// <summary> /// Initializes a new instance of <see cref="CompressedArchiveIdentifier"/>. /// </summary> /// <param name="format">The compressed archive format to use in the identifier.</param> /// <param name="implementation">The compressed archive access implementation kind to use in the identifier.</param> public CompressedArchiveIdentifier(CompressedArchiveFormat format, CompressedArchiveAccessImplementation implementation) { _format = format; _implementation = implementation; }
public void GZipAccess_OpenNonEmptyGZipForCreate_ThrowsInvalidOperationException(CompressedArchiveAccessImplementation implementation) { var gzipResource = TestResource.TagalongBinGZip; using (var stream = gzipResource.OpenResourceForReading()) { Assert.Throws <InvalidOperationException>(() => CompressedArchiveAccess.Open(stream, CompressedArchiveFormat.GZip, CompressedArchiveAccessMode.Create, implementation)); } }
public void CompressedArchiveAccess_RegisterFactoryWithForbiddenImplementationValue_ThrowsArgumentOutOfRangeException(CompressedArchiveAccessImplementation implementation) { var format = this.GetFakeCompressedArchiveFormatForTest(); Assert.Throws <ArgumentOutOfRangeException>(() => CompressedArchiveAccess.RegisterFactory( format, implementation, (s, m) => TestCompressedArchiveAccess.Create(s, m, format, implementation))); }