示例#1
0
        public DeltaFragment(IStorage delta)
        {
            Delta = delta;

            if (Delta.GetSize() < 0x40)
            {
                throw new InvalidDataException("Delta file is too small.");
            }

            Header = new DeltaFragmentHeader(delta.AsFile(OpenMode.Read));

            if (Header.Magic != Ndv0Magic)
            {
                throw new InvalidDataException("NDV0 magic value is missing.");
            }

            long fragmentSize = Header.FragmentHeaderSize + Header.FragmentBodySize;

            if (Delta.GetSize() < fragmentSize)
            {
                throw new InvalidDataException($"Delta file is smaller than the header indicates. (0x{fragmentSize} bytes)");
            }

            ParseDeltaStructure();
        }
示例#2
0
        public SectorStorage(IStorage baseStorage, int sectorSize, bool leaveOpen)
        {
            BaseStorage = baseStorage;
            SectorSize  = sectorSize;
            SectorCount = (int)Util.DivideByRoundUp(BaseStorage.GetSize(), SectorSize);
            _length     = BaseStorage.GetSize();

            if (!leaveOpen)
            {
                ToDispose.Add(BaseStorage);
            }
        }
示例#3
0
 public static void WriteAllBytes(this IStorage input, string filename, IProgressReport progress = null)
 {
     using (var outFile = new FileStream(filename, FileMode.Create, FileAccess.Write))
     {
         input.CopyToStream(outFile, input.GetSize(), progress);
     }
 }
示例#4
0
        public void SetBaseStorage(IStorage baseStorage)
        {
            Original = baseStorage;

            if (Original.GetSize() != Header.OriginalSize)
            {
                throw new InvalidDataException($"Original file size does not match the size in the delta header. (0x{Header.OriginalSize} bytes)");
            }
        }
示例#5
0
        public StorageStream(IStorage baseStorage, FileAccess access, bool leaveOpen)
        {
            BaseStorage = baseStorage;
            LeaveOpen   = leaveOpen;
            _length     = baseStorage.GetSize();

            CanRead  = access.HasFlag(FileAccess.Read);
            CanWrite = access.HasFlag(FileAccess.Write);
        }
示例#6
0
        public static IStorage Slice(this IStorage storage, long start)
        {
            long length = storage.GetSize();

            if (length == -1)
            {
                return(storage.Slice(start, length));
            }

            return(storage.Slice(start, length - start));
        }
示例#7
0
        public static byte[] ToArray(this IStorage storage)
        {
            if (storage == null)
            {
                return(new byte[0]);
            }

            var arr = new byte[storage.GetSize()];

            storage.CopyTo(new MemoryStorage(arr));
            return(arr);
        }
示例#8
0
        public static T[] ToArray <T>(this IStorage storage) where T : unmanaged
        {
            if (storage == null)
            {
                return(new T[0]);
            }

            var         arr  = new T[storage.GetSize() / Marshal.SizeOf <T>()];
            Span <byte> dest = MemoryMarshal.Cast <T, byte>(arr.AsSpan());

            storage.Read(dest, 0);
            return(arr);
        }
示例#9
0
        public CachedStorage(IStorage baseStorage, int blockSize, int cacheSize, bool leaveOpen)
        {
            BaseStorage = baseStorage;
            BlockSize   = blockSize;
            _length     = BaseStorage.GetSize();

            if (!leaveOpen)
            {
                ToDispose.Add(BaseStorage);
            }

            for (int i = 0; i < cacheSize; i++)
            {
                var block = new CacheBlock {
                    Buffer = new byte[blockSize], Index = -1
                };
                Blocks.AddLast(block);
            }
        }
示例#10
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);
        }
示例#11
0
 // Todo: Move out of SubStorage
 public static IStorage AsReadOnly(this IStorage storage, bool leaveOpen)
 {
     return(new SubStorage(storage, 0, storage.GetSize(), leaveOpen, FileAccess.Read));
 }
示例#12
0
 public static void CopyToStream(this IStorage input, Stream output) => CopyToStream(input, output, input.GetSize());
示例#13
0
 public static void Fill(this IStorage input, byte value, IProgressReport progress = null)
 {
     input.Fill(value, 0, input.GetSize(), progress);
 }