private IEnumerable <DriveBlock> readAvailableContentBlocks() { lock (_entriesTableLock) { var operation = _synchronizer.EnqueueOperation(drive => { if (drive.Length < ByteHelper.GetLength <int>()) { return(new byte[0]); } var buffer = new byte[ByteHelper.GetLength <int>()]; drive.Position = drive.Length - ByteHelper.GetLength <int>() * 2;// read last 4 but 4 bytes drive.Read(buffer, 0, buffer.Length); var infoLength = BitConverter.ToInt32(buffer, 0); if (infoLength <= 0) { buffer = new byte[0]; } else { buffer = new byte[infoLength]; drive.Position = drive.Length - ByteHelper.GetLength <int>() * 2 - infoLength; drive.Read(buffer, 0, infoLength); } drive.SetLength(drive.Length - infoLength - ByteHelper.GetLength <int>() * 2); //get rid of available blocks info return(buffer); }, OperationType.FileTable); _synchronizer.EnqueueOperation(operation); var readBytes = operation.Task.Result; var processedBytes = 0; while (processedBytes < readBytes.Length) { var retv = AvailableDriveBlock.Read(readBytes.Skip(processedBytes).Take(AvailableDriveBlock.BytesBlockLength) .ToArray()); processedBytes += AvailableDriveBlock.BytesBlockLength; yield return(retv); } } }
private WriteOperation eraseEntry(BaseEntry entry) { lock (_entriesTableLock) { var position = entry.Position;//position of length bytes var mark = (byte)ServiceMarks.Proceed; _entryWriter.AddAvailableBlock(new DriveBlock { Position = position,//position where length bytes located Length = entry.Length }); var operation = _entryWriter.WriteTo(position + ByteHelper.GetLength <int>(), new[] { mark });// add 4 bytes to the position to rewrite block mark return(operation); } }
public static AvailableDriveBlock Read(byte[] block) { if (block.Length != BytesBlockLength) { throw new InvalidOperationException("Unable to read block"); } var position = 0; var blockPosition = BitConverter.ToInt64(block, position); position += ByteHelper.GetLength <long>(); var blockLength = BitConverter.ToInt32(block, position); var retv = new AvailableDriveBlock(blockPosition, blockLength); return(retv); }
private bool checkIfDriveIsFinalized() { return(_synchronizer.EnqueueOperation(drive => { if (drive.Length < ByteHelper.GetLength <int>()) { return false; } drive.Position = drive.Length - ByteHelper.GetLength <int>(); var buffer = new byte[ByteHelper.GetLength <int>()]; drive.Read(buffer, 0, buffer.Length); // read last 4 bytes var readInt = BitConverter.ToInt32(buffer, 0); return readInt == (int)ServiceBytes.DriveEnd; }, OperationType.FileTable).Task.Result); }
private IEnumerable <SectorInfo> readSectors() { lock (_sectorsLock) { var buffer = new byte[4096]; var reader = new SectorInfoRawReader(_synchronizer, _parameters); var lengthBytesLength = ByteHelper.GetLength <int>(); while (reader.CheckCanRead(lengthBytesLength)) { reader.Read(buffer, 0, lengthBytesLength).Task.Wait(); var sectorInfoEntryLength = BitConverter.ToInt32(buffer, 0); if (sectorInfoEntryLength == (int)ServiceBytes.End) { yield break; } buffer = new byte[sectorInfoEntryLength]; var position = reader.CurrentPosition; reader.Read(buffer, 0, sectorInfoEntryLength).Task.Wait(); var sector = SectorInfo.Read(buffer); _sectorInfosStartPositions[sector] = position; _sectorInfoWriter.SetCurrentPostion(reader.CurrentPosition); if (_sectorNextId <= sector.Id) { _sectorNextId = sector.Id + 1; } yield return(sector); if (sector.Length == 0) { yield break; } } } }
private WriteOperation writeSectorInfo(SectorInfo sectorInfo) { var bytes = sectorInfo.GetBytes(); lock (_sectorsLock) { if (!_sectorInfoWriter.CheckCanWrite(bytes.Length)) { throw new InvalidOperationException("Unable to write sector info"); } if (sectorInfo.Mark != ServiceMarks.EntriesSector) { return(_sectorInfoWriter.Write(bytes)); } var position = sectorInfo.StartPosition + sectorInfo.Length - ByteHelper.GetLength <int>(); var op = new FileTableOperation(drive => drive.Write(position, ServiceBytes.End), position); _synchronizer.EnqueueOperation(op); return(_sectorInfoWriter.Write(bytes)); } }
public IEnumerable <BaseEntry> ReadEntries() { lock (_entriesTableLock) { var buffer = new byte[1024 * 1024]; var breakReading = false; foreach (var sectorInfo in _sectorInfosStartPositions.Keys) { if (sectorInfo.Mark != ServiceMarks.EntriesSector) { continue; } var reader = new EntriesTableRawReader(_synchronizer, _parameters, sectorInfo.StartPosition); reader.Read(buffer, 0, ByteHelper.GetLength <int>()).Task.Wait(); var blockLength = BitConverter.ToInt32(buffer, 0); while (blockLength != (int)ServiceBytes.End && blockLength > 0) { var readBlockBytesCount = 0L; var block = new byte[blockLength]; var blockBodyPosition = reader.CurrentPosition; var blockStartPosition = blockBodyPosition - ByteHelper.GetLength <int>(); while (readBlockBytesCount < blockLength)//in case if block longer than buffer { var bytesToRead = buffer.Length > blockLength ? blockLength : buffer.Length; if (!reader.CheckCanRead(bytesToRead)) { breakReading = true; break; } var readBytesCount = reader.Read(buffer, 0, bytesToRead).Task.Result; Array.Copy(buffer, 0, block, readBlockBytesCount, readBlockBytesCount + readBytesCount); readBlockBytesCount += readBytesCount; } if (breakReading) { break; } var entryReader = EntryReaderFactory.Create(block, blockStartPosition);//it requires position of length bytes if (entryReader != null) { var entry = entryReader.GetEntry <BaseEntry>(); yield return(entry); } else { _entryWriter.AddAvailableBlock(new DriveBlock { Length = blockLength, Position = blockStartPosition //position where length bytes are located }); } _entryWriter.SetCurrentPosition(reader.CurrentPosition);//set position just after the last entry if (!reader.CheckCanRead(ByteHelper.GetLength <int>())) { break; } reader.Read(buffer, 0, ByteHelper.GetLength <int>()).Task.Wait(); blockLength = BitConverter.ToInt32(buffer, 0); } } } }