public MegFileHolder Load(string filePath) { if (null == filePath || !StringUtility.HasText(filePath)) { throw new ArgumentNullException(nameof(filePath)); } if (!m_fileSystem.File.Exists(filePath)) { throw new FileNotFoundException($"The file {filePath} does not exist."); } uint headerSize = GetMegFileHeaderSize(filePath); byte[] megFileHeader = new byte[headerSize]; using (BinaryReader reader = new BinaryReader(m_fileSystem.FileStream.Create(filePath, FileMode.Open))) { reader.Read(megFileHeader, 0, megFileHeader.Length); } MegFileBuilder builder = new MegFileBuilder(); MegFile megFile = builder.FromBytes(megFileHeader); MegFileHolder holder = new MegFileHolder(m_fileSystem.Path.GetDirectoryName(filePath), m_fileSystem.Path.GetFileNameWithoutExtension(filePath)); for (int i = 0; i < megFile.Header.NumFiles; i++) { string fileName = megFile.FileNameTable[i].FileName; uint fileOffset = megFile.FileContentTable[i].FileStartOffsetInBytes; uint fileSize = megFile.FileContentTable[i].FileSizeInBytes; holder.Content.Add(new MegFileDataEntry(fileName, Convert.ToInt32(fileOffset), fileSize)); } return(holder); }
public void UnpackSingleFileFromMegFile_Test__ThrowsArgumentException(string targetDirectory, string fileName) { IMegFileProcessService svc = new MegFileProcessService(m_fileSystem); MegFileHolder megFileHolder = svc.Load(TestConstants.FILE_PATH_MEG_FILE); svc.UnpackSingleFileFromMegFile(megFileHolder, targetDirectory, fileName); }
public void UnpackMegFile(MegFileHolder holder, string targetDirectory) { if (!m_fileSystem.Directory.Exists(targetDirectory)) { m_logger?.LogWarning($"The given directory does not exist. Trying to create it."); } }
public void PackFilesAsMegArchive(string megArchiveName, IDictionary <string, string> packedFileNameToAbsoluteFilePathsMap, string targetDirectory) { if (!StringUtility.HasText(megArchiveName)) { throw new ArgumentException( "The provided argument is null, an empty string or only consists of whitespace.", nameof(megArchiveName)); } if (!packedFileNameToAbsoluteFilePathsMap.Any()) { throw new ArgumentException( "The provided argument does not contain any elements.", nameof(packedFileNameToAbsoluteFilePathsMap)); } if (!StringUtility.HasText(targetDirectory)) { throw new ArgumentException( "The provided argument is null, an empty string or only consists of whitespace.", nameof(targetDirectory)); } string actualName = StringUtility.RemoveFileExtension(megArchiveName); MegFileHolder megFileHolder = new MegFileHolder(targetDirectory, actualName); foreach ((string key, string value) in packedFileNameToAbsoluteFilePathsMap) { megFileHolder.Content.Add(new MegFileDataEntry(key, value)); } MegFileBuilder builder = new MegFileBuilder(m_fileSystem); MegFile megFile = builder.FromHolder(megFileHolder, out IList <string> filesToStream); string writePath = m_fileSystem.Path.Combine(megFileHolder.FilePath, megFileHolder.FullyQualifiedName); CreateTargetDirectoryIfNotExists(megFileHolder.FilePath); using (BinaryWriter writer = new BinaryWriter(m_fileSystem.FileStream.Create(writePath, FileMode.Create, FileAccess.Write, FileShare.None))) { writer.Write(megFile.ToBytes()); } foreach (string file in filesToStream) { using Stream readStream = m_fileSystem.File.OpenRead(file); using Stream writeStream = m_fileSystem.FileStream.Create(writePath, FileMode.Append, FileAccess.Write, FileShare.None); byte[] buffer = new byte[BUFFER_SIZE]; int bytesRead; while ((bytesRead = readStream.Read(buffer, 0, buffer.Length)) > 0) { writeStream.Write(buffer, 0, bytesRead); } } }
private void UnpackMegFileFlatDirectoryHierarchy(MegFileHolder holder, string targetDirectory, MegFileDataEntry megFileDataEntry) { string filePath = m_fileSystem.Path.Combine(targetDirectory, megFileDataEntry.RelativeFilePath); filePath = m_fileSystem.Path.Combine(targetDirectory, m_fileSystem.Path.GetFileName(filePath)); using BinaryReader reader = GetBinaryReaderForFileHolder(holder); ExtractFileFromMegArchive(reader, megFileDataEntry, filePath); }
public void UnpackSingleFileFromMegFile_Test__ThrowsMultipleFilesWithMatchingNameInArchiveException() { string exportTestPath = m_fileSystem.Path.Combine(TestConstants.BASE_PATH, "UnpackSingleFileFromMegFile_Test__ThrowsFileNotContainedInArchiveException"); IMegFileProcessService svc = new MegFileProcessService(m_fileSystem); MegFileHolder megFileHolder = svc.Load(TestConstants.FILE_PATH_MEG_FILE); svc.UnpackSingleFileFromMegFile(megFileHolder, exportTestPath, "XML", false); }
private void UnpackMegFilePreservingDirectoryHierarchy(MegFileHolder holder, string targetDirectory, MegFileDataEntry megFileDataEntry) { string filePath = m_fileSystem.Path.Combine(targetDirectory, megFileDataEntry.RelativeFilePath); string path = m_fileSystem.FileInfo.FromFileName(filePath).Directory.FullName; CreateTargetDirectoryIfNotExists(path); using BinaryReader reader = GetBinaryReaderForFileHolder(holder); ExtractFileFromMegArchive(reader, megFileDataEntry, filePath); }
public void UnpackMegFile(MegFileHolder holder, string targetDirectory) { CreateTargetDirectoryIfNotExists(targetDirectory); using BinaryReader readStream = GetBinaryReaderForFileHolder(holder); foreach (MegFileDataEntry megFileDataEntry in holder.Content) { string filePath = m_fileSystem.Path.Combine(targetDirectory, megFileDataEntry.RelativeFilePath); string path = m_fileSystem.FileInfo.FromFileName(filePath).Directory.FullName; CreateTargetDirectoryIfNotExists(path); ExtractFileFromMegArchive(readStream, megFileDataEntry, filePath); } }
public void FromHolder_Test__FileHeaderIsBinaryEquivalent() { MegFileHolder megFileHolder = new MegFileHolder(BASE_PATH, "test"); megFileHolder.Content.Add(new MegFileDataEntry("data/xml/campaignfiles.xml")); megFileHolder.Content.Add(new MegFileDataEntry("data/xml/gameobjectfiles.xml")); MegFileBuilder builder = new MegFileBuilder(m_fileSystem); MegFile megFile = builder.FromHolder(megFileHolder); Assert.IsNotNull(megFile); m_fileSystem.File.WriteAllBytes(m_fileSystem.Path.Combine(BASE_PATH, megFileHolder.FileName + "." + megFileHolder.FileType.FileExtension), megFile.ToBytes()); var f = m_fileSystem.File.ReadAllBytes(m_fileSystem.Path.Combine(BASE_PATH, megFileHolder.FileName + "." + megFileHolder.FileType.FileExtension)); }
public void UnpackSingleFileFromMegFile_Test__DirectoryHierarchyFlatUnpackedFileIsBinaryEquivalent() { string exportTestPath = m_fileSystem.Path.Combine(TestConstants.BASE_PATH, "UnpackSingleFileFromMegFile_Test__UnpackedFileIsBinaryEquivalent"); IMegFileProcessService svc = new MegFileProcessService(m_fileSystem); MegFileHolder megFileHolder = svc.Load(TestConstants.FILE_PATH_MEG_FILE); svc.UnpackSingleFileFromMegFile(megFileHolder, exportTestPath, TestConstants.FILE_NAME_GAMEOBJECTFILES, false); byte[] expected = m_fileSystem.File.ReadAllBytes(TestConstants.FILE_PATH_GAMEOBJECTFILES); byte[] actual = m_fileSystem.File.ReadAllBytes(m_fileSystem.Path.Combine(exportTestPath, TestConstants.FILE_NAME_GAMEOBJECTFILES.ToUpper())); TestUtility.AssertAreBinaryEquivalent(expected, actual); }
public void UnpackSingleFileFromMegFile(MegFileHolder holder, string targetDirectory, string fileName, bool preserveDirectoryHierarchy = true) { if (holder.Content == null || !holder.Content.Any()) { throw new ArgumentException( $"{typeof(MegFileHolder)}:{nameof(holder)} is not valid or contains no data."); } if (!StringUtility.HasText(targetDirectory)) { throw new ArgumentException( $"{typeof(string)}:{nameof(targetDirectory)} is not valid or contains no data."); } if (!StringUtility.HasText(fileName)) { throw new ArgumentException( $"{typeof(string)}:{nameof(fileName)} is not valid or contains no data."); } if (!holder.TryGetAllMegFileDataEntriesWithMatchingName(fileName, out IList <MegFileDataEntry> megFileDataEntries)) { throw new FileNotContainedInArchiveException( $"The file \"{fileName}\" is not contained in the currently loaded MEG archive \"{holder.FullyQualifiedName}\""); } if (megFileDataEntries.Count > 1) { throw new MultipleFilesWithMatchingNameInArchiveException( $"There are multiple files matching the search filer \"{fileName}\" in the currently loaded MEG archive \"{holder.FullyQualifiedName}\". The files cannot be extracted without conflicting overwrites." + $"\nFiles in question: {megFileDataEntries}"); } CreateTargetDirectoryIfNotExists(targetDirectory); if (preserveDirectoryHierarchy) { UnpackMegFilePreservingDirectoryHierarchy(holder, targetDirectory, megFileDataEntries[0]); } else { UnpackMegFileFlatDirectoryHierarchy(holder, targetDirectory, megFileDataEntries[0]); } }
public void FromHolder_Test__FileHeaderIsConsistent() { MegFileHolder megFileHolder = new MegFileHolder(BASE_PATH, "test"); megFileHolder.Content.Add(new MegFileDataEntry("data/xml/campaignfiles.xml")); megFileHolder.Content.Add(new MegFileDataEntry("data/xml/gameobjectfiles.xml")); MegFileBuilder builder = new MegFileBuilder(m_fileSystem); MegFile megFile = builder.FromHolder(megFileHolder); Assert.IsNotNull(megFile); Assert.IsNotNull(megFile.Header); Assert.IsNotNull(megFile.FileContentTable); Assert.IsNotNull(megFile.FileNameTable); Assert.AreEqual(2u, megFile.Header.NumFiles); Assert.AreEqual(2u, megFile.Header.NumFileNames); Assert.AreEqual(40, megFile.FileContentTable.Size); Assert.AreEqual(58, megFile.FileNameTable.Size); Assert.IsTrue(megFile.FileNameTable.MegFileNameTableRecords[0].FileName.Equals("data/xml/gameobjectfiles.xml", StringComparison.InvariantCultureIgnoreCase)); Assert.IsTrue(megFile.FileNameTable.MegFileNameTableRecords[1].FileName.Equals("data/xml/campaignfiles.xml", StringComparison.InvariantCultureIgnoreCase)); }
public void Load_Test__MegFileHolderIntegrity() { IMegFileProcessService svc = new MegFileProcessService(m_fileSystem); MegFileHolder megFileHolder = svc.Load(TestConstants.FILE_PATH_MEG_FILE); Assert.IsTrue(StringUtility.HasText(megFileHolder.FileName)); string expectedFileName = TestConstants.FILE_NAME_MEG_FILE.Replace(".meg", string.Empty); string expectedFilePath = TestConstants.FILE_PATH_MEG_FILE.Replace( (TestUtility.IsWindows() ? "\\" : "/") + TestConstants.FILE_NAME_MEG_FILE, string.Empty); Assert.IsTrue(expectedFileName.Equals(megFileHolder.FileName, StringComparison.InvariantCultureIgnoreCase)); Assert.IsTrue(expectedFilePath.Equals(megFileHolder.FilePath, StringComparison.InvariantCultureIgnoreCase)); Assert.AreEqual(2, megFileHolder.Content.Count); const string expectedBasePath = "DATA/XML/"; foreach (MegFileDataEntry megFileDataEntry in megFileHolder.Content) { if (megFileDataEntry.RelativeFilePath.Equals( expectedBasePath + TestConstants.FILE_NAME_GAMEOBJECTFILES, StringComparison.InvariantCultureIgnoreCase)) { uint expectedFileSize = (uint)m_fileSystem.File.ReadAllBytes(TestConstants.FILE_PATH_GAMEOBJECTFILES).Length; Assert.AreEqual(expectedFileSize, megFileDataEntry.Size); } if (megFileDataEntry.RelativeFilePath.Equals( expectedBasePath + TestConstants.FILE_NAME_CAMPAIGNFILES, StringComparison.InvariantCultureIgnoreCase)) { uint expectedFileSize = (uint)m_fileSystem.File.ReadAllBytes(TestConstants.FILE_PATH_CAMPAIGNFILES).Length; Assert.AreEqual(expectedFileSize, megFileDataEntry.Size); } } }
public void FromHolder_Test__FileHeaderIsBinaryEquivalent() { MegFileHolder megFileHolder = new MegFileHolder(TestConstants.BASE_PATH, "FromHolder_Test__FileHeaderIsBinaryEquivalent"); megFileHolder.Content.Add(new MegFileDataEntry("data/xml/campaignfiles.xml", TestConstants.FILE_PATH_CAMPAIGNFILES)); megFileHolder.Content.Add(new MegFileDataEntry("data/xml/gameobjectfiles.xml", TestConstants.FILE_PATH_GAMEOBJECTFILES)); MegFileBuilder builder = new MegFileBuilder(m_fileSystem); MegFile megFile = builder.FromHolder(megFileHolder); Assert.IsNotNull(megFile); m_fileSystem.File.WriteAllBytes( m_fileSystem.Path.Combine(TestConstants.BASE_PATH, megFileHolder.FullyQualifiedName), megFile.ToBytes()); byte[] readMegFile = m_fileSystem.File.ReadAllBytes(m_fileSystem.Path.Combine(TestConstants.BASE_PATH, megFileHolder.FullyQualifiedName)); Assert.AreEqual(TestConstants.CONTENT_MEG_FILE_HEADER.Length, readMegFile.Length); for (int i = 0; i < TestConstants.CONTENT_MEG_FILE_HEADER.Length; i++) { Assert.AreEqual(TestConstants.CONTENT_MEG_FILE_HEADER[i], readMegFile[i]); } }
public void UnpackMegFile(MegFileHolder holder, string targetDirectory, string fileName, bool preserveDirectoryHierarchy = true) { throw new System.NotImplementedException(); }
private BinaryReader GetBinaryReaderForFileHolder(MegFileHolder holder) { return(new BinaryReader(m_fileSystem.FileStream.Create( m_fileSystem.Path.Combine(holder.FilePath, $"{holder.FileName}.{holder.FileType.FileExtension}"), FileMode.Open, FileAccess.Read, FileShare.Read))); }
public void SetUp() { s_holder = new MegFileHolder("test", "test"); s_holder.Content.Add(new MegFileDataEntry(FILE_NAME_1, "C:/my_absolute/my_file.txt")); s_holder.Content.Add(new MegFileDataEntry(FILE_NAME_2, "C:/my_absolute/another_file.txt")); }
public void UnpackMegFile(string filePath, string targetDirectory) { MegFileHolder holder = Load(filePath); UnpackMegFile(holder, targetDirectory); }