public SimplifiedSubFileStreamIoSession(FileStream stream, SubFileHeader subFile, FileHeaderBlock header) { if (stream is null) { throw new ArgumentNullException("stream"); } if (subFile is null) { throw new ArgumentNullException("subFile"); } if (header is null) { throw new ArgumentNullException("header"); } if (subFile.DirectBlock == 0) { throw new Exception("Must assign subFile.DirectBlock"); } m_stream = stream; m_header = header; m_blockSize = header.BlockSize; m_subFile = subFile; m_memory = new Memory(m_blockSize); m_buffer = new byte[m_blockSize]; m_currentPhysicalBlock = -1; m_blockDataLength = m_blockSize - FileStructureConstants.BlockFooterLength; }
/// <summary> /// Creates an SimplifiedSubFileStream /// </summary> /// <param name="stream">The location to read from.</param> /// <param name="subFile">The file to read.</param> /// <param name="fileHeaderBlock">The FileAllocationTable</param> internal SimplifiedSubFileStream(FileStream stream, SubFileHeader subFile, FileHeaderBlock fileHeaderBlock) { if (stream is null) { throw new ArgumentNullException("stream"); } if (subFile is null) { throw new ArgumentNullException("subFile"); } if (fileHeaderBlock is null) { throw new ArgumentNullException("fileHeaderBlock"); } if (subFile.DirectBlock == 0) { throw new Exception("Must assign subFile.DirectBlock"); } if (fileHeaderBlock.IsReadOnly) { throw new ArgumentException("This parameter cannot be read only when opening for writing", "fileHeaderBlock"); } if (subFile.IsReadOnly) { throw new ArgumentException("This parameter cannot be read only when opening for writing", "subFile"); } m_blockSize = fileHeaderBlock.BlockSize; m_stream = stream; m_subFile = subFile; m_fileHeaderBlock = fileHeaderBlock; }
/// <summary> /// Creates a new instance of this class. /// </summary> /// <param name="ioSessions">IoSessions to use to read from this disk</param> public IndexParser(SubFileDiskIoSessionPool ioSessions) : base(ioSessions.Header.BlockSize) { m_subFile = ioSessions.File; m_ioSessions = ioSessions; m_oldFirstOffset = -1; }
/// <summary> /// Creates a new file on the file system and returns the <see cref="SubFileHeader"/> associated with the new file. /// </summary> /// <param name="fileName">Represents the nature of the data that will be stored in this file.</param> /// <returns></returns> /// <remarks>A file system only supports 64 files. This is a fundamental limitation and cannot be changed easily.</remarks> public SubFileHeader CreateNewFile(SubFileName fileName) { base.TestForEditable(); if (!CanWrite) { throw new Exception("Writing to this file type is not supported"); } if (IsReadOnly) { throw new Exception("File is read only"); } if (m_files.Count >= 64) { throw new OverflowException("Only 64 files per file system is supported"); } if (ContainsSubFile(fileName)) { throw new DuplicateNameException("Name already exists"); } SubFileHeader node = new SubFileHeader(m_nextFileId, fileName, isImmutable: false, isSimplified: IsSimplifiedFileFormat); m_nextFileId++; m_files.Add(node); return(node); }
/// <summary> /// Opens a ArchiveFileStream that can be used to read/write to the file passed to this function. /// </summary> /// <returns></returns> public SubFileStream OpenFile(SubFileName fileName) { for (int x = 0; x < m_fileHeaderBlock.Files.Count; x++) { SubFileHeader file = m_fileHeaderBlock.Files[x]; if (file.FileName == fileName) { return(OpenFile(x)); } } throw new Exception("File does not exist"); }
/// <summary> /// Creates this file with the following data. /// </summary> /// <param name="diskIo"></param> /// <param name="header"></param> /// <param name="file"></param> /// <param name="isReadOnly"></param> public SubFileDiskIoSessionPool(DiskIo diskIo, FileHeaderBlock header, SubFileHeader file, bool isReadOnly) { LastReadonlyBlock = diskIo.LastCommittedHeader.LastAllocatedBlock; File = file; Header = header; IsReadOnly = isReadOnly; SourceData = diskIo.CreateDiskIoSession(header, file); SourceIndex = diskIo.CreateDiskIoSession(header, file); if (!isReadOnly) { DestinationData = diskIo.CreateDiskIoSession(header, file); DestinationIndex = diskIo.CreateDiskIoSession(header, file); } }
/// <summary> /// Creates and Opens a new file on the current file system. /// </summary> /// <returns></returns> public ISupportsBinaryStream CreateFile(SubFileName fileName) { if (m_disposed) { throw new ObjectDisposedException(GetType().FullName); } CloseCurrentFile(); SubFileHeader subFile = m_fileHeaderBlock.CreateNewFile(fileName); subFile.DirectBlock = m_fileHeaderBlock.LastAllocatedBlock + 1; m_subFileStream = new SimplifiedSubFileStream(m_stream, subFile, m_fileHeaderBlock); return(m_subFileStream); }
/// <summary> /// Creates an SubFileStream /// </summary> /// <param name="dataReader">The location to read from.</param> /// <param name="subFile">The file to read.</param> /// <param name="fileHeaderBlock">The FileAllocationTable</param> /// <param name="isReadOnly">Determines if the stream allows editing.</param> internal SubFileStream(DiskIo dataReader, SubFileHeader subFile, FileHeaderBlock fileHeaderBlock, bool isReadOnly) { if (dataReader == null) { throw new ArgumentNullException("dataReader"); } if (subFile == null) { throw new ArgumentNullException("subFile"); } if (fileHeaderBlock == null) { throw new ArgumentNullException("subFile"); } if (!isReadOnly) { if (dataReader.IsReadOnly) { throw new ArgumentException("This parameter cannot be read only when opening for writing", "dataReader"); } if (fileHeaderBlock.IsReadOnly) { throw new ArgumentException("This parameter cannot be read only when opening for writing", "fileHeaderBlock"); } if (subFile.IsReadOnly) { throw new ArgumentException("This parameter cannot be read only when opening for writing", "subFile"); } } if (isReadOnly) { if (!fileHeaderBlock.IsReadOnly) { throw new ArgumentException("This parameter must be read only when opening for reading", "fileHeaderBlock"); } if (!subFile.IsReadOnly) { throw new ArgumentException("This parameter must be read only when opening for reading", "subFile"); } } m_blockSize = dataReader.BlockSize; m_dataReader = dataReader; m_subFile = subFile; m_fileHeaderBlock = fileHeaderBlock; m_isReadOnly = isReadOnly; }
/// <summary> /// Creates a <see cref="ShadowCopyAllocator"/> that is used make shadow copies of blocks. /// </summary> /// <param name="ioSessions"></param> public ShadowCopyAllocator(SubFileDiskIoSessionPool ioSessions) : base(ioSessions) { if (ioSessions == null) { throw new ArgumentNullException("ioSessions"); } if (ioSessions.IsReadOnly) { throw new ArgumentException("DataReader is read only", "ioSessions"); } m_lastReadOnlyBlock = ioSessions.LastReadonlyBlock; m_fileHeaderBlock = ioSessions.Header; m_subFileHeader = ioSessions.File; m_ioSessions = ioSessions; }
/// <summary> /// Opens a ArchiveFileStream that can be used to read/write to the file passed to this function. /// </summary> /// <returns></returns> public SubFileStream OpenFile(SubFileName fileName) { if (m_disposed) { throw new ObjectDisposedException(GetType().FullName); } for (int x = 0; x < Files.Count; x++) { SubFileHeader file = Files[x]; if (file.FileName == fileName) { return(OpenFile(x)); } } throw new Exception("File does not exist"); }
/// <summary> /// Opens a ArchiveFileStream that can be used to read/write to the file passed to this function. /// </summary> /// <param name="fileIndex">The index of the file to open.</param> /// <returns></returns> public SubFileStream OpenFile(int fileIndex) { if (m_disposed) { throw new ObjectDisposedException(GetType().FullName); } if (fileIndex < 0 || fileIndex >= m_fileHeaderBlock.Files.Count) { throw new ArgumentOutOfRangeException("fileIndex", "The file index provided could not be found in the header."); } SubFileHeader subFile = m_fileHeaderBlock.Files[fileIndex]; SubFileStream fileStream = new SubFileStream(m_dataReader, subFile, m_fileHeaderBlock, isReadOnly: false); m_openedFiles.Add(fileStream); return(fileStream); }