// /*************************************************************************** // The Disc Image Chef // ---------------------------------------------------------------------------- // // Filename : DataFile.cs // Author(s) : Natalia Portillo // // Component : Core algorithms. // // --[ Description ] ---------------------------------------------------------- // // Abstracts writing to files. // // --[ License ] -------------------------------------------------------------- // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General public License for more details. // // You should have received a copy of the GNU General public License // along with this program. If not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2020 Natalia Portillo // ****************************************************************************/ using System.Diagnostics.CodeAnalysis; using System.IO; using Aaru.Console; namespace Aaru.Core { /// /// Abstracts a datafile with a block based interface /// [SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")] public class DataFile { FileStream dataFs; /// /// Opens, or create, a new file /// /// File public DataFile(string outputFile) { dataFs = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.ReadWrite); } /// /// Closes the file /// public void Close() { dataFs?.Close(); } /// /// Reads bytes at current position /// /// Array to place read data within /// Offset of where data will be read /// How many bytes to read /// How many bytes were read public int Read(byte[] array, int offset, int count) => dataFs.Read(array, offset, count); /// /// Seeks to the specified block /// /// Block to seek to /// Block size in bytes /// Position public long Seek(ulong block, ulong blockSize) => dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin); /// /// Seeks to specified byte position /// /// Byte position /// Where to count for position /// Position public long Seek(ulong offset, SeekOrigin origin) => dataFs.Seek((long)offset, origin); /// /// Seeks to specified byte position /// /// Byte position /// Where to count for position /// Position public long Seek(long offset, SeekOrigin origin) => dataFs.Seek(offset, origin); /// /// Writes data at current position /// /// Data public void Write(byte[] data) { Write(data, 0, data.Length); } /// /// Writes data at current position /// /// Data /// Offset of data from where to start taking data to write /// How many bytes to write public void Write(byte[] data, int offset, int count) { dataFs.Write(data, offset, count); } /// /// Writes data at specified block /// /// Data /// Block /// Bytes per block public void WriteAt(byte[] data, ulong block, uint blockSize) { WriteAt(data, block, blockSize, 0, data.Length); } /// /// Writes data at specified block /// /// Data /// Block /// Bytes per block /// Offset of data from where to start taking data to write /// How many bytes to write public void WriteAt(byte[] data, ulong block, uint blockSize, int offset, int count) { dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin); dataFs.Write(data, offset, count); } /// /// Current file position /// public long Position => dataFs.Position; /// /// Writes data to a newly created file /// /// Who asked the file to be written (class, plugin, etc.) /// Data to write /// First part of the file name /// Last part of the file name /// What is the data about? public static void WriteTo(string who, string outputPrefix, string outputSuffix, string whatWriting, byte[] data) { if(!string.IsNullOrEmpty(outputPrefix) && !string.IsNullOrEmpty(outputSuffix)) WriteTo(who, outputPrefix + outputSuffix, data, whatWriting); } /// /// Writes data to a newly created file /// /// Who asked the file to be written (class, plugin, etc.) /// Filename to create /// Data to write /// What is the data about? /// If set to true overwrites the file, does nothing otherwise public static void WriteTo(string who, string filename, byte[] data, string whatWriting = null, bool overwrite = false) { if(string.IsNullOrEmpty(filename)) return; if(File.Exists(filename)) if(overwrite) File.Delete(filename); else { DicConsole.ErrorWriteLine("Not overwriting file {0}", filename); return; } try { DicConsole.DebugWriteLine(who, "Writing " + whatWriting + " to {0}", filename); FileStream outputFs = new FileStream(filename, FileMode.CreateNew); outputFs.Write(data, 0, data.Length); outputFs.Close(); } catch { DicConsole.ErrorWriteLine("Unable to write file {0}", filename); } } } }