コード例 #1
0
        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);
                }
            }
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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;
                    }
                }
            }
        }
コード例 #6
0
        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));
            }
        }
コード例 #7
0
        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);
                    }
                }
            }
        }