protected override Result WriteImpl(long offset, ReadOnlySpan <byte> source)
        {
            var iterator = new AllocationTableIterator(Fat, InitialBlock);

            long inPos     = offset;
            int  outPos    = 0;
            int  remaining = source.Length;

            while (remaining > 0)
            {
                int blockNum = (int)(inPos / BlockSize);
                iterator.Seek(blockNum);

                int  segmentPos     = (int)(inPos - (long)iterator.VirtualBlock * BlockSize);
                long physicalOffset = iterator.PhysicalBlock * BlockSize + segmentPos;

                int remainingInSegment = iterator.CurrentSegmentSize * BlockSize - segmentPos;
                int bytesToWrite       = Math.Min(remaining, remainingInSegment);

                Result rc = BaseStorage.Write(physicalOffset, source.Slice(outPos, bytesToWrite));
                if (rc.IsFailure())
                {
                    return(rc);
                }

                outPos    += bytesToWrite;
                inPos     += bytesToWrite;
                remaining -= bytesToWrite;
            }

            return(Result.Success);
        }
Example #2
0
        public static IEnumerable <(int block, int length)> DumpChain(this AllocationTable table, int startBlock)
        {
            var iterator = new AllocationTableIterator(table, startBlock);

            do
            {
                yield return(iterator.PhysicalBlock, iterator.CurrentSegmentSize);
            } while (iterator.MoveNext());
        }
Example #3
0
        protected override Result DoRead(long offset, Span <byte> destination)
        {
            var iterator = new AllocationTableIterator(Fat, InitialBlock);

            long inPos     = offset;
            int  outPos    = 0;
            int  remaining = destination.Length;

            while (remaining > 0)
            {
                int blockNum = (int)(inPos / BlockSize);

                if (!iterator.Seek(blockNum))
                {
                    return(ResultFs.InvalidAllocationTableOffset.Log());
                }

                int  segmentPos     = (int)(inPos - (long)iterator.VirtualBlock * BlockSize);
                long physicalOffset = iterator.PhysicalBlock * BlockSize + segmentPos;

                int remainingInSegment = iterator.CurrentSegmentSize * BlockSize - segmentPos;
                int bytesToRead        = Math.Min(remaining, remainingInSegment);

                Result rc = BaseStorage.Read(physicalOffset, destination.Slice(outPos, bytesToRead));
                if (rc.IsFailure())
                {
                    return(rc);
                }

                outPos    += bytesToRead;
                inPos     += bytesToRead;
                remaining -= bytesToRead;
            }

            return(Result.Success);
        }