コード例 #1
0
        private static void CopyStream(IEnumerator <Step> sourceWalker, IEnumerator <Step> targetWalker, CopyInfo copyInfo)
        {
            /* initialize source walker */
            var sourceStream    = default(Stream);
            var lastSourceChunk = default(ulong[]);

            /* initialize target walker */
            var targetBuffer    = default(Memory <byte>);
            var lastTargetChunk = default(ulong[]);
            var currentTarget   = default(Memory <byte>);

            /* walk until end */
            while (sourceWalker.MoveNext())
            {
                /* load next source stream */
                var sourceStep = sourceWalker.Current;

                if (sourceStream is null /* if stream not assigned yet */ ||
                    !sourceStep.Chunk.SequenceEqual(lastSourceChunk) /* or the chunk has changed */)
                {
                    sourceStream    = copyInfo.GetSourceStream(sourceStep.Chunk);
                    lastSourceChunk = sourceStep.Chunk;
                }

                sourceStream?.Seek((int)sourceStep.Offset * copyInfo.TypeSize, SeekOrigin.Begin);        // corresponds to
                var currentLength = (int)sourceStep.Length * copyInfo.TypeSize;                          // sourceBuffer.Slice()

                while (currentLength > 0)
                {
                    /* load next target buffer */
                    if (currentTarget.Length == 0)
                    {
                        var success    = targetWalker.MoveNext();
                        var targetStep = targetWalker.Current;

                        if (!success || targetStep.Length == 0)
                        {
                            throw new UriFormatException("The target walker stopped early.");
                        }

                        if (targetBuffer.Length == 0 /* if buffer not assigned yet */ ||
                            !targetStep.Chunk.SequenceEqual(lastTargetChunk) /* or the chunk has changed */)
                        {
                            targetBuffer    = copyInfo.GetTargetBuffer(targetStep.Chunk);
                            lastTargetChunk = targetStep.Chunk;
                        }

                        currentTarget = targetBuffer.Slice(
                            (int)targetStep.Offset * copyInfo.TypeSize,
                            (int)targetStep.Length * copyInfo.TypeSize);
                    }

                    /* copy */
                    var length = Math.Min(currentLength, currentTarget.Length);
                    sourceStream?.Read(currentTarget.Slice(0, length).Span);                             // corresponds to span.CopyTo

                    sourceStream?.Seek((int)sourceStep.Offset * copyInfo.TypeSize, SeekOrigin.Begin);    // corresponds to
                    currentLength -= (int)sourceStep.Length * copyInfo.TypeSize;                         // sourceBuffer.Slice()

                    currentTarget = currentTarget.Slice(length);
                }
            }
        }
コード例 #2
0
        private static void CopyMemory(IEnumerator <Step> sourceWalker, IEnumerator <Step> targetWalker, CopyInfo copyInfo)
        {
            /* initialize source walker */
            var sourceBuffer    = default(Memory <byte>);
            var lastSourceChunk = default(ulong[]);

            /* initialize target walker */
            var targetBuffer    = default(Memory <byte>);
            var lastTargetChunk = default(ulong[]);
            var currentTarget   = default(Memory <byte>);

            /* walk until end */
            while (sourceWalker.MoveNext())
            {
                /* load next source buffer */
                var sourceStep = sourceWalker.Current;

                if (sourceBuffer.Length == 0 /* if buffer not assigned yet */ ||
                    !sourceStep.Chunk.SequenceEqual(lastSourceChunk) /* or the chunk has changed */)
                {
                    sourceBuffer    = copyInfo.GetSourceBuffer(sourceStep.Chunk);
                    lastSourceChunk = sourceStep.Chunk;
                }

                var currentSource = sourceBuffer.Slice(
                    (int)sourceStep.Offset * copyInfo.TypeSize,
                    (int)sourceStep.Length * copyInfo.TypeSize);

                while (currentSource.Length > 0)
                {
                    /* load next target buffer */
                    if (currentTarget.Length == 0)
                    {
                        var success    = targetWalker.MoveNext();
                        var targetStep = targetWalker.Current;

                        if (!success || targetStep.Length == 0)
                        {
                            throw new UriFormatException("The target walker stopped early.");
                        }

                        if (targetBuffer.Length == 0 /* if buffer not assigned yet */ ||
                            !targetStep.Chunk.SequenceEqual(lastTargetChunk) /* or the chunk has changed */)
                        {
                            targetBuffer    = copyInfo.GetTargetBuffer(targetStep.Chunk);
                            lastTargetChunk = targetStep.Chunk;
                        }

                        currentTarget = targetBuffer.Slice(
                            (int)targetStep.Offset * copyInfo.TypeSize,
                            (int)targetStep.Length * copyInfo.TypeSize);
                    }

                    /* copy */
                    var length = Math.Min(currentSource.Length, currentTarget.Length);

                    currentSource
                    .Slice(0, length)
                    .CopyTo(currentTarget);

                    currentSource = currentSource.Slice(length);
                    currentTarget = currentTarget.Slice(length);
                }
            }
        }