예제 #1
0
        public static void Fill(this IStorage input, byte value, long offset, long count, IProgressReport progress = null)
        {
            const int threshold = 0x400;

            if (count > threshold)
            {
                input.FillLarge(value, offset, count, progress);
                return;
            }

            Span <byte> buf = stackalloc byte[(int)count];

            buf.Fill(value);

            input.Write(buf, offset);
        }
예제 #2
0
        private static void FillLarge(this IStorage input, byte value, long offset, long count, IProgressReport progress = null)
        {
            const int bufferSize = 0x4000;

            long remaining = count;

            if (remaining < 0)
            {
                throw new ArgumentException("Storage must have an explicit length");
            }
            progress?.SetTotal(remaining);

            long pos = offset;

            byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

            try
            {
                buffer.AsSpan(0, (int)Math.Min(remaining, bufferSize)).Fill(value);

                while (remaining > 0)
                {
                    int         toFill = (int)Math.Min(bufferSize, remaining);
                    Span <byte> buf    = buffer.AsSpan(0, toFill);

                    input.Write(buf, pos);

                    remaining -= toFill;
                    pos       += toFill;

                    progress?.ReportAdd(toFill);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }

            progress?.SetTotal(0);
        }
예제 #3
0
        public static void CopyTo(this IStorage input, IStorage output, IProgressReport progress = null)
        {
            const int bufferSize = 81920;
            long      remaining  = Math.Min(input.GetSize(), output.GetSize());

            if (remaining < 0)
            {
                throw new ArgumentException("Storage must have an explicit length");
            }
            progress?.SetTotal(remaining);

            long pos = 0;

            byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

            try
            {
                while (remaining > 0)
                {
                    int         toCopy = (int)Math.Min(bufferSize, remaining);
                    Span <byte> buf    = buffer.AsSpan(0, toCopy);
                    input.Read(buf, pos);
                    output.Write(buf, pos);

                    remaining -= toCopy;
                    pos       += toCopy;

                    progress?.ReportAdd(toCopy);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }

            progress?.SetTotal(0);
        }
예제 #4
0
 public static void Write(this IStorage storage, byte[] buffer, long offset, int count, int bufferOffset)
 {
     ValidateStorageParameters(buffer, offset, count, bufferOffset);
     storage.Write(buffer.AsSpan(bufferOffset, count), offset);
 }