Exemplo n.º 1
0
        byte[] ReadDynamic(int count)
        {
            int positionInBuffer = 0;
            int bytesRemaining   = count;

            byte[] destBuffer = new byte[count];

            while (positionInBuffer < count)
            {
                byte[] data = new byte[0];
                if (Position < StaticDataLength)
                {
                    // Read a chunk from non-dynamic area, next iteration will read dynamic data
                    int maxReadLength = (int)(StaticDataLength - Position);
                    int length        = bytesRemaining > maxReadLength ? maxReadLength : bytesRemaining;
                    data = InternalRead(length);
                }
                else
                {
                    // Lookup block allocation table for real data offset
                    var   targetVirtualOffset = (ulong)(Position - StaticDataLength);
                    ulong blockNumber         = XvdMath.OffsetToBlockNumber(targetVirtualOffset);
                    long  inBlockOffset       = (long)XvdMath.InBlockOffset(targetVirtualOffset);
                    int   maxReadLength       = (int)(XvdFile.BLOCK_SIZE - inBlockOffset);
                    int   length = bytesRemaining > maxReadLength ? maxReadLength : bytesRemaining;

                    var targetPage = _xvdFile.ReadBat(blockNumber);
                    if (targetPage == XvdFile.INVALID_SECTOR)
                    {
                        data = new byte[length];
                        // Advance stream position cause we are not actually reading data
                        Position += length;
                    }
                    else
                    {
                        long targetPhysicalOffset = DynamicBaseOffset
                                                    + (long)XvdMath.PageNumberToOffset(targetPage)
                                                    + inBlockOffset;

                        data = InternalReadAbsolute(targetPhysicalOffset, length);
                    }
                }

                Array.Copy(data, 0, destBuffer, positionInBuffer, data.Length);
                positionInBuffer += data.Length;
                bytesRemaining   -= data.Length;
            }

            return(destBuffer);
        }