initial commit
This commit is contained in:
commit
1b60743303
274 changed files with 25866 additions and 0 deletions
211
ImageReader/Stream/DiscSectorStream.cs
Normal file
211
ImageReader/Stream/DiscSectorStream.cs
Normal file
|
@ -0,0 +1,211 @@
|
|||
// Decompiled with JetBrains decompiler
|
||||
// Type: ImageReader.Stream.DiscSectorStream
|
||||
// Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
||||
// MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B
|
||||
// Assembly location: ImageReader.dll
|
||||
|
||||
using ImageReader.DiscSectors;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace ImageReader.Stream
|
||||
{
|
||||
public class DiscSectorStream : System.IO.Stream
|
||||
{
|
||||
private System.IO.Stream sourceStream;
|
||||
private IDiscSector sector;
|
||||
private long absStartAddress;
|
||||
private long absEndAddress;
|
||||
private bool disposed;
|
||||
private bool disposeSourceStream;
|
||||
|
||||
public DiscSectorStream(
|
||||
System.IO.Stream source,
|
||||
IDiscSector sector,
|
||||
uint extent,
|
||||
uint size,
|
||||
bool autoReleaseSource)
|
||||
{
|
||||
this.disposed = false;
|
||||
if (size > (uint) int.MaxValue)
|
||||
throw new ArgumentException(string.Format("invalid size: files larger than {0} in size are not supported", (object) int.MaxValue), nameof (size));
|
||||
if (size > uint.MaxValue)
|
||||
throw new ArgumentException(string.Format("invalid size: a file on an ISO 9660 formatted disc cannot be larger than {0} in size", (object) uint.MaxValue), nameof (size));
|
||||
if (!source.CanSeek)
|
||||
throw new ArgumentException(string.Format("invalid base stream: only seekable streams are supported"), "baseStream");
|
||||
this.sector = sector;
|
||||
this.sourceStream = source;
|
||||
this.absStartAddress = (long) extent * (long) sector.Size;
|
||||
this.absEndAddress = this.absStartAddress + this.LogicalToPhysical((long) size);
|
||||
this.disposeSourceStream = autoReleaseSource;
|
||||
this.Seek(0L, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public DiscSectorStream(string isoFile, IDiscSector sector, uint extent, uint size)
|
||||
: this((System.IO.Stream) new FileStream(isoFile, FileMode.Open, FileAccess.Read, FileShare.Read), sector, extent, size, true)
|
||||
{
|
||||
}
|
||||
|
||||
public DiscSectorStream(System.IO.Stream source, IDiscSector sector)
|
||||
: this(source, sector, 0U, 0U, true)
|
||||
=> this.absEndAddress = this.absStartAddress + source.Length;
|
||||
|
||||
public override bool CanRead => !this.disposed && this.sourceStream.CanRead;
|
||||
|
||||
public override bool CanTimeout => this.disposed || this.sourceStream.CanTimeout;
|
||||
|
||||
public override bool CanSeek => !this.disposed && this.sourceStream.CanSeek;
|
||||
|
||||
public override bool CanWrite => !this.disposed && this.sourceStream.CanWrite;
|
||||
|
||||
public override long Length => this.PhysicalToLogical(this.absEndAddress - this.absStartAddress);
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get => this.PhysicalToLogical(this.sourceStream.Position - this.absStartAddress);
|
||||
set => this.Seek(value, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
long logical = this.PhysicalToLogical(this.sourceStream.Position - this.absStartAddress);
|
||||
long num1 = Math.Min((long) count, this.Length - logical);
|
||||
long sectors = num1 / (long) this.sector.DataLength;
|
||||
long num2 = num1 % (long) this.sector.DataLength;
|
||||
int num3 = 0;
|
||||
if ((long) (buffer.Length - offset) < sectors * (long) this.sector.DataLength + num2)
|
||||
throw new ArgumentOutOfRangeException("buffer is too small");
|
||||
if (sectors > 0L)
|
||||
num3 += this.ReadSector(buffer, offset, sectors);
|
||||
if (num2 > 0L)
|
||||
{
|
||||
if (this.sourceStream.Position % (long) this.sector.Size == 0L)
|
||||
this.sourceStream.Seek((long) this.sector.DataOffset, SeekOrigin.Current);
|
||||
num3 += this.sourceStream.Read(buffer, Convert.ToInt32(sectors * (long) this.sector.DataLength), (int) num2);
|
||||
}
|
||||
return num3;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer.Length - offset < count)
|
||||
throw new ArgumentOutOfRangeException("buffer is too small");
|
||||
long logical = this.PhysicalToLogical(this.sourceStream.Position - this.absStartAddress);
|
||||
long num1 = Math.Min((long) count, this.Length - logical);
|
||||
long sectors = num1 / (long) this.sector.DataLength;
|
||||
long num2 = num1 % (long) this.sector.DataLength;
|
||||
long num3 = 0;
|
||||
if (sectors > 0L)
|
||||
num3 += (long) this.WriteSector(buffer, offset, sectors);
|
||||
if (num2 <= 0L)
|
||||
return;
|
||||
if (sectors > 0L || this.sourceStream.Position == this.absStartAddress)
|
||||
this.sourceStream.Seek((long) this.sector.DataOffset, SeekOrigin.Current);
|
||||
this.sourceStream.Write(buffer, Convert.ToInt32(sectors * (long) this.sector.DataLength), (int) num2);
|
||||
long num4 = num3 + num2;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
long offset1;
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
if (offset < 0L || offset > this.Length)
|
||||
throw new ArgumentException(string.Format("must be in range of (0, {0}) when seeking from {1}", (object) this.Length, (object) SeekOrigin.Begin), nameof (offset));
|
||||
offset1 = this.absStartAddress + this.LogicalToPhysical(offset);
|
||||
break;
|
||||
case SeekOrigin.Current:
|
||||
long logical = this.PhysicalToLogical(this.sourceStream.Position - this.absStartAddress);
|
||||
if ((offset > 0L || logical + offset < 0L) && (offset < 0L || logical + offset > this.Length))
|
||||
throw new ArgumentException(string.Format("must be in range of (0, {0}) or (-{0}, 0) when seeking from {1}", (object) this.Length, (object) SeekOrigin.Current), nameof (offset));
|
||||
offset1 = this.LogicalToPhysical(logical + offset) - (this.sourceStream.Position - this.absStartAddress);
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
if (offset > 0L || this.Length + offset < 0L)
|
||||
throw new ArgumentException(string.Format("must be in range of (-{0}, 0) when seeking from {1}", (object) this.Length, (object) SeekOrigin.End), nameof (offset));
|
||||
offset1 = this.absStartAddress + this.LogicalToPhysical(this.Length + offset);
|
||||
origin = SeekOrigin.Begin;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
return this.PhysicalToLogical(this.sourceStream.Seek(offset1, origin) - this.absStartAddress);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
if (this.sourceStream == null || !this.disposeSourceStream)
|
||||
return;
|
||||
this.sourceStream.Close();
|
||||
}
|
||||
|
||||
public override void SetLength(long value) => throw new NotSupportedException();
|
||||
|
||||
public override void WriteByte(byte value) => throw new NotSupportedException();
|
||||
|
||||
public override void Flush() => throw new NotSupportedException();
|
||||
|
||||
private long LogicalToPhysical(long logicalAddress)
|
||||
{
|
||||
long num1 = logicalAddress / (long) this.sector.DataLength;
|
||||
long num2 = logicalAddress % (long) this.sector.DataLength;
|
||||
if (num2 != 0L)
|
||||
num2 += (long) this.sector.DataOffset;
|
||||
return num1 * (long) this.sector.Size + num2;
|
||||
}
|
||||
|
||||
private long PhysicalToLogical(long physicalAddress)
|
||||
{
|
||||
long num1 = physicalAddress % (long) this.sector.Size;
|
||||
long num2 = physicalAddress / (long) this.sector.Size;
|
||||
if (num1 != 0L)
|
||||
{
|
||||
string.Format("the specified absolute address {0} is out of the stream's logical range", (object) physicalAddress);
|
||||
num1 -= (long) this.sector.DataOffset;
|
||||
}
|
||||
return num2 * (long) this.sector.DataLength + num1;
|
||||
}
|
||||
|
||||
private int ReadSector(byte[] buffer, int offset, long sectors)
|
||||
{
|
||||
int num = 0;
|
||||
byte[] buffer1 = new byte[this.sector.Size];
|
||||
for (int index = 0; (long) index < sectors; ++index)
|
||||
{
|
||||
this.sourceStream.Read(buffer1, 0, buffer1.Length);
|
||||
Buffer.BlockCopy((Array) buffer1, this.sector.DataOffset, (Array) buffer, offset + index * this.sector.DataLength, this.sector.DataLength);
|
||||
num += this.sector.DataLength;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private int WriteSector(byte[] buffer, int offset, long sectors)
|
||||
{
|
||||
int num = 0;
|
||||
for (int index = 0; (long) index < sectors; ++index)
|
||||
{
|
||||
this.sourceStream.Seek((long) this.sector.DataOffset, SeekOrigin.Current);
|
||||
this.sourceStream.Write(buffer, offset + index * this.sector.DataLength, this.sector.DataLength);
|
||||
this.sourceStream.Seek((long) (this.sector.Size - this.sector.DataOffset), SeekOrigin.Current);
|
||||
num += this.sector.DataLength;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public new virtual void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize((object) this);
|
||||
}
|
||||
|
||||
protected new virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (this.disposed)
|
||||
return;
|
||||
if (disposing)
|
||||
this.Close();
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue