Example #1
0
        public override int Read(long pos, byte[] buffer, int offset, int count)
        {
            int totalRead = 0;

            int limitedCount = (int)Math.Min(count, Math.Max(0, Capacity - pos));

            while (totalRead < limitedCount)
            {
                long             extentLogicalStart;
                ExtentDescriptor extent            = FindExtent(pos, out extentLogicalStart);
                long             extentStreamStart = extent.StartBlock * (long)_context.MasterDirectoryBlock.BlockSize;
                long             extentSize        = extent.BlockCount * (long)_context.MasterDirectoryBlock.BlockSize;

                long extentOffset = pos + totalRead - extentLogicalStart;
                int  toRead       = (int)Math.Min(limitedCount - totalRead, extentSize - extentOffset);

                // Remaining in extent can create a situation where amount to read is zero, and that appears
                // to be OK, just need to exit thie while loop to avoid infinite loop.
                if (toRead == 0)
                {
                    break;
                }

                Stream volStream = _context.VolumeStream;
                volStream.Position = extentStreamStart + extentOffset;
                int numRead = volStream.Read(buffer, offset + totalRead, toRead);

                totalRead += numRead;
            }

            return(totalRead);
        }
Example #2
0
        private ExtentDescriptor FindExtent(long pos, out long extentLogicalStart)
        {
            uint blocksSeen = 0;
            uint block      = (uint)(pos / _context.MasterDirectoryBlock.BlockSize);

            for (int i = 0; i < _baseData.Extents.Length; ++i)
            {
                if (blocksSeen + _baseData.Extents[i].BlockCount > block)
                {
                    extentLogicalStart = blocksSeen * (long)_context.MasterDirectoryBlock.BlockSize;
                    return(_baseData.Extents[i]);
                }

                blocksSeen += _baseData.Extents[i].BlockCount;
            }

            while (blocksSeen < _baseData.TotalBlocks)
            {
                byte[] extentData = _context.ExtentsOverflow.Find(new ExtentKey(_cnid, blocksSeen, false));

                if (extentData != null)
                {
                    int extentDescriptorCount = extentData.Length / 8;
                    for (int a = 0; a < extentDescriptorCount; a++)
                    {
                        ExtentDescriptor extentDescriptor = new ExtentDescriptor();
                        int bytesRead = extentDescriptor.ReadFrom(extentData, a * 8);

                        if (blocksSeen + extentDescriptor.BlockCount > block)
                        {
                            extentLogicalStart = blocksSeen * (long)_context.MasterDirectoryBlock.BlockSize;
                            return(extentDescriptor);
                        }

                        blocksSeen += extentDescriptor.BlockCount;
                    }
                }
                else
                {
                    throw new IOException("Missing extent from extent overflow file: cnid=" + _cnid + ", blocksSeen=" +
                                          blocksSeen);
                }
            }

            throw new InvalidOperationException("Requested file fragment beyond EOF");
        }