private void AssertContainsEntry(ModuleEntry entry) { if (!ContainsEntry(entry)) { throw new ArgumentException("The entry does not belong to the module"); } }
/// <summary> /// Opens a stream on an entry. /// </summary> /// <param name="moduleStream">A stream open on the module file.</param> /// <param name="entry">The entry.</param> /// <param name="section">The section to open.</param> /// <returns>A stream which can be used to read the entry data. It will depend on <paramref name="moduleStream"/>.</returns> public ModuleBlockStream OpenEntry(Stream moduleStream, ModuleEntry entry, ModuleEntrySection section) { AssertContainsEntry(entry); var blockCompressor = new ModuleBlockCompressor(moduleStream, DataBaseOffset); return(new ModuleBlockStream(blockCompressor, entry, section)); }
/// <summary> /// Checks if a <see cref="ModuleEntry"/> belongs to this module. /// </summary> /// <param name="entry">The entry.</param> /// <returns><c>true</c> if the entry belongs to this module.</returns> public bool ContainsEntry(ModuleEntry entry) { if (entry.Index < 0 || entry.Index >= _entries.Count) { return(false); } return(_entries[entry.Index] == entry); }
/// <summary> /// Extracts an entry to a file. All directories in the path will be created. /// </summary> /// <param name="moduleStream">A stream open on the module file.</param> /// <param name="entry">The entry.</param> /// <param name="section">The section to extract.</param> /// <param name="filePath">The path of the output file to create.</param> public void ExtractEntry(Stream moduleStream, ModuleEntry entry, ModuleEntrySection section, string filePath) { AssertContainsEntry(entry); var directories = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directories)) { Directory.CreateDirectory(directories); } using (var fileStream = File.Create(filePath)) ExtractEntry(moduleStream, entry, section, fileStream); }
private MemoryStream _currentBlockStream; // Can be null public ModuleBlockStream(ModuleBlockCompressor blockCompressor, ModuleEntry entry, ModuleEntrySection section) { _blockCompressor = blockCompressor; _entryOffset = entry.DataOffset; _blocks = GetBlocks(entry, section); if (_blocks.Count > 0) { _sectionOffset = _blocks[0].UncompressedOffset; _entryPosition = _sectionOffset; var lastBlock = _blocks[_blocks.Count - 1]; _sectionLength = lastBlock.UncompressedOffset + lastBlock.UncompressedSize - _sectionOffset; } }
private static List <ModuleDataBlock> GetBlocks(ModuleEntry entry, ModuleEntrySection section) { if (entry.IsRawFile && section != ModuleEntrySection.All) { throw new ArgumentException($"Raw module entries cannot be accessed per-section"); } int start, count; switch (section) { case ModuleEntrySection.Header: start = 0; count = entry.HeaderBlockCount; break; case ModuleEntrySection.TagData: start = entry.HeaderBlockCount; count = entry.TagDataBlockCount; break; case ModuleEntrySection.ResourceData: start = entry.HeaderBlockCount + entry.TagDataBlockCount; count = entry.ResourceBlockCount; break; case ModuleEntrySection.All: start = 0; count = entry.Blocks.Count; break; default: throw new ArgumentException($"Unsupported module entry section {section}", nameof(section)); } return(entry.Blocks .Skip(start) .Take(count) .OrderBy(b => b.UncompressedOffset) .ToList()); }
/// <summary> /// Looks up an entry by its global tag ID. /// </summary> /// <param name="id">The global tag ID to search for.</param> /// <param name="entry">The result variable.</param> /// <returns><c>true</c> if the entry was found.</returns> public bool GetEntryByGlobalTagId(int id, out ModuleEntry entry) { return(_entriesByGlobalTagId.TryGetValue(id, out entry)); }
/// <summary> /// Looks up an entry by its filename. /// </summary> /// <param name="name">The filename to search for.</param> /// <param name="entry">The result variable.</param> /// <returns><c>true</c> if the entry was found.</returns> public bool GetEntryByName(string name, out ModuleEntry entry) { return(_entriesByName.TryGetValue(name, out entry)); }
/// <summary> /// Extracts all or part of an entry to a stream. /// </summary> /// <param name="moduleStream">A stream open on the module file.</param> /// <param name="entry">The entry.</param> /// <param name="section">The section to extract.</param> /// <param name="outStream">The stream to extract to.</param> public void ExtractEntry(Stream moduleStream, ModuleEntry entry, ModuleEntrySection section, Stream outStream) { AssertContainsEntry(entry); using (var entryStream = OpenEntry(moduleStream, entry, section)) entryStream.CopyTo(outStream); }