Move all interfaces, extents, interop and metadata to DiscImageChef.CommonTypes.

This commit is contained in:
2018-06-25 19:08:16 +01:00
parent 7187ce2e36
commit 2af10e0a0b
34 changed files with 9254 additions and 0 deletions

View File

@@ -46,10 +46,46 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CICMMetadata\dotnet\cicm.cs">
<Link>Metadata/cicm.cs</Link>
</Compile>
<Compile Include="Enums\Images.cs" />
<Compile Include="Exceptions\Images.cs" />
<Compile Include="Extents\ExtentsByte.cs" />
<Compile Include="Extents\ExtentsConverter.cs" />
<Compile Include="Extents\ExtentsInt.cs" />
<Compile Include="Extents\ExtentsLong.cs" />
<Compile Include="Extents\ExtentsSByte.cs" />
<Compile Include="Extents\ExtentsShort.cs" />
<Compile Include="Extents\ExtentsUInt.cs" />
<Compile Include="Extents\ExtentsULong.cs" />
<Compile Include="Extents\ExtentsUShort.cs" />
<Compile Include="Filters.cs" />
<Compile Include="Geometry.cs" />
<Compile Include="Interfaces\IChecksum.cs" />
<Compile Include="Interfaces\IFilesystem.cs" />
<Compile Include="Interfaces\IFilter.cs" />
<Compile Include="Interfaces\IFloppyImage.cs" />
<Compile Include="Interfaces\IMediaImage.cs" />
<Compile Include="Interfaces\IPartition.cs" />
<Compile Include="Interfaces\IReadOnlyFilesystem.cs" />
<Compile Include="Interfaces\IWritableFloppyImage.cs" />
<Compile Include="Interfaces\IWritableImage.cs" />
<Compile Include="Interop\DetectOS.cs" />
<Compile Include="Interop\PlatformID.cs" />
<Compile Include="Interop\Version.cs" />
<Compile Include="Metadata\DeviceReport.cs" />
<Compile Include="Metadata\Dimensions.cs" />
<Compile Include="Metadata\MediaType.cs" />
<Compile Include="Metadata\Resume.cs" />
<Compile Include="Metadata\Statistics.cs" />
<Compile Include="Metadata\Version.cs" />
<Compile Include="Partition.cs" />
<Compile Include="MediaType.cs" />
<Compile Include="MediaTypeFromSCSI.cs" />
<Compile Include="PluginBase.cs" />
<Compile Include="Structs\Filesystems.cs" />
<Compile Include="Structs\Images.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\LICENSE.LGPL">
@@ -60,6 +96,14 @@
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.2.2-beta" />
</ItemGroup>
<ItemGroup>
<Content Include="..\LICENSE.MIT">
<Link>LICENSE.MIT</Link>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DiscImageChef.Decoders\DiscImageChef.Decoders.csproj" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>

356
Enums/Images.cs Normal file
View File

@@ -0,0 +1,356 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Enums.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines enumerations to be used by disc image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
namespace DiscImageChef.CommonTypes.Enums
{
/// <summary>
/// Track (as partitioning element) types.
/// </summary>
public enum TrackType : byte
{
/// <summary>Audio track</summary>
Audio = 0,
/// <summary>Data track (not any of the below defined ones)</summary>
Data = 1,
/// <summary>Data track, compact disc mode 1</summary>
CdMode1 = 2,
/// <summary>Data track, compact disc mode 2, formless</summary>
CdMode2Formless = 3,
/// <summary>Data track, compact disc mode 2, form 1</summary>
CdMode2Form1 = 4,
/// <summary>Data track, compact disc mode 2, form 2</summary>
CdMode2Form2 = 5
}
/// <summary>
/// Type of subchannel in track
/// </summary>
public enum TrackSubchannelType
{
/// <summary>
/// Track does not has subchannel dumped, or it's not a CD
/// </summary>
None,
/// <summary>
/// Subchannel is packed and error corrected
/// </summary>
Packed,
/// <summary>
/// Subchannel is interleaved
/// </summary>
Raw,
/// <summary>
/// Subchannel is packed and comes interleaved with main channel in same file
/// </summary>
PackedInterleaved,
/// <summary>
/// Subchannel is interleaved and comes interleaved with main channel in same file
/// </summary>
RawInterleaved,
/// <summary>
/// Only Q subchannel is stored as 16 bytes
/// </summary>
Q16,
/// <summary>
/// Only Q subchannel is stored as 16 bytes and comes interleaved with main channel in same file
/// </summary>
Q16Interleaved
}
/// <summary>
/// Metadata present for each sector (aka, "tag").
/// </summary>
public enum SectorTagType
{
/// <summary>Apple's GCR sector tags, 12 bytes</summary>
AppleSectorTag,
/// <summary>Sync frame from CD sector, 12 bytes</summary>
CdSectorSync,
/// <summary>CD sector header, 4 bytes</summary>
CdSectorHeader,
/// <summary>CD mode 2 sector subheader</summary>
CdSectorSubHeader,
/// <summary>CD sector EDC, 4 bytes</summary>
CdSectorEdc,
/// <summary>CD sector ECC P, 172 bytes</summary>
CdSectorEccP,
/// <summary>CD sector ECC Q, 104 bytes</summary>
CdSectorEccQ,
/// <summary>CD sector ECC (P and Q), 276 bytes</summary>
CdSectorEcc,
/// <summary>CD sector subchannel, 96 bytes</summary>
CdSectorSubchannel,
/// <summary>CD track ISRC, string, 12 bytes</summary>
CdTrackIsrc,
/// <summary>CD track text, string, 13 bytes</summary>
CdTrackText,
/// <summary>CD track flags, 1 byte</summary>
CdTrackFlags,
/// <summary>DVD sector copyright information</summary>
DvdCmi,
/// <summary>Floppy address mark (contents depend on underlying floppy format)</summary>
FloppyAddressMark
}
/// <summary>
/// Metadata present for each media.
/// </summary>
public enum MediaTagType
{
/// <summary>CD table of contents</summary>
CD_TOC,
/// <summary>CD session information</summary>
CD_SessionInfo,
/// <summary>CD full table of contents</summary>
CD_FullTOC,
/// <summary>CD PMA</summary>
CD_PMA,
/// <summary>CD Adress-Time-In-Pregroove</summary>
CD_ATIP,
/// <summary>CD-Text</summary>
CD_TEXT,
/// <summary>CD Media Catalogue Number</summary>
CD_MCN,
/// <summary>DVD/HD DVD Physical Format Information</summary>
DVD_PFI,
/// <summary>DVD Lead-in Copyright Management Information</summary>
DVD_CMI,
/// <summary>DVD disc key</summary>
DVD_DiscKey,
/// <summary>DVD/HD DVD Burst Cutting Area</summary>
DVD_BCA,
/// <summary>DVD/HD DVD Lead-in Disc Manufacturer Information</summary>
DVD_DMI,
/// <summary>Media identifier</summary>
DVD_MediaIdentifier,
/// <summary>Media key block</summary>
DVD_MKB,
/// <summary>DVD-RAM/HD DVD-RAM DDS information</summary>
DVDRAM_DDS,
/// <summary>DVD-RAM/HD DVD-RAM Medium status</summary>
DVDRAM_MediumStatus,
/// <summary>DVD-RAM/HD DVD-RAM Spare area information</summary>
DVDRAM_SpareArea,
/// <summary>DVD-R/-RW/HD DVD-R RMD in last border-out</summary>
DVDR_RMD,
/// <summary>Pre-recorded information from DVD-R/-RW lead-in</summary>
DVDR_PreRecordedInfo,
/// <summary>DVD-R/-RW/HD DVD-R media identifier</summary>
DVDR_MediaIdentifier,
/// <summary>DVD-R/-RW/HD DVD-R physical format information</summary>
DVDR_PFI,
/// <summary>ADIP information</summary>
DVD_ADIP,
/// <summary>HD DVD Lead-in copyright protection information</summary>
HDDVD_CPI,
/// <summary>HD DVD-R Medium Status</summary>
HDDVD_MediumStatus,
/// <summary>DVD+/-R DL Layer capacity</summary>
DVDDL_LayerCapacity,
/// <summary>DVD-R DL Middle Zone start address</summary>
DVDDL_MiddleZoneAddress,
/// <summary>DVD-R DL Jump Interval Size</summary>
DVDDL_JumpIntervalSize,
/// <summary>DVD-R DL Start LBA of the manual layer jump</summary>
DVDDL_ManualLayerJumpLBA,
/// <summary>Blu-ray Disc Information</summary>
BD_DI,
/// <summary>Blu-ray Burst Cutting Area</summary>
BD_BCA,
/// <summary>Blu-ray Disc Definition Structure</summary>
BD_DDS,
/// <summary>Blu-ray Cartridge Status</summary>
BD_CartridgeStatus,
/// <summary>Blu-ray Status of Spare Area</summary>
BD_SpareArea,
/// <summary>AACS volume identifier</summary>
AACS_VolumeIdentifier,
/// <summary>AACS pre-recorded media serial number</summary>
AACS_SerialNumber,
/// <summary>AACS media identifier</summary>
AACS_MediaIdentifier,
/// <summary>Lead-in AACS media key block</summary>
AACS_MKB,
/// <summary>AACS data keys</summary>
AACS_DataKeys,
/// <summary>LBA extents flagged for bus encryption by AACS</summary>
AACS_LBAExtents,
/// <summary>CPRM media key block in Lead-in</summary>
AACS_CPRM_MKB,
/// <summary>Recognized layer formats in hybrid discs</summary>
Hybrid_RecognizedLayers,
/// <summary>Disc write protection status</summary>
MMC_WriteProtection,
/// <summary>Disc standard information</summary>
MMC_DiscInformation,
/// <summary>Disc track resources information</summary>
MMC_TrackResourcesInformation,
/// <summary>BD-R Pseudo-overwrite information</summary>
MMC_POWResourcesInformation,
/// <summary>SCSI INQUIRY response</summary>
SCSI_INQUIRY,
/// <summary>SCSI MODE PAGE 2Ah</summary>
SCSI_MODEPAGE_2A,
/// <summary>ATA IDENTIFY DEVICE response</summary>
ATA_IDENTIFY,
/// <summary>ATA IDENTIFY PACKET DEVICE response</summary>
ATAPI_IDENTIFY,
/// <summary>PCMCIA/CardBus Card Information Structure</summary>
PCMCIA_CIS,
/// <summary>SecureDigital CID</summary>
SD_CID,
/// <summary>SecureDigital CSD</summary>
SD_CSD,
/// <summary>SecureDigital SCR</summary>
SD_SCR,
/// <summary>SecureDigital OCR</summary>
SD_OCR,
/// <summary>MultiMediaCard CID</summary>
MMC_CID,
/// <summary>MultiMediaCard CSD</summary>
MMC_CSD,
/// <summary>MultiMediaCard OCR</summary>
MMC_OCR,
/// <summary>MultiMediaCard Extended CSD</summary>
MMC_ExtendedCSD,
/// <summary>Xbox Security Sector</summary>
Xbox_SecuritySector,
/// <summary>
/// On floppy disks, data in last cylinder usually in a different format that contains duplication or
/// manufacturing information
/// </summary>
Floppy_LeadOut,
/// <summary>DVD Disc Control Blocks</summary>
DCB,
/// <summary>Compact Disc Lead-in</summary>
CD_LeadIn,
/// <summary>Compact Disc Lead-out</summary>
CD_LeadOut,
/// <summary>SCSI MODE SENSE (6)</summary>
SCSI_MODESENSE_6,
/// <summary>SCSI MODE SENSE (10)</summary>
SCSI_MODESENSE_10,
/// <summary>USB descriptors</summary>
USB_Descriptors,
/// <summary>XGD unlocked DMI</summary>
Xbox_DMI,
/// <summary>XDG unlocked PFI</summary>
Xbox_PFI
}
/// <summary>
/// Enumeration of media types defined in CICM metadata
/// </summary>
public enum XmlMediaType
{
/// <summary>
/// Purely optical discs
/// </summary>
OpticalDisc,
/// <summary>
/// Media that is physically block-based or abstracted like that
/// </summary>
BlockMedia,
/// <summary>
/// Media that can be accessed by-byte or by-bit, like chips
/// </summary>
LinearMedia,
/// <summary>
/// Media that can only store data when it is modulated to audio
/// </summary>
AudioMedia
}
/// <summary> CD flags bitmask</summary>
[Flags]
public enum CdFlags : byte
{
/// <summary>Track is quadraphonic.</summary>
FourChannel = 0x08,
/// <summary>Track is non-audio (data).</summary>
DataTrack = 0x04,
/// <summary>Track is copy protected.</summary>
CopyPermitted = 0x02,
/// <summary>Track has pre-emphasis.</summary>
PreEmphasis = 0x01
}
/// <summary>Status of a requested floppy sector</summary>
[Flags]
public enum FloppySectorStatus : byte
{
/// <summary>Both address mark and data checksums are correct.</summary>
Correct = 0x01,
/// <summary>Data checksum is incorrect.</summary>
DataError = 0x02,
/// <summary>Addres mark checksum is incorrect.</summary>
AddressMarkError = 0x04,
/// <summary>There is another sector in the same track/head with same sector id.</summary>
Duplicated = 0x08,
/// <summary>Sector data section is not magnetized.</summary>
Demagnetized = 0x10,
/// <summary>Sector data section has a physically visible hole.</summary>
Hole = 0x20,
/// <summary>There is no address mark containing the requested sector id in the track/head.</summary>
NotFound = 0x40
}
public enum FloppyTypes : byte
{
/// <summary>8" floppy</summary>
Floppy,
/// <summary>5.25" floppy</summary>
MiniFloppy,
/// <summary>3.5" floppy</summary>
MicroFloppy,
/// <summary>3" floppy</summary>
CompactFloppy,
/// <summary>5.25" twiggy</summary>
FileWare,
/// <summary>2.5" quickdisk</summary>
QuickDisk
}
public enum FloppyDensities : byte
{
/// <summary>Standard coercitivity (about 300Oe as found in 8" and 5.25"-double-density disks).</summary>
Standard,
/// <summary>Double density coercitivity (about 600Oe as found in 5.25" HD and 3.5" DD disks).</summary>
Double,
/// <summary>High density coercitivity (about 700Oe as found in 3.5" HD disks).</summary>
High,
/// <summary>Extended density coercitivity (about 750Oe as found in 3.5" ED disks).</summary>
Extended
}
}

188
Exceptions/Images.cs Normal file
View File

@@ -0,0 +1,188 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Enums.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines exceptions to be thrown by disc image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Runtime.Serialization;
namespace DiscImageChef.CommonTypes.Exceptions
{
/// <summary>
/// Feature is supported by image but not implemented yet.
/// </summary>
[Serializable]
public class FeatureSupportedButNotImplementedImageException : Exception
{
/// <summary>
/// Feature is supported by image but not implemented yet.
/// </summary>
/// <param name="message">Message.</param>
/// <param name="inner">Inner.</param>
public FeatureSupportedButNotImplementedImageException(string message, Exception inner) :
base(message, inner) { }
/// <summary>
/// Feature is supported by image but not implemented yet.
/// </summary>
/// <param name="message">Message.</param>
public FeatureSupportedButNotImplementedImageException(string message) : base(message) { }
/// <summary>
/// Feature is supported by image but not implemented yet.
/// </summary>
/// <param name="info">Info.</param>
/// <param name="context">Context.</param>
protected FeatureSupportedButNotImplementedImageException(SerializationInfo info, StreamingContext context)
{
if(info == null) throw new ArgumentNullException(nameof(info));
}
}
/// <summary>
/// Feature is not supported by image.
/// </summary>
[Serializable]
public class FeatureUnsupportedImageException : Exception
{
/// <summary>
/// Feature is not supported by image.
/// </summary>
/// <param name="message">Message.</param>
/// <param name="inner">Inner.</param>
public FeatureUnsupportedImageException(string message, Exception inner) : base(message, inner) { }
/// <summary>
/// Feature is not supported by image.
/// </summary>
/// <param name="message">Message.</param>
public FeatureUnsupportedImageException(string message) : base(message) { }
/// <summary>
/// Feature is not supported by image.
/// </summary>
/// <param name="info">Info.</param>
/// <param name="context">Context.</param>
protected FeatureUnsupportedImageException(SerializationInfo info, StreamingContext context)
{
if(info == null) throw new ArgumentNullException(nameof(info));
}
}
/// <summary>
/// Feature is supported by image but not present on it.
/// </summary>
[Serializable]
public class FeatureNotPresentImageException : Exception
{
/// <summary>
/// Feature is supported by image but not present on it.
/// </summary>
/// <param name="message">Message.</param>
/// <param name="inner">Inner.</param>
public FeatureNotPresentImageException(string message, Exception inner) : base(message, inner) { }
/// <summary>
/// Feature is supported by image but not present on it.
/// </summary>
/// <param name="message">Message.</param>
public FeatureNotPresentImageException(string message) : base(message) { }
/// <summary>
/// Feature is supported by image but not present on it.
/// </summary>
/// <param name="info">Info.</param>
/// <param name="context">Context.</param>
protected FeatureNotPresentImageException(SerializationInfo info, StreamingContext context)
{
if(info == null) throw new ArgumentNullException(nameof(info));
}
}
/// <summary>
/// Feature is supported by image but not by the disc it represents.
/// </summary>
[Serializable]
public class FeaturedNotSupportedByDiscImageException : Exception
{
/// <summary>
/// Feature is supported by image but not by the disc it represents.
/// </summary>
/// <param name="message">Message.</param>
/// <param name="inner">Inner.</param>
public FeaturedNotSupportedByDiscImageException(string message, Exception inner) : base(message, inner) { }
/// <summary>
/// Feature is supported by image but not by the disc it represents.
/// </summary>
/// <param name="message">Message.</param>
public FeaturedNotSupportedByDiscImageException(string message) : base(message) { }
/// <summary>
/// Feature is supported by image but not by the disc it represents.
/// </summary>
/// <param name="info">Info.</param>
/// <param name="context">Context.</param>
protected FeaturedNotSupportedByDiscImageException(SerializationInfo info, StreamingContext context)
{
if(info == null) throw new ArgumentNullException(nameof(info));
}
}
/// <summary>
/// Corrupt, incorrect or unhandled feature found on image
/// </summary>
[Serializable]
public class ImageNotSupportedException : Exception
{
/// <summary>
/// Corrupt, incorrect or unhandled feature found on image
/// </summary>
/// <param name="message">Message.</param>
/// <param name="inner">Inner.</param>
public ImageNotSupportedException(string message, Exception inner) : base(message, inner) { }
/// <summary>
/// Corrupt, incorrect or unhandled feature found on image
/// </summary>
/// <param name="message">Message.</param>
public ImageNotSupportedException(string message) : base(message) { }
/// <summary>
/// Corrupt, incorrect or unhandled feature found on image
/// </summary>
/// <param name="info">Info.</param>
/// <param name="context">Context.</param>
protected ImageNotSupportedException(SerializationInfo info, StreamingContext context)
{
if(info == null) throw new ArgumentNullException(nameof(info));
}
}
}

248
Extents/ExtentsByte.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsByte.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for byte types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="byte" />
/// </summary>
public class ExtentsByte
{
List<Tuple<byte, byte>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsByte()
{
backend = new List<Tuple<byte, byte>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsByte(IEnumerable<Tuple<byte, byte>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(byte item)
{
Tuple<byte, byte> removeOne = null;
Tuple<byte, byte> removeTwo = null;
Tuple<byte, byte> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<byte, byte>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<byte, byte>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<byte, byte>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<byte, byte>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<byte, byte>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(byte start, byte end, bool run = false)
{
byte realEnd;
if(run) realEnd = (byte)(start + end - 1);
else realEnd = end;
// TODO: Optimize this
for(byte t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(byte item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(byte item)
{
Tuple<byte, byte> toRemove = null;
Tuple<byte, byte> toAddOne = null;
Tuple<byte, byte> toAddTwo = null;
foreach(Tuple<byte, byte> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<byte, byte>(extent.Item1, (byte)(item - 1));
toAddTwo = new Tuple<byte, byte>((byte)(item + 1), extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<byte, byte>((byte)(item + 1), extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<byte, byte>(extent.Item1, (byte)(item - 1));
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<byte, byte>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(byte item, out byte start)
{
start = 0;
foreach(Tuple<byte, byte> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,65 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsConverter.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : XML metadata.
//
// --[ Description ] ----------------------------------------------------------
//
// Converts extents to/from XML.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using Schemas;
namespace DiscImageChef.CommonTypes.Extents
{
public static class ExtentsConverter
{
public static ExtentType[] ToMetadata(ExtentsULong extents)
{
if(extents == null) return null;
Tuple<ulong, ulong>[] tuples = extents.ToArray();
ExtentType[] array = new ExtentType[tuples.Length];
for(ulong i = 0; i < (ulong)array.LongLength; i++)
array[i] = new ExtentType {Start = tuples[i].Item1, End = tuples[i].Item2};
return array;
}
public static ExtentsULong FromMetadata(ExtentType[] extents)
{
if(extents == null) return null;
List<Tuple<ulong, ulong>> tuples =
extents.Select(extent => new Tuple<ulong, ulong>(extent.Start, extent.End)).ToList();
return new ExtentsULong(tuples);
}
}
}

248
Extents/ExtentsInt.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsInt.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for int types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License aint with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="int" />
/// </summary>
public class ExtentsInt
{
List<Tuple<int, int>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsInt()
{
backend = new List<Tuple<int, int>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsInt(IEnumerable<Tuple<int, int>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(int item)
{
Tuple<int, int> removeOne = null;
Tuple<int, int> removeTwo = null;
Tuple<int, int> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<int, int>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<int, int>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<int, int>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<int, int>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<int, int>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(int start, int end, bool run = false)
{
int realEnd;
if(run) realEnd = start + end - 1;
else realEnd = end;
// TODO: Optimize this
for(int t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(int item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(int item)
{
Tuple<int, int> toRemove = null;
Tuple<int, int> toAddOne = null;
Tuple<int, int> toAddTwo = null;
foreach(Tuple<int, int> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<int, int>(extent.Item1, item - 1);
toAddTwo = new Tuple<int, int>(item + 1, extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<int, int>(item + 1, extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<int, int>(extent.Item1, item - 1);
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<int, int>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(int item, out int start)
{
start = 0;
foreach(Tuple<int, int> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

248
Extents/ExtentsLong.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsLong.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for long types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="long" />
/// </summary>
public class ExtentsLong
{
List<Tuple<long, long>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsLong()
{
backend = new List<Tuple<long, long>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsLong(IEnumerable<Tuple<long, long>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(long item)
{
Tuple<long, long> removeOne = null;
Tuple<long, long> removeTwo = null;
Tuple<long, long> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<long, long>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<long, long>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<long, long>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<long, long>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<long, long>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(long start, long end, bool run = false)
{
long realEnd;
if(run) realEnd = start + end - 1;
else realEnd = end;
// TODO: Optimize this
for(long t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(long item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(long item)
{
Tuple<long, long> toRemove = null;
Tuple<long, long> toAddOne = null;
Tuple<long, long> toAddTwo = null;
foreach(Tuple<long, long> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<long, long>(extent.Item1, item - 1);
toAddTwo = new Tuple<long, long>(item + 1, extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<long, long>(item + 1, extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<long, long>(extent.Item1, item - 1);
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<long, long>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(long item, out long start)
{
start = 0;
foreach(Tuple<long, long> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

248
Extents/ExtentsSByte.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsSByte.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for sbyte types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="sbyte" />
/// </summary>
public class ExtentsSByte
{
List<Tuple<sbyte, sbyte>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsSByte()
{
backend = new List<Tuple<sbyte, sbyte>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsSByte(IEnumerable<Tuple<sbyte, sbyte>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(sbyte item)
{
Tuple<sbyte, sbyte> removeOne = null;
Tuple<sbyte, sbyte> removeTwo = null;
Tuple<sbyte, sbyte> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<sbyte, sbyte>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<sbyte, sbyte>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<sbyte, sbyte>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<sbyte, sbyte>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<sbyte, sbyte>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(sbyte start, sbyte end, bool run = false)
{
sbyte realEnd;
if(run) realEnd = (sbyte)(start + end - 1);
else realEnd = end;
// TODO: Optimize this
for(sbyte t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(sbyte item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(sbyte item)
{
Tuple<sbyte, sbyte> toRemove = null;
Tuple<sbyte, sbyte> toAddOne = null;
Tuple<sbyte, sbyte> toAddTwo = null;
foreach(Tuple<sbyte, sbyte> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<sbyte, sbyte>(extent.Item1, (sbyte)(item - 1));
toAddTwo = new Tuple<sbyte, sbyte>((sbyte)(item + 1), extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<sbyte, sbyte>((sbyte)(item + 1), extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<sbyte, sbyte>(extent.Item1, (sbyte)(item - 1));
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<sbyte, sbyte>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(sbyte item, out sbyte start)
{
start = 0;
foreach(Tuple<sbyte, sbyte> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

248
Extents/ExtentsShort.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsShort.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for short types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License ashort with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="short" />
/// </summary>
public class ExtentsShort
{
List<Tuple<short, short>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsShort()
{
backend = new List<Tuple<short, short>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsShort(IEnumerable<Tuple<short, short>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(short item)
{
Tuple<short, short> removeOne = null;
Tuple<short, short> removeTwo = null;
Tuple<short, short> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<short, short>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<short, short>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<short, short>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<short, short>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<short, short>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(short start, short end, bool run = false)
{
short realEnd;
if(run) realEnd = (short)(start + end - 1);
else realEnd = end;
// TODO: Optimize this
for(short t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(short item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(short item)
{
Tuple<short, short> toRemove = null;
Tuple<short, short> toAddOne = null;
Tuple<short, short> toAddTwo = null;
foreach(Tuple<short, short> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<short, short>(extent.Item1, (short)(item - 1));
toAddTwo = new Tuple<short, short>((short)(item + 1), extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<short, short>((short)(item + 1), extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<short, short>(extent.Item1, (short)(item - 1));
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<short, short>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(short item, out short start)
{
start = 0;
foreach(Tuple<short, short> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

248
Extents/ExtentsUInt.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsUInt.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for uint types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License auint with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="uint" />
/// </summary>
public class ExtentsUInt
{
List<Tuple<uint, uint>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsUInt()
{
backend = new List<Tuple<uint, uint>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsUInt(IEnumerable<Tuple<uint, uint>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(uint item)
{
Tuple<uint, uint> removeOne = null;
Tuple<uint, uint> removeTwo = null;
Tuple<uint, uint> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<uint, uint>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<uint, uint>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<uint, uint>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<uint, uint>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<uint, uint>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(uint start, uint end, bool run = false)
{
uint realEnd;
if(run) realEnd = start + end - 1;
else realEnd = end;
// TODO: Optimize this
for(uint t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(uint item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(uint item)
{
Tuple<uint, uint> toRemove = null;
Tuple<uint, uint> toAddOne = null;
Tuple<uint, uint> toAddTwo = null;
foreach(Tuple<uint, uint> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<uint, uint>(extent.Item1, item - 1);
toAddTwo = new Tuple<uint, uint>(item + 1, extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<uint, uint>(item + 1, extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<uint, uint>(extent.Item1, item - 1);
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<uint, uint>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(uint item, out uint start)
{
start = 0;
foreach(Tuple<uint, uint> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

248
Extents/ExtentsULong.cs Normal file
View File

@@ -0,0 +1,248 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsULong.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for ulong types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License aulong with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="ulong" />
/// </summary>
public class ExtentsULong
{
List<Tuple<ulong, ulong>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsULong()
{
backend = new List<Tuple<ulong, ulong>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsULong(IEnumerable<Tuple<ulong, ulong>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(ulong item)
{
Tuple<ulong, ulong> removeOne = null;
Tuple<ulong, ulong> removeTwo = null;
Tuple<ulong, ulong> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<ulong, ulong>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<ulong, ulong>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<ulong, ulong>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<ulong, ulong>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<ulong, ulong>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(ulong start, ulong end, bool run = false)
{
ulong realEnd;
if(run) realEnd = start + end - 1;
else realEnd = end;
// TODO: Optimize this
for(ulong t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(ulong item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(ulong item)
{
Tuple<ulong, ulong> toRemove = null;
Tuple<ulong, ulong> toAddOne = null;
Tuple<ulong, ulong> toAddTwo = null;
foreach(Tuple<ulong, ulong> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<ulong, ulong>(extent.Item1, item - 1);
toAddTwo = new Tuple<ulong, ulong>(item + 1, extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<ulong, ulong>(item + 1, extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<ulong, ulong>(extent.Item1, item - 1);
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<ulong, ulong>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(ulong item, out ulong start)
{
start = 0;
foreach(Tuple<ulong, ulong> extent in backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

249
Extents/ExtentsUShort.cs Normal file
View File

@@ -0,0 +1,249 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : ExtentsUShort.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Extent helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides extents for ushort types.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License aushort with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DiscImageChef.CommonTypes.Extents
{
/// <summary>
/// Implements extents for <see cref="ushort" />
/// </summary>
public class ExtentsUShort
{
List<Tuple<ushort, ushort>> backend;
/// <summary>
/// Initialize an empty list of extents
/// </summary>
public ExtentsUShort()
{
backend = new List<Tuple<ushort, ushort>>();
}
/// <summary>
/// Initializes extents with an specific list
/// </summary>
/// <param name="list">List of extents as tuples "start, end"</param>
public ExtentsUShort(IEnumerable<Tuple<ushort, ushort>> list)
{
backend = list.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Gets a count of how many extents are stored
/// </summary>
public int Count => backend.Count;
/// <summary>
/// Adds the specified number to the corresponding extent, or creates a new one
/// </summary>
/// <param name="item"></param>
public void Add(ushort item)
{
Tuple<ushort, ushort> removeOne = null;
Tuple<ushort, ushort> removeTwo = null;
Tuple<ushort, ushort> itemToAdd = null;
for(int i = 0; i < backend.Count; i++)
{
// Already contained in an extent
if(item >= backend[i].Item1 && item <= backend[i].Item2) return;
// Expands existing extent start
if(item == backend[i].Item1 - 1)
{
removeOne = backend[i];
if(i > 0 && item == backend[i - 1].Item2 + 1)
{
removeTwo = backend[i - 1];
itemToAdd = new Tuple<ushort, ushort>(backend[i - 1].Item1, backend[i].Item2);
}
else itemToAdd = new Tuple<ushort, ushort>(item, backend[i].Item2);
break;
}
// Expands existing extent end
if(item != backend[i].Item2 + 1) continue;
removeOne = backend[i];
if(i < backend.Count - 1 && item == backend[i + 1].Item1 - 1)
{
removeTwo = backend[i + 1];
itemToAdd = new Tuple<ushort, ushort>(backend[i].Item1, backend[i + 1].Item2);
}
else itemToAdd = new Tuple<ushort, ushort>(backend[i].Item1, item);
break;
}
if(itemToAdd != null)
{
backend.Remove(removeOne);
backend.Remove(removeTwo);
backend.Add(itemToAdd);
}
else backend.Add(new Tuple<ushort, ushort>(item, item));
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
}
/// <summary>
/// Adds a new extent
/// </summary>
/// <param name="start">First element of the extent</param>
/// <param name="end">
/// Last element of the extent or if <see cref="run" /> is <c>true</c> how many elements the extent runs
/// for
/// </param>
/// <param name="run">If set to <c>true</c>, <see cref="end" /> indicates how many elements the extent runs for</param>
public void Add(ushort start, ushort end, bool run = false)
{
ushort realEnd;
if(run) realEnd = (ushort)(start + end - 1);
else realEnd = end;
// TODO: Optimize this
for(ushort t = start; t <= realEnd; t++) Add(t);
}
/// <summary>
/// Checks if the specified item is contained by an extent on this instance
/// </summary>
/// <param name="item">Item to seach for</param>
/// <returns><c>true</c> if any of the extents on this instance contains the item</returns>
public bool Contains(ushort item)
{
return backend.Any(extent => item >= extent.Item1 && item <= extent.Item2);
}
/// <summary>
/// Removes all extents from this instance
/// </summary>
public void Clear()
{
backend.Clear();
}
/// <summary>
/// Removes an item from the extents in this instance
/// </summary>
/// <param name="item">Item to remove</param>
/// <returns><c>true</c> if the item was contained in a known extent and removed, false otherwise</returns>
public bool Remove(ushort item)
{
Tuple<ushort, ushort> toRemove = null;
Tuple<ushort, ushort> toAddOne = null;
Tuple<ushort, ushort> toAddTwo = null;
foreach(Tuple<ushort, ushort> extent in backend)
{
// Extent is contained and not a border
if(item > extent.Item1 && item < extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<ushort, ushort>(extent.Item1, (ushort)(item - 1));
toAddTwo = new Tuple<ushort, ushort>((ushort)(item + 1), extent.Item2);
break;
}
// Extent is left border, but not only element
if(item == extent.Item1 && item != extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<ushort, ushort>((ushort)(item + 1), extent.Item2);
break;
}
// Extent is right border, but not only element
if(item != extent.Item1 && item == extent.Item2)
{
toRemove = extent;
toAddOne = new Tuple<ushort, ushort>(extent.Item1, (ushort)(item - 1));
break;
}
// Extent is only element
if(item != extent.Item1 || item != extent.Item2) continue;
toRemove = extent;
break;
}
// Item not found
if(toRemove == null) return false;
backend.Remove(toRemove);
if(toAddOne != null) backend.Add(toAddOne);
if(toAddTwo != null) backend.Add(toAddTwo);
// Sort
backend = backend.OrderBy(t => t.Item1).ToList();
return true;
}
/// <summary>
/// Converts the list of extents to an array of <see cref="Tuple" /> where T1 is first element of the extent and T2 is
/// last element
/// </summary>
/// <returns>Array of <see cref="Tuple" /></returns>
public Tuple<ushort, ushort>[] ToArray()
{
return backend.ToArray();
}
/// <summary>
/// Gets the first element of the extent that contains the specified item
/// </summary>
/// <param name="item">Item</param>
/// <param name="start">First element of extent</param>
/// <returns><c>true</c> if item was found in an extent, false otherwise</returns>
public bool GetStart(ushort item, out ushort start)
{
start = 0;
foreach(Tuple<ushort, ushort> extent in
backend.Where(extent => item >= extent.Item1 && item <= extent.Item2))
{
start = extent.Item1;
return true;
}
return false;
}
}
}

108
Filters.cs Normal file
View File

@@ -0,0 +1,108 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Filters.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Filters.
//
// --[ Description ] ----------------------------------------------------------
//
// Enumerates all filters and instantiates the correct one.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
namespace DiscImageChef.CommonTypes
{
public class FiltersList
{
public SortedDictionary<string, IFilter> Filters;
/// <summary>
/// Fills the list of all known filters
/// </summary>
public FiltersList()
{
Assembly assembly = Assembly.Load("DiscImageChef.Filters");
Filters = new SortedDictionary<string, IFilter>();
foreach(Type type in assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IFilter))))
try
{
IFilter filter = (IFilter)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
if(filter != null && !Filters.ContainsKey(filter.Name.ToLower()))
Filters.Add(filter.Name.ToLower(), filter);
}
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
}
/// <summary>
/// Gets the filter that allows to read the specified path
/// </summary>
/// <param name="path">Path</param>
/// <returns>The filter that allows reading the specified path</returns>
public IFilter GetFilter(string path)
{
try
{
IFilter noFilter = null;
foreach(IFilter filter in Filters.Values)
if(filter.Id != new Guid("12345678-AAAA-BBBB-CCCC-123456789000"))
{
if(!filter.Identify(path)) continue;
IFilter foundFilter =
(IFilter)filter.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
foundFilter?.Open(path);
if(foundFilter?.IsOpened() == true) return foundFilter;
}
else
noFilter = filter;
if(!noFilter?.Identify(path) == true) return noFilter;
noFilter?.Open(path);
return noFilter;
}
catch(IOException) { return null; }
}
/// <summary>
/// Gets all known filters
/// </summary>
/// <returns>Known filters</returns>
public SortedDictionary<string, IFilter> GetFiltersList()
{
return Filters;
}
}
}

60
Interfaces/IChecksum.cs Normal file
View File

@@ -0,0 +1,60 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IChecksum.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Provides an interface for implementing checksums and hashes.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
namespace DiscImageChef.CommonTypes.Interfaces
{
public interface IChecksum
{
/// <summary>
/// Updates the hash with data.
/// </summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of buffer to hash.</param>
void Update(byte[] data, uint len);
/// <summary>
/// Updates the hash with data.
/// </summary>
/// <param name="data">Data buffer.</param>
void Update(byte[] data);
/// <summary>
/// Returns a byte array of the hash value.
/// </summary>
byte[] Final();
/// <summary>
/// Returns a hexadecimal representation of the hash value.
/// </summary>
string End();
}
}

72
Interfaces/IFilesystem.cs Normal file
View File

@@ -0,0 +1,72 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IFilesystem.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Filesystem plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Interface for filesystem plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Text;
using Schemas;
namespace DiscImageChef.CommonTypes.Interfaces
{
/// <summary>
/// Interface to implement filesystem plugins.
/// </summary>
public interface IFilesystem
{
Encoding Encoding { get; }
/// <summary>Plugin name.</summary>
string Name { get; }
/// <summary>Plugin UUID.</summary>
Guid Id { get; }
/// <summary>
/// Information about the filesystem as expected by CICM Metadata XML
/// </summary>
/// <value>Information about the filesystem as expected by CICM Metadata XML</value>
FileSystemType XmlFsType { get; }
/// <summary>
/// Identifies the filesystem in the specified LBA
/// </summary>
/// <param name="imagePlugin">Disk image.</param>
/// <param name="partition">Partition.</param>
/// <returns><c>true</c>, if the filesystem is recognized, <c>false</c> otherwise.</returns>
bool Identify(IMediaImage imagePlugin, Partition partition);
/// <summary>
/// Gets information about the identified filesystem.
/// </summary>
/// <param name="imagePlugin">Disk image.</param>
/// <param name="partition">Partition.</param>
/// <param name="information">Filesystem information.</param>
/// <param name="encoding">Which encoding to use for this filesystem.</param>
void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding);
}
}

172
Interfaces/IFilter.cs Normal file
View File

@@ -0,0 +1,172 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IFilter.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Filters.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines the interface for a Filter.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.IO;
namespace DiscImageChef.CommonTypes.Interfaces
{
public interface IFilter
{
/// <summary>Descriptive name of the plugin</summary>
string Name { get; }
/// <summary>Unique UUID of the plugin</summary>
Guid Id { get; }
/// <summary>
/// Closes all opened streams.
/// </summary>
void Close();
/// <summary>
/// Gets the path used to open this filter.<br />
/// UNIX: /path/to/archive.zip/path/to/file.bin =&gt; /path/to/archive.zip/path/to/file.bin <br />
/// Windows: C:\path\to\archive.zip\path\to\file.bin =&gt; C:\path\to\archive.zip\path\to\file.bin
/// </summary>
/// <returns>Path used to open this filter.</returns>
string GetBasePath();
/// <summary>
/// Gets creation time of file referenced by this filter.
/// </summary>
/// <returns>The creation time.</returns>
DateTime GetCreationTime();
/// <summary>
/// Gets length of this filter's data fork.
/// </summary>
/// <returns>The data fork length.</returns>
long GetDataForkLength();
/// <summary>
/// Gets a stream to access the data fork contents.
/// </summary>
/// <returns>The data fork stream.</returns>
Stream GetDataForkStream();
/// <summary>
/// Gets the filename for the file referenced by this filter.<br />
/// UNIX: /path/to/archive.zip/path/to/file.bin =&gt; file.bin <br />
/// Windows: C:\path\to\archive.zip\path\to\file.bin =&gt; file.bin
/// </summary>
/// <returns>The filename.</returns>
string GetFilename();
/// <summary>
/// Gets last write time of file referenced by this filter.
/// </summary>
/// <returns>The last write time.</returns>
DateTime GetLastWriteTime();
/// <summary>
/// Gets length of file referenced by ths filter.
/// </summary>
/// <returns>The length.</returns>
long GetLength();
/// <summary>
/// Gets full path to file referenced by this filter. If it's an archive, it's the path inside the archive.<br />
/// UNIX: /path/to/archive.zip/path/to/file.bin =&gt; /path/to/file.bin <br />
/// Windows: C:\path\to\archive.zip\path\to\file.bin =&gt; \path\to\file.bin
/// </summary>
/// <returns>The path.</returns>
string GetPath();
/// <summary>
/// Gets path to parent folder to the file referenced by this filter. If it's an archive, it's the full path to the
/// archive itself.<br />
/// UNIX: /path/to/archive.zip/path/to/file.bin =&gt; /path/to/archive.zip <br />
/// Windows: C:\path\to\archive.zip\path\to\file.bin =&gt; C:\path\to\archive.zip
/// </summary>
/// <returns>The parent folder.</returns>
string GetParentFolder();
/// <summary>
/// Gets length of this filter's resource fork.
/// </summary>
/// <returns>The resource fork length.</returns>
long GetResourceForkLength();
/// <summary>
/// Gets a stream to access the resource fork contents.
/// </summary>
/// <returns>The resource fork stream.</returns>
Stream GetResourceForkStream();
/// <summary>
/// Returns true if the file referenced by this filter has a resource fork
/// </summary>
bool HasResourceFork();
/// <summary>
/// Identifies if the specified path contains data recognizable by this filter instance
/// </summary>
/// <param name="path">Path.</param>
bool Identify(string path);
/// <summary>
/// Identifies if the specified stream contains data recognizable by this filter instance
/// </summary>
/// <param name="stream">Stream.</param>
bool Identify(Stream stream);
/// <summary>
/// Identifies if the specified buffer contains data recognizable by this filter instance
/// </summary>
/// <param name="buffer">Buffer.</param>
bool Identify(byte[] buffer);
/// <summary>
/// Returns true if the filter has a file/stream/buffer currently opened and no
/// <see cref="M:DiscImageChef.Filters.Filter.Close" /> has been issued.
/// </summary>
bool IsOpened();
/// <summary>
/// Opens the specified path with this filter instance
/// </summary>
/// <param name="path">Path.</param>
void Open(string path);
/// <summary>
/// Opens the specified stream with this filter instance
/// </summary>
/// <param name="stream">Stream.</param>
void Open(Stream stream);
/// <summary>
/// Opens the specified buffer with this filter instance
/// </summary>
/// <param name="buffer">Buffer.</param>
void Open(byte[] buffer);
}
}

129
Interfaces/IFloppyImage.cs Normal file
View File

@@ -0,0 +1,129 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IFloppyImage.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines interface to be implemented by floppy image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs;
namespace DiscImageChef.CommonTypes.Interfaces
{
/// <summary>
/// Abstract class to implement disk image reading plugins that can contain floppy images.
/// This interface is needed because floppy formatting characteristics are not necesarily compatible with the whole.
/// LBA-oriented interface is defined by <see cref="IMediaImage" />.
/// All data returned by these methods is already decoded from its corresponding bitstream.
/// </summary>
public interface IFloppyImage : IMediaImage
{
/// <summary>
/// Floppy info, contains information about physical characteristics of floppy, like size, bitrate, track density,
/// etc...
/// </summary>
FloppyInfo FloppyInfo { get; }
/// <summary>
/// Reads a sector's user data.
/// </summary>
/// <returns>
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Duplicated" /> one of the duplicates is returned
/// randomly.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Demagnetized" /> or
/// <see cref="FloppySectorStatus.Hole" /> random data is returned.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.NotFound" /> <c>null</c> is returned.
/// Otherwise, whatever is in the sector is returned.
/// </returns>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <param name="sector">Logical sector ID.</param>
/// <param name="status">Status of request.</param>
byte[] ReadSector(ushort track, byte head, ushort sector, out FloppySectorStatus status);
/// <summary>
/// Reads a sector's tag.
/// </summary>
/// <returns>
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Duplicated" /> one of the duplicates is returned
/// randomly.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Demagnetized" /> or
/// <see cref="FloppySectorStatus.Hole" /> random data is returned.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.NotFound" /> <c>null</c> is returned.
/// Otherwise, whatever tag is in the sector is returned.
/// </returns>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <param name="sector">Logical sector ID.</param>
/// <param name="status">Status of request.</param>
byte[] ReadSectorTag(ushort track, byte head, ushort sector, out FloppySectorStatus status, SectorTagType tag);
/// <summary>
/// Reads a whole track. It includes all gaps, address marks, sectors data, etc.
/// </summary>
/// <returns>The track data.</returns>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
byte[] ReadTrack(ushort track, byte head);
/// <summary>
/// Reads a sector's data including all tags, address mark, and so, in a format dependent of represented media.
/// </summary>
/// <returns>
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Duplicated" /> one of the duplicates is returned
/// randomly.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Demagnetized" /> or
/// <see cref="FloppySectorStatus.Hole" /> random data is returned.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.NotFound" /> <c>null</c> is returned.
/// Otherwise, whatever is in the sector is returned.
/// </returns>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <param name="sector">Logical sector ID.</param>
/// <param name="status">Status of request.</param>
byte[] ReadSectorLong(ushort track, byte head, ushort sector, out FloppySectorStatus status);
/// <summary>
/// Verifies a track.
/// </summary>
/// <returns>True if correct, false if incorrect, null if uncheckable.</returns>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
bool? VerifyTrack(ushort track, byte head);
/// <summary>
/// Verifies a sector, relative to track.
/// </summary>
/// <returns>True if correct, false if incorrect, null if uncheckable.</returns>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <param name="sector">Logical sector ID.</param>
/// <param name="status">Status of request.</param>
bool? VerifySector(ushort track, byte head, ushort sector);
}
}

257
Interfaces/IMediaImage.cs Normal file
View File

@@ -0,0 +1,257 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IMediaImage.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines interface to be implemented by disc image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs;
using Schemas;
namespace DiscImageChef.CommonTypes.Interfaces
{
/// <summary>
/// Abstract class to implement disk image reading plugins.
/// </summary>
public interface IMediaImage
{
/// <summary>Image information</summary>
ImageInfo Info { get; }
/// <summary>Plugin name.</summary>
string Name { get; }
/// <summary>Plugin UUID.</summary>
Guid Id { get; }
/// <summary>
/// Gets the image format.
/// </summary>
/// <value>The image format.</value>
string Format { get; }
/// <summary>
/// Gets an array partitions. Typically only useful for optical disc
/// images where each track and index means a different partition, as
/// reads can be relative to them.
/// </summary>
/// <value>The partitions.</value>
List<Partition> Partitions { get; }
/// <summary>
/// Gets the disc track extents (start, length).
/// </summary>
/// <value>The track extents.</value>
List<Track> Tracks { get; }
/// <summary>
/// Gets the sessions (optical discs only).
/// </summary>
/// <value>The sessions.</value>
List<Session> Sessions { get; }
/// <summary>List of dump hardware used to create the image from real media</summary>
List<DumpHardwareType> DumpHardware { get; }
/// <summary>Gets the CICM XML metadata for the image</summary>
CICMMetadataType CicmMetadata { get; }
/// <summary>
/// Identifies the image.
/// </summary>
/// <returns><c>true</c>, if image was identified, <c>false</c> otherwise.</returns>
/// <param name="imageFilter">Image filter.</param>
bool Identify(IFilter imageFilter);
/// <summary>
/// Opens the image.
/// </summary>
/// <returns><c>true</c>, if image was opened, <c>false</c> otherwise.</returns>
/// <param name="imageFilter">Image filter.</param>
bool Open(IFilter imageFilter);
/// <summary>
/// Reads a disk tag.
/// </summary>
/// <returns>Disk tag</returns>
/// <param name="tag">Tag type to read.</param>
byte[] ReadDiskTag(MediaTagType tag);
/// <summary>
/// Reads a sector's user data.
/// </summary>
/// <returns>The sector's user data.</returns>
/// <param name="sectorAddress">Sector address (LBA).</param>
byte[] ReadSector(ulong sectorAddress);
/// <summary>
/// Reads a sector's tag.
/// </summary>
/// <returns>The sector's tag.</returns>
/// <param name="sectorAddress">Sector address (LBA).</param>
/// <param name="tag">Tag type.</param>
byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag);
/// <summary>
/// Reads a sector's user data, relative to track.
/// </summary>
/// <returns>The sector's user data.</returns>
/// <param name="sectorAddress">Sector address (relative LBA).</param>
/// <param name="track">Track.</param>
byte[] ReadSector(ulong sectorAddress, uint track);
/// <summary>
/// Reads a sector's tag, relative to track.
/// </summary>
/// <returns>The sector's tag.</returns>
/// <param name="sectorAddress">Sector address (relative LBA).</param>
/// <param name="track">Track.</param>
/// <param name="tag">Tag type.</param>
byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag);
/// <summary>
/// Reads user data from several sectors.
/// </summary>
/// <returns>The sectors user data.</returns>
/// <param name="sectorAddress">Starting sector address (LBA).</param>
/// <param name="length">How many sectors to read.</param>
byte[] ReadSectors(ulong sectorAddress, uint length);
/// <summary>
/// Reads tag from several sectors.
/// </summary>
/// <returns>The sectors tag.</returns>
/// <param name="sectorAddress">Starting sector address (LBA).</param>
/// <param name="length">How many sectors to read.</param>
/// <param name="tag">Tag type.</param>
byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag);
/// <summary>
/// Reads user data from several sectors, relative to track.
/// </summary>
/// <returns>The sectors user data.</returns>
/// <param name="sectorAddress">Starting sector address (relative LBA).</param>
/// <param name="length">How many sectors to read.</param>
/// <param name="track">Track.</param>
byte[] ReadSectors(ulong sectorAddress, uint length, uint track);
/// <summary>
/// Reads tag from several sectors, relative to track.
/// </summary>
/// <returns>The sectors tag.</returns>
/// <param name="sectorAddress">Starting sector address (relative LBA).</param>
/// <param name="length">How many sectors to read.</param>
/// <param name="track">Track.</param>
/// <param name="tag">Tag type.</param>
byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag);
/// <summary>
/// Reads a complete sector (user data + all tags).
/// </summary>
/// <returns>The complete sector. Format depends on disk type.</returns>
/// <param name="sectorAddress">Sector address (LBA).</param>
byte[] ReadSectorLong(ulong sectorAddress);
/// <summary>
/// Reads a complete sector (user data + all tags), relative to track.
/// </summary>
/// <returns>The complete sector. Format depends on disk type.</returns>
/// <param name="sectorAddress">Sector address (relative LBA).</param>
/// <param name="track">Track.</param>
byte[] ReadSectorLong(ulong sectorAddress, uint track);
/// <summary>
/// Reads several complete sector (user data + all tags).
/// </summary>
/// <returns>The complete sectors. Format depends on disk type.</returns>
/// <param name="sectorAddress">Starting sector address (LBA).</param>
/// <param name="length">How many sectors to read.</param>
byte[] ReadSectorsLong(ulong sectorAddress, uint length);
/// <summary>
/// Reads several complete sector (user data + all tags), relative to track.
/// </summary>
/// <returns>The complete sectors. Format depends on disk type.</returns>
/// <param name="sectorAddress">Starting sector address (relative LBA).</param>
/// <param name="length">How many sectors to read.</param>
/// <param name="track">Track.</param>
byte[] ReadSectorsLong(ulong sectorAddress, uint length, uint track);
/// <summary>
/// Gets the disc track extents for a specified session.
/// </summary>
/// <returns>The track exents for that session.</returns>
/// <param name="session">Session.</param>
List<Track> GetSessionTracks(Session session);
/// <summary>
/// Gets the disc track extents for a specified session.
/// </summary>
/// <returns>The track exents for that session.</returns>
/// <param name="session">Session.</param>
List<Track> GetSessionTracks(ushort session);
/// <summary>
/// Verifies a sector.
/// </summary>
/// <returns>True if correct, false if incorrect, null if uncheckable.</returns>
/// <param name="sectorAddress">Sector address (LBA).</param>
bool? VerifySector(ulong sectorAddress);
/// <summary>
/// Verifies a sector, relative to track.
/// </summary>
/// <returns>True if correct, false if incorrect, null if uncheckable.</returns>
/// <param name="sectorAddress">Sector address (relative LBA).</param>
/// <param name="track">Track.</param>
bool? VerifySector(ulong sectorAddress, uint track);
/// <summary>
/// Verifies several sectors.
/// </summary>
/// <returns>True if all are correct, false if any is incorrect, null if any is uncheckable.</returns>
/// <param name="sectorAddress">Starting sector address (LBA).</param>
/// <param name="length">How many sectors to read.</param>
/// <param name="failingLbas">List of incorrect sectors</param>
/// <param name="unknownLbas">List of uncheckable sectors</param>
bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, out List<ulong> unknownLbas);
/// <summary>
/// Verifies several sectors, relative to track.
/// </summary>
/// <returns>True if all are correct, false if any is incorrect, null if any is uncheckable.</returns>
/// <param name="sectorAddress">Starting sector address (relative LBA).</param>
/// <param name="length">How many sectors to read.</param>
/// <param name="track">Track.</param>
/// <param name="failingLbas">List of incorrect sectors</param>
/// <param name="unknownLbas">List of uncheckable sectors</param>
bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas);
/// <summary>
/// Verifies media image internal checksum.
/// </summary>
/// <returns>True if correct, false if incorrect, null if there is no internal checksum available</returns>
bool? VerifyMediaImage();
}
}

60
Interfaces/IPartition.cs Normal file
View File

@@ -0,0 +1,60 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IPartition.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Partitioning scheme plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines methods to be used by partitioning scheme plugins and several
// constants.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Interfaces;
namespace DiscImageChef.Partitions
{
/// <summary>
/// Abstract class to implement partitioning schemes interpreting plugins.
/// </summary>
public interface IPartition
{
/// <summary>Plugin name.</summary>
string Name { get; }
/// <summary>Plugin UUID.</summary>
Guid Id { get; }
/// <summary>
/// Interprets a partitioning scheme.
/// </summary>
/// <returns><c>true</c>, if partitioning scheme is recognized, <c>false</c> otherwise.</returns>
/// <param name="imagePlugin">Disk image.</param>
/// <param name="partitions">Returns list of partitions.</param>
/// <param name="sectorOffset">At which sector to start searching for the partition scheme.</param>
bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset);
}
}

View File

@@ -0,0 +1,138 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IReadOnlyFilesystem.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Filesystem plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Interface for filesystem plugins that offer read-only support of their
// contents.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DiscImageChef.CommonTypes.Structs;
namespace DiscImageChef.CommonTypes.Interfaces
{
/// <summary>
/// Interface to implement filesystem plugins.
/// </summary>
public interface IReadOnlyFilesystem : IFilesystem
{
/// <summary>
/// Retrieves a list of options supported by the filesystem, with name, type and description
/// </summary>
IEnumerable<(string name, Type type, string description)> SupportedOptions { get; }
/// <summary>
/// Initializates whatever internal structures the filesystem plugin needs to be able to read files and directories
/// from the filesystem.
/// </summary>
/// <param name="imagePlugin"></param>
/// <param name="partition"></param>
/// <param name="encoding">Which encoding to use for this filesystem.</param>
/// <param name="options">Dictionary of key=value pairs containing options to pass to the filesystem</param>
Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options);
/// <summary>
/// Frees all internal structures created by
/// <see cref="Mount" />
/// </summary>
Errno Unmount();
/// <summary>
/// Maps a filesystem block from a file to a block from the underlying device.
/// </summary>
/// <returns>Error number.</returns>
/// <param name="path">File path.</param>
/// <param name="fileBlock">File block.</param>
/// <param name="deviceBlock">Device block.</param>
Errno MapBlock(string path, long fileBlock, out long deviceBlock);
/// <summary>
/// Gets the attributes of a file or directory
/// </summary>
/// <returns>Error number.</returns>
/// <param name="path">File path.</param>
/// <param name="attributes">File attributes.</param>
Errno GetAttributes(string path, out FileAttributes attributes);
/// <summary>
/// Lists all extended attributes, alternate data streams and forks of the given file.
/// </summary>
/// <returns>Error number.</returns>
/// <param name="path">Path.</param>
/// <param name="xattrs">List of extended attributes, alternate data streams and forks.</param>
Errno ListXAttr(string path, out List<string> xattrs);
/// <summary>
/// Reads an extended attribute, alternate data stream or fork from the given file.
/// </summary>
/// <returns>Error number.</returns>
/// <param name="path">File path.</param>
/// <param name="xattr">Extendad attribute, alternate data stream or fork name.</param>
/// <param name="buf">Buffer.</param>
Errno GetXattr(string path, string xattr, ref byte[] buf);
/// <summary>
/// Reads data from a file (main/only data stream or data fork).
/// </summary>
/// <param name="path">File path.</param>
/// <param name="offset">Offset.</param>
/// <param name="size">Bytes to read.</param>
/// <param name="buf">Buffer.</param>
Errno Read(string path, long offset, long size, ref byte[] buf);
/// <summary>
/// Lists contents from a directory.
/// </summary>
/// <param name="path">Directory path.</param>
/// <param name="contents">Directory contents.</param>
Errno ReadDir(string path, out List<string> contents);
/// <summary>
/// Gets information about the mounted volume.
/// </summary>
/// <param name="stat">Information about the mounted volume.</param>
Errno StatFs(out FileSystemInfo stat);
/// <summary>
/// Gets information about a file or directory.
/// </summary>
/// <param name="path">File path.</param>
/// <param name="stat">File information.</param>
Errno Stat(string path, out FileEntryInfo stat);
/// <summary>
/// Solves a symbolic link.
/// </summary>
/// <param name="path">Link path.</param>
/// <param name="dest">Link destination.</param>
Errno ReadLink(string path, out string dest);
}
}

View File

@@ -0,0 +1,98 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IFloppyImage.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines interface to be implemented by floppy image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs;
namespace DiscImageChef.CommonTypes.Interfaces
{
/// <summary>
/// Abstract class to implement disk image reading plugins that can contain floppy images.
/// This interface is needed because floppy formatting characteristics are not necesarily compatible with the whole
/// LBA-oriented interface defined by <see cref="IMediaImage" />.
/// All data expected by these methods is already decoded from its corresponding bitstream.
/// </summary>
public interface IWritableFloppyImage : IFloppyImage, IWritableImage
{
/// <summary>
/// Indicates the image plugin the floppy physical characteristics and must be called before following methods are
/// called. Once this is called, LBA-based methods should not be used.
/// </summary>
/// <param name="info">
/// Floppy info, contains information about physical characteristics of floppy, like size, bitrate,
/// track density, etc...
/// </param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool SetFloppyCharacteristics(FloppyInfo info);
/// <summary>
/// Writes a sector's user data.
/// </summary>
/// <param name="data">
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Duplicated" /> one of the duplicates.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Demagnetized" />, <see cref="FloppySectorStatus.Hole" />,
/// <see cref="FloppySectorStatus.NotFound" /> it will be ignored.
/// Otherwise, whatever data should be in the sector.
/// </param>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <param name="sector">Logical sector ID.</param>
/// <param name="status">Status of sector.</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSector(byte[] data, ushort track, byte head, ushort sector, FloppySectorStatus status);
/// <summary>
/// Writes a whole track, including all gaps, address marks, sectors data, etc.
/// </summary>
/// <param name="data">The track data.</param>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteTrack(byte[] data, ushort track, byte head);
/// <summary>
/// Writes a sector's data including all tags, address mark, and so, in a format dependent of represented media.
/// </summary>
/// <param name="data">
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Duplicated" /> one of the duplicates.
/// If <see cref="status" /> is <see cref="FloppySectorStatus.Demagnetized" />, <see cref="FloppySectorStatus.Hole" />,
/// <see cref="FloppySectorStatus.NotFound" /> it will be ignored.
/// Otherwise, whatever data should be in the sector.
/// </param>
/// <param name="track">Physical track (position of the heads over the floppy media, 0-based).</param>
/// <param name="head">Physical head (0-based).</param>
/// <param name="sector">Logical sector ID.</param>
/// <param name="status">Status of request.</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSectorLong(byte[] data, ushort track, byte head, ushort sector, out FloppySectorStatus status);
}
}

View File

@@ -0,0 +1,186 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IWritableImage.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines interface to be implemented by writable image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs;
using Schemas;
namespace DiscImageChef.CommonTypes.Interfaces
{
/// <summary>
/// Abstract class to implement disk image writing plugins.
/// TODO: This interface is subject to change until notice.
/// </summary>
public interface IWritableImage : IMediaImage
{
/// <summary>
/// Gets a list of <see cref="MediaTagType" /> that are supported by the media image format
/// </summary>
IEnumerable<MediaTagType> SupportedMediaTags { get; }
/// <summary>
/// Gets a list of <see cref="SectorTagType" /> that are supported by the media image format
/// </summary>
IEnumerable<SectorTagType> SupportedSectorTags { get; }
/// <summary>
/// Gets a list of <see cref="MediaType" /> that are supported by the media image format
/// </summary>
IEnumerable<MediaType> SupportedMediaTypes { get; }
/// <summary>
/// Retrieves a list of options supported by the filesystem, with name, type and description
/// </summary>
IEnumerable<(string name, Type type, string description)> SupportedOptions { get; }
/// <summary>
/// Gets a list of known extensions for format auto-chosing
/// </summary>
IEnumerable<string> KnownExtensions { get; }
bool IsWriting { get; }
string ErrorMessage { get; }
/// <summary>
/// Creates a new image in the specified path, for the specified <see cref="MediaType" />, with the
/// specified options to hold a media with the specified number of sectors
/// </summary>
/// <param name="path">Path to the new image, with extension</param>
/// <param name="mediaType"><see cref="MediaType" /> that will be written in the image</param>
/// <param name="options">Options to be used when creating new image</param>
/// <param name="sectors">How many sectors the media has.</param>
/// <param name="sectorSize"></param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool Create(string path, MediaType mediaType, Dictionary<string, string> options, ulong sectors,
uint sectorSize);
/// <summary>
/// Writes a media tag to the image
/// </summary>
/// <param name="data">Media tag</param>
/// <param name="tag">
/// <see cref="MediaTagType" />
/// </param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteMediaTag(byte[] data, MediaTagType tag);
/// <summary>
/// Writes a sector to the image
/// </summary>
/// <param name="data">Sector data</param>
/// <param name="sectorAddress">Sector address</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSector(byte[] data, ulong sectorAddress);
/// <summary>
/// Writes several sectors to the image
/// </summary>
/// <param name="data">Sectors data</param>
/// <param name="sectorAddress">Sector starting address</param>
/// <param name="length">How many sectors to write</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSectors(byte[] data, ulong sectorAddress, uint length);
/// <summary>
/// Writes a sector to the image with main channel tags attached
/// </summary>
/// <param name="data">Sector data with its main channel tags attached</param>
/// <param name="sectorAddress">Sector address</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSectorLong(byte[] data, ulong sectorAddress);
/// <summary>
/// Writes several sectors to the image
/// </summary>
/// <param name="data">Sector data with their main channel tags attached</param>
/// <param name="sectorAddress">Sector starting address</param>
/// <param name="length">How many sectors to write</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSectorsLong(byte[] data, ulong sectorAddress, uint length);
/// <summary>
/// Sets tracks for optical media
/// </summary>
/// <param name="tracks">List of tracks</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool SetTracks(List<Track> tracks);
/// <summary>
/// Closes and flushes to disk the image
/// </summary>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool Close();
/// <summary>
/// Sets image metadata
/// </summary>
/// <param name="metadata"><see cref="ImageInfo" /> containing image metadata</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool SetMetadata(ImageInfo metadata);
/// <summary>
/// Sets media geometry
/// </summary>
/// <param name="cylinders">Cylinders</param>
/// <param name="heads">Heads</param>
/// <param name="sectorsPerTrack">Sectors per track</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool SetGeometry(uint cylinders, uint heads, uint sectorsPerTrack);
/// <summary>
/// Writes parallel or subchannel sector tag for one sector
/// </summary>
/// <param name="data">Tag data to write</param>
/// <param name="sectorAddress">Sector address</param>
/// <param name="tag">Tag type</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSectorTag(byte[] data, ulong sectorAddress, SectorTagType tag);
/// <summary>
/// Writes parallel or subchannel sector tag for several sector
/// </summary>
/// <param name="data">Tag data to write</param>
/// <param name="sectorAddress">Starting sector address</param>
/// <param name="length">How many sectors to write</param>
/// <param name="tag">Tag type</param>
/// <returns><c>true</c> if operating completed successfully, <c>false</c> otherwise</returns>
bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag);
/// <summary>
/// Sets the list of dump hardware used to create the image from real media
/// </summary>
bool SetDumpHardware(List<DumpHardwareType> dumpHardware);
/// <summary>
/// Sets the CICM XML metadata for the image
/// </summary>
bool SetCicmMetadata(CICMMetadataType metadata);
}
}

306
Interop/DetectOS.cs Normal file
View File

@@ -0,0 +1,306 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : DetectOS.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Interop services.
//
// --[ Description ] ----------------------------------------------------------
//
// Detects underlying operating system.
//
// --[ License ] --------------------------------------------------------------
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace DiscImageChef.CommonTypes.Interop
{
public static class DetectOS
{
public static readonly bool IsMono = Type.GetType("Mono.Runtime") != null;
/// <summary>
/// Checks if the underlying runtime runs in 64-bit mode
/// </summary>
public static readonly bool Is64Bit = IntPtr.Size == 8;
/// <summary>
/// Checks if the underlying runtime runs in 32-bit mode
/// </summary>
public static readonly bool Is32Bit = IntPtr.Size == 4;
[DllImport("libc", SetLastError = true)]
static extern int uname(out utsname name);
[DllImport("libc", SetLastError = true, EntryPoint = "sysctlbyname", CharSet = CharSet.Ansi)]
static extern int OSX_sysctlbyname(string name, IntPtr oldp, IntPtr oldlenp, IntPtr newp, uint newlen);
/// <summary>
/// Gets the real platform ID, not the incomplete .NET framework one
/// </summary>
/// <returns>Platform ID</returns>
/// <exception cref="Exception">Unhandled exception</exception>
public static PlatformID GetRealPlatformID()
{
if((int)Environment.OSVersion.Platform < 4 || (int)Environment.OSVersion.Platform == 5)
return (PlatformID)(int)Environment.OSVersion.Platform;
int error = uname(out utsname unixname);
if(error != 0) throw new Exception($"Unhandled exception calling uname: {Marshal.GetLastWin32Error()}");
switch(unixname.sysname)
{
// TODO: Differentiate Linux, Android, Tizen
case "Linux":
{
#if __ANDROID__
return PlatformID.Android;
#else
return PlatformID.Linux;
#endif
}
case "Darwin":
{
IntPtr pLen = Marshal.AllocHGlobal(sizeof(int));
int osxError = OSX_sysctlbyname("hw.machine", IntPtr.Zero, pLen, IntPtr.Zero, 0);
if(osxError != 0)
{
Marshal.FreeHGlobal(pLen);
throw new Exception($"Unhandled exception calling uname: {Marshal.GetLastWin32Error()}");
}
int length = Marshal.ReadInt32(pLen);
IntPtr pStr = Marshal.AllocHGlobal(length);
osxError = OSX_sysctlbyname("hw.machine", pStr, pLen, IntPtr.Zero, 0);
if(osxError != 0)
{
Marshal.FreeHGlobal(pStr);
Marshal.FreeHGlobal(pLen);
throw new Exception($"Unhandled exception calling uname: {Marshal.GetLastWin32Error()}");
}
string machine = Marshal.PtrToStringAnsi(pStr);
Marshal.FreeHGlobal(pStr);
Marshal.FreeHGlobal(pLen);
if(machine != null && (machine.StartsWith("iPad", StringComparison.Ordinal) ||
machine.StartsWith("iPod", StringComparison.Ordinal) ||
machine.StartsWith("iPhone", StringComparison.Ordinal)))
return PlatformID.iOS;
return PlatformID.MacOSX;
}
case "GNU": return PlatformID.Hurd;
case "FreeBSD":
case "GNU/kFreeBSD": return PlatformID.FreeBSD;
case "DragonFly": return PlatformID.DragonFly;
case "Haiku": return PlatformID.Haiku;
case "HP-UX": return PlatformID.HPUX;
case "AIX": return PlatformID.AIX;
case "OS400": return PlatformID.OS400;
case "IRIX":
case "IRIX64": return PlatformID.IRIX;
case "Minix": return PlatformID.Minix;
case "NetBSD": return PlatformID.NetBSD;
case "NONSTOP_KERNEL": return PlatformID.NonStop;
case "OpenBSD": return PlatformID.OpenBSD;
case "QNX": return PlatformID.QNX;
case "SINIX-Y": return PlatformID.SINIX;
case "SunOS": return PlatformID.Solaris;
case "OSF1": return PlatformID.Tru64;
case "ULTRIX": return PlatformID.Ultrix;
case "SCO_SV": return PlatformID.OpenServer;
case "UnixWare": return PlatformID.UnixWare;
case "Interix":
case "UWIN-W7": return PlatformID.Win32NT;
default:
{
if(unixname.sysname.StartsWith("CYGWIN_NT", StringComparison.Ordinal) ||
unixname.sysname.StartsWith("MINGW32_NT", StringComparison.Ordinal) ||
unixname.sysname.StartsWith("MSYS_NT", StringComparison.Ordinal) ||
unixname.sysname.StartsWith("UWIN", StringComparison.Ordinal)) return PlatformID.Win32NT;
return PlatformID.Unknown;
}
}
}
/// <summary>
/// Gets a string for the current operating system REAL version (handles Darwin 1.4 and Windows 10 falsifying)
/// </summary>
/// <returns>Current operating system version</returns>
public static string GetVersion()
{
string environ = Environment.OSVersion.Version.ToString();
switch(GetRealPlatformID())
{
case PlatformID.MacOSX:
if(Environment.OSVersion.Version.Major != 1)
return $"10.{Environment.OSVersion.Version.Major - 4}.{Environment.OSVersion.Version.Minor}";
switch(Environment.OSVersion.Version.Minor)
{
case 3: return "10.0";
case 4: return "10.1";
}
goto default;
case PlatformID.Win32NT:
// From Windows 8.1 the reported version is simply falsified...
if(Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Major >= 2 ||
Environment.OSVersion.Version.Major > 6)
return FileVersionInfo
.GetVersionInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),
"KERNEL32.DLL")).ProductVersion;
return environ;
default: return environ;
}
}
/// <summary>
/// From a platform ID and version returns a human-readable version
/// </summary>
/// <param name="id">Platform ID</param>
/// <param name="version">Version number</param>
/// <returns>Operating system name</returns>
public static string GetPlatformName(PlatformID id, string version = null)
{
switch(id)
{
case PlatformID.AIX: return "AIX";
case PlatformID.Android: return "Android";
case PlatformID.DragonFly: return "DragonFly BSD";
case PlatformID.FreeBSD: return "FreeBSD";
case PlatformID.Haiku: return "Haiku";
case PlatformID.HPUX: return "HP/UX";
case PlatformID.Hurd: return "Hurd";
case PlatformID.iOS: return "iOS";
case PlatformID.IRIX: return "IRIX";
case PlatformID.Linux: return "Linux";
case PlatformID.MacOSX:
if(string.IsNullOrEmpty(version)) return "macOS";
string[] pieces = version.Split('.');
if(pieces.Length < 2 || !int.TryParse(pieces[1], out int minor)) return "macOS";
if(minor >= 12) return "macOS";
if(minor >= 8) return "OS X";
return "Mac OS X";
case PlatformID.Minix: return "MINIX";
case PlatformID.NetBSD: return "NetBSD";
case PlatformID.NonStop: return "NonStop OS";
case PlatformID.OpenBSD: return "OpenBSD";
case PlatformID.OpenServer: return "SCO OpenServer";
case PlatformID.OS400: return "OS/400";
case PlatformID.PlayStation3: return "Sony CellOS";
case PlatformID.PlayStation4: return "Sony Orbis OS";
case PlatformID.QNX: return "QNX";
case PlatformID.SINIX: return "SINIX";
case PlatformID.Solaris: return "Sun Solaris";
case PlatformID.Tizen: return "Samsung Tizen";
case PlatformID.Tru64: return "Tru64 UNIX";
case PlatformID.Ultrix: return "Ultrix";
case PlatformID.Unix: return "UNIX";
case PlatformID.UnixWare: return "SCO UnixWare";
case PlatformID.Wii: return "Nintendo Wii";
case PlatformID.WiiU: return "Nintendo Wii U";
case PlatformID.Win32NT:
if(string.IsNullOrEmpty(version)) return "Windows NT/2000/XP/Vista/7/10";
if(version.StartsWith("3.", StringComparison.Ordinal) ||
version.StartsWith("4.", StringComparison.Ordinal)) return "Windows NT";
if(version.StartsWith("5.0", StringComparison.Ordinal)) return "Windows 2000";
if(version.StartsWith("5.1", StringComparison.Ordinal)) return "Windows XP";
if(version.StartsWith("5.2", StringComparison.Ordinal)) return "Windows 2003";
if(version.StartsWith("6.0", StringComparison.Ordinal)) return "Windows Vista";
if(version.StartsWith("6.1", StringComparison.Ordinal)) return "Windows 7";
if(version.StartsWith("6.2", StringComparison.Ordinal)) return "Windows 8";
if(version.StartsWith("6.3", StringComparison.Ordinal)) return "Windows 8.1";
if(version.StartsWith("10.0", StringComparison.Ordinal)) return "Windows 10";
return "Windows NT/2000/XP/Vista/7/10";
case PlatformID.Win32S: return "Windows 3.x with win32s";
case PlatformID.Win32Windows:
if(string.IsNullOrEmpty(version)) return "Windows 9x/Me";
if(version.StartsWith("4.0", StringComparison.Ordinal)) return "Windows 95";
if(version.StartsWith("4.10.2222", StringComparison.Ordinal)) return "Windows 98 SE";
if(version.StartsWith("4.1", StringComparison.Ordinal)) return "Windows 98";
if(version.StartsWith("4.9", StringComparison.Ordinal)) return "Windows Me";
return "Windows 9x/Me";
case PlatformID.WinCE: return "Windows CE/Mobile";
case PlatformID.WindowsPhone: return "Windows Phone";
case PlatformID.Xbox: return "Xbox OS";
case PlatformID.zOS: return "z/OS";
default: return id.ToString();
}
}
/// <summary>
/// POSIX uname structure, size from OSX, big enough to handle extra fields
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct utsname
{
/// <summary>
/// System name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string sysname;
/// <summary>
/// Node name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string nodename;
/// <summary>
/// Release level
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string release;
/// <summary>
/// Version level
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string version;
/// <summary>
/// Hardware level
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string machine;
}
}
}

192
Interop/PlatformID.cs Normal file
View File

@@ -0,0 +1,192 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : PlatformID.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Interop services.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains an enhanced PlatformID enumeration.
//
// --[ License ] --------------------------------------------------------------
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
namespace DiscImageChef.CommonTypes.Interop
{
/// <summary>
/// Contains an arbitrary list of OSes, even if .NET does not run on them
/// </summary>
public enum PlatformID
{
/// <summary>
/// Win32s
/// </summary>
Win32S = 0,
/// <summary>
/// Win32 (Windows 9x)
/// </summary>
Win32Windows = 1,
/// <summary>
/// Windows NT
/// </summary>
Win32NT = 2,
/// <summary>
/// Windows Mobile
/// </summary>
WinCE = 3,
/// <summary>
/// UNIX (do not use, too generic)
/// </summary>
Unix = 4,
/// <summary>
/// Xbox 360
/// </summary>
Xbox = 5,
/// <summary>
/// OS X
/// </summary>
MacOSX = 6,
/// <summary>
/// iOS is not OS X
/// </summary>
iOS = 7,
/// <summary>
/// Linux
/// </summary>
Linux = 8,
/// <summary>
/// Sun Solaris
/// </summary>
Solaris = 9,
/// <summary>
/// NetBSD
/// </summary>
NetBSD = 10,
/// <summary>
/// OpenBSD
/// </summary>
OpenBSD = 11,
/// <summary>
/// FreeBSD
/// </summary>
FreeBSD = 12,
/// <summary>
/// DragonFly BSD
/// </summary>
DragonFly = 13,
/// <summary>
/// Nintendo Wii
/// </summary>
Wii = 14,
/// <summary>
/// Nintendo Wii U
/// </summary>
WiiU = 15,
/// <summary>
/// Sony PlayStation 3
/// </summary>
PlayStation3 = 16,
/// <summary>
/// Sony Playstation 4
/// </summary>
PlayStation4 = 17,
/// <summary>
/// Google Android
/// </summary>
Android = 18,
/// <summary>
/// Samsung Tizen
/// </summary>
Tizen = 19,
/// <summary>
/// Windows Phone
/// </summary>
WindowsPhone = 20,
/// <summary>
/// GNU/Hurd
/// </summary>
Hurd = 21,
/// <summary>
/// Haiku
/// </summary>
Haiku = 22,
/// <summary>
/// HP-UX
/// </summary>
HPUX = 23,
/// <summary>
/// AIX
/// </summary>
AIX = 24,
/// <summary>
/// OS/400
/// </summary>
OS400 = 25,
/// <summary>
/// IRIX
/// </summary>
IRIX = 26,
/// <summary>
/// Minix
/// </summary>
Minix = 27,
/// <summary>
/// NonStop
/// </summary>
NonStop = 28,
/// <summary>
/// QNX
/// </summary>
QNX = 29,
/// <summary>
/// SINIX
/// </summary>
SINIX = 30,
/// <summary>
/// Tru64 UNIX
/// </summary>
Tru64 = 31,
/// <summary>
/// Ultrix
/// </summary>
Ultrix = 32,
/// <summary>
/// SCO OpenServer / SCO UNIX
/// </summary>
OpenServer = 33,
/// <summary>
/// SCO UnixWare
/// </summary>
UnixWare = 34,
/// <summary>
/// IBM z/OS
/// </summary>
zOS = 35,
Unknown = -1
}
}

79
Interop/Version.cs Normal file
View File

@@ -0,0 +1,79 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Version.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Interop services.
//
// --[ Description ] ----------------------------------------------------------
//
// Returns DiscImageChef version.
//
// --[ License ] --------------------------------------------------------------
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Reflection;
using System.Runtime;
namespace DiscImageChef.CommonTypes.Interop
{
public static class Version
{
/// <summary>
/// Gets version string
/// </summary>
/// <returns>Version</returns>
public static string GetVersion()
{
return typeof(Version).Assembly.GetName().Version.ToString();
}
public static string GetNetCoreVersion()
{
Assembly assembly = typeof(GCSettings).Assembly;
string[] assemblyPath =
assembly.CodeBase.Split(new[] {'/', '\\'}, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if(netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];
return null;
}
public static string GetMonoVersion()
{
if(!DetectOS.IsMono) return null;
MethodInfo monoDisplayName = Type.GetType("Mono.Runtime")
?.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
if(monoDisplayName != null) return (string)monoDisplayName.Invoke(null, null);
return null;
}
}
}

1051
Metadata/DeviceReport.cs Normal file

File diff suppressed because it is too large Load Diff

922
Metadata/Dimensions.cs Normal file
View File

@@ -0,0 +1,922 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Dimensions.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : XML metadata.
//
// --[ Description ] ----------------------------------------------------------
//
// Gets physical dimensions of a device/media based on its media type.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using Schemas;
namespace DiscImageChef.CommonTypes.Metadata
{
public static class Dimensions
{
public static DimensionsType DimensionsFromMediaType(CommonTypes.MediaType dskType)
{
DimensionsType dmns = new DimensionsType();
switch(dskType)
{
#region 5.25" floppy disk
case CommonTypes.MediaType.Apple32SS:
case CommonTypes.MediaType.Apple32DS:
case CommonTypes.MediaType.Apple33SS:
case CommonTypes.MediaType.Apple33DS:
case CommonTypes.MediaType.AppleFileWare:
case CommonTypes.MediaType.DOS_525_SS_DD_8:
case CommonTypes.MediaType.DOS_525_SS_DD_9:
case CommonTypes.MediaType.DOS_525_DS_DD_8:
case CommonTypes.MediaType.DOS_525_DS_DD_9:
case CommonTypes.MediaType.DOS_525_HD:
case CommonTypes.MediaType.XDF_525:
case CommonTypes.MediaType.ACORN_525_SS_SD_40:
case CommonTypes.MediaType.ACORN_525_SS_SD_80:
case CommonTypes.MediaType.ACORN_525_SS_DD_40:
case CommonTypes.MediaType.ACORN_525_SS_DD_80:
case CommonTypes.MediaType.ACORN_525_DS_DD:
case CommonTypes.MediaType.ATARI_525_SD:
case CommonTypes.MediaType.ATARI_525_ED:
case CommonTypes.MediaType.ATARI_525_DD:
case CommonTypes.MediaType.CBM_1540:
case CommonTypes.MediaType.CBM_1540_Ext:
case CommonTypes.MediaType.CBM_1571:
case CommonTypes.MediaType.ECMA_66:
case CommonTypes.MediaType.ECMA_70:
case CommonTypes.MediaType.NEC_525_HD:
case CommonTypes.MediaType.ECMA_78:
case CommonTypes.MediaType.ECMA_78_2:
case CommonTypes.MediaType.ECMA_99_8:
case CommonTypes.MediaType.ECMA_99_15:
case CommonTypes.MediaType.ECMA_99_26:
case CommonTypes.MediaType.FDFORMAT_525_DD:
case CommonTypes.MediaType.FDFORMAT_525_HD:
// According to ECMA-99 et al
dmns.Height = 133.3;
dmns.HeightSpecified = true;
dmns.Width = 133.3;
dmns.WidthSpecified = true;
dmns.Thickness = 1.65;
return dmns;
#endregion 5.25" floppy disk
#region 3.5" floppy disk
case CommonTypes.MediaType.AppleSonySS:
case CommonTypes.MediaType.AppleSonyDS:
case CommonTypes.MediaType.DOS_35_SS_DD_8:
case CommonTypes.MediaType.DOS_35_SS_DD_9:
case CommonTypes.MediaType.DOS_35_DS_DD_8:
case CommonTypes.MediaType.DOS_35_DS_DD_9:
case CommonTypes.MediaType.DOS_35_HD:
case CommonTypes.MediaType.DOS_35_ED:
case CommonTypes.MediaType.DMF:
case CommonTypes.MediaType.DMF_82:
case CommonTypes.MediaType.XDF_35:
case CommonTypes.MediaType.ACORN_35_DS_DD:
case CommonTypes.MediaType.CBM_35_DD:
case CommonTypes.MediaType.CBM_AMIGA_35_DD:
case CommonTypes.MediaType.CBM_AMIGA_35_HD:
case CommonTypes.MediaType.FDFORMAT_35_DD:
case CommonTypes.MediaType.FDFORMAT_35_HD:
case CommonTypes.MediaType.NEC_35_HD_8:
case CommonTypes.MediaType.NEC_35_HD_15:
case CommonTypes.MediaType.Floptical:
case CommonTypes.MediaType.HiFD:
case CommonTypes.MediaType.UHD144:
case CommonTypes.MediaType.Apricot_35:
case CommonTypes.MediaType.FD32MB:
// According to ECMA-100 et al
dmns.Height = 94;
dmns.HeightSpecified = true;
dmns.Width = 90;
dmns.WidthSpecified = true;
dmns.Thickness = 3.3;
return dmns;
#endregion 3.5" floppy disk
#region 8" floppy disk
case CommonTypes.MediaType.IBM23FD:
case CommonTypes.MediaType.IBM33FD_128:
case CommonTypes.MediaType.IBM33FD_256:
case CommonTypes.MediaType.IBM33FD_512:
case CommonTypes.MediaType.IBM43FD_128:
case CommonTypes.MediaType.IBM43FD_256:
case CommonTypes.MediaType.IBM53FD_256:
case CommonTypes.MediaType.IBM53FD_512:
case CommonTypes.MediaType.IBM53FD_1024:
case CommonTypes.MediaType.RX01:
case CommonTypes.MediaType.RX02:
case CommonTypes.MediaType.NEC_8_SD:
case CommonTypes.MediaType.NEC_8_DD:
case CommonTypes.MediaType.ECMA_54:
case CommonTypes.MediaType.ECMA_59:
case CommonTypes.MediaType.ECMA_69_8:
case CommonTypes.MediaType.ECMA_69_15:
case CommonTypes.MediaType.ECMA_69_26:
// According to ECMA-59 et al
dmns.Height = 203.2;
dmns.HeightSpecified = true;
dmns.Width = 203.2;
dmns.WidthSpecified = true;
dmns.Thickness = 1.65;
return dmns;
#endregion 8" floppy disk
#region 356mm magneto optical
case CommonTypes.MediaType.ECMA_260:
case CommonTypes.MediaType.ECMA_260_Double:
// According to ECMA-260 et al
dmns.Height = 421.84;
dmns.HeightSpecified = true;
dmns.Width = 443.76;
dmns.WidthSpecified = true;
dmns.Thickness = 25.4;
return dmns;
#endregion 356mm magneto optical
#region 300mm magneto optical
case CommonTypes.MediaType.ECMA_189:
case CommonTypes.MediaType.ECMA_190:
case CommonTypes.MediaType.ECMA_317:
// According to ECMA-317 et al
dmns.Height = 340;
dmns.HeightSpecified = true;
dmns.Width = 320;
dmns.WidthSpecified = true;
dmns.Thickness = 17;
return dmns;
#endregion 300mm magneto optical
#region 5.25" magneto optical
case CommonTypes.MediaType.ECMA_153:
case CommonTypes.MediaType.ECMA_153_512:
case CommonTypes.MediaType.ECMA_183_512:
case CommonTypes.MediaType.ECMA_183:
case CommonTypes.MediaType.ECMA_184_512:
case CommonTypes.MediaType.ECMA_184:
case CommonTypes.MediaType.ECMA_195:
case CommonTypes.MediaType.ECMA_195_512:
case CommonTypes.MediaType.ECMA_238:
case CommonTypes.MediaType.ECMA_280:
case CommonTypes.MediaType.ECMA_322:
case CommonTypes.MediaType.ECMA_322_2k:
case CommonTypes.MediaType.UDO:
case CommonTypes.MediaType.UDO2:
case CommonTypes.MediaType.UDO2_WORM:
// According to ECMA-183 et al
dmns.Height = 153;
dmns.HeightSpecified = true;
dmns.Width = 135;
dmns.WidthSpecified = true;
dmns.Thickness = 11;
return dmns;
#endregion 5.25" magneto optical
#region 3.5" magneto optical
case CommonTypes.MediaType.ECMA_154:
case CommonTypes.MediaType.ECMA_201:
case CommonTypes.MediaType.ECMA_201_ROM:
case CommonTypes.MediaType.ECMA_223:
case CommonTypes.MediaType.ECMA_223_512:
case CommonTypes.MediaType.GigaMo:
case CommonTypes.MediaType.GigaMo2:
// According to ECMA-154 et al
dmns.Height = 94;
dmns.HeightSpecified = true;
dmns.Width = 90;
dmns.WidthSpecified = true;
dmns.Thickness = 6;
return dmns;
#endregion 3.5" magneto optical
case CommonTypes.MediaType.PD650:
case CommonTypes.MediaType.PD650_WORM:
dmns.Height = 135;
dmns.HeightSpecified = true;
dmns.Width = 124;
dmns.WidthSpecified = true;
dmns.Thickness = 7.8;
return dmns;
case CommonTypes.MediaType.ECMA_239:
dmns.Height = 97;
dmns.HeightSpecified = true;
dmns.Width = 92;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.MMCmicro:
dmns.Height = 14;
dmns.HeightSpecified = true;
dmns.Width = 12;
dmns.WidthSpecified = true;
dmns.Thickness = 1.1;
return dmns;
case CommonTypes.MediaType.MemoryStickMicro:
dmns.Height = 15;
dmns.HeightSpecified = true;
dmns.Width = 12.5;
dmns.WidthSpecified = true;
dmns.Thickness = 1.2;
return dmns;
case CommonTypes.MediaType.microSD:
dmns.Height = 11;
dmns.HeightSpecified = true;
dmns.Width = 15;
dmns.WidthSpecified = true;
dmns.Thickness = 1;
return dmns;
case CommonTypes.MediaType.miniSD:
dmns.Height = 21.5;
dmns.HeightSpecified = true;
dmns.Width = 20;
dmns.WidthSpecified = true;
dmns.Thickness = 1.4;
return dmns;
case CommonTypes.MediaType.QIC3010:
case CommonTypes.MediaType.QIC3020:
case CommonTypes.MediaType.QIC3080:
case CommonTypes.MediaType.QIC3095:
case CommonTypes.MediaType.QIC320:
case CommonTypes.MediaType.QIC40:
case CommonTypes.MediaType.QIC80:
dmns.Height = 20;
dmns.HeightSpecified = true;
dmns.Width = 21.5;
dmns.WidthSpecified = true;
dmns.Thickness = 1.6;
return dmns;
case CommonTypes.MediaType.RSMMC:
dmns.Height = 18;
dmns.HeightSpecified = true;
dmns.Width = 24;
dmns.WidthSpecified = true;
dmns.Thickness = 1.4;
return dmns;
case CommonTypes.MediaType.MMC:
dmns.Height = 32;
dmns.HeightSpecified = true;
dmns.Width = 24;
dmns.WidthSpecified = true;
dmns.Thickness = 1.4;
return dmns;
case CommonTypes.MediaType.SecureDigital:
dmns.Height = 32;
dmns.HeightSpecified = true;
dmns.Width = 24;
dmns.WidthSpecified = true;
dmns.Thickness = 2.1;
return dmns;
case CommonTypes.MediaType.xD:
dmns.Height = 20;
dmns.HeightSpecified = true;
dmns.Width = 25;
dmns.WidthSpecified = true;
dmns.Thickness = 1.78;
return dmns;
case CommonTypes.MediaType.XQD:
dmns.Height = 38.5;
dmns.HeightSpecified = true;
dmns.Width = 29.8;
dmns.WidthSpecified = true;
dmns.Thickness = 3.8;
return dmns;
case CommonTypes.MediaType.MemoryStickDuo:
case CommonTypes.MediaType.MemoryStickProDuo:
dmns.Height = 20;
dmns.HeightSpecified = true;
dmns.Width = 31;
dmns.WidthSpecified = true;
dmns.Thickness = 1.6;
return dmns;
case CommonTypes.MediaType.Nintendo3DSGameCard:
case CommonTypes.MediaType.NintendoDSGameCard:
case CommonTypes.MediaType.NintendoDSiGameCard:
dmns.Height = 35;
dmns.HeightSpecified = true;
dmns.Width = 33;
dmns.WidthSpecified = true;
dmns.Thickness = 3.8;
return dmns;
case CommonTypes.MediaType.DataPlay:
dmns.Height = 42;
dmns.HeightSpecified = true;
dmns.Width = 33.5;
dmns.WidthSpecified = true;
dmns.Thickness = 3;
return dmns;
case CommonTypes.MediaType.Microdrive:
dmns.Height = 44;
dmns.HeightSpecified = true;
dmns.Width = 34;
dmns.WidthSpecified = true;
dmns.Thickness = 8;
return dmns;
case CommonTypes.MediaType.ExpressCard34:
dmns.Height = 75;
dmns.HeightSpecified = true;
dmns.Width = 34;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.SmartMedia:
dmns.Height = 45;
dmns.HeightSpecified = true;
dmns.Width = 37;
dmns.WidthSpecified = true;
dmns.Thickness = 0.76;
return dmns;
case CommonTypes.MediaType.MiniCard:
dmns.Height = 45;
dmns.HeightSpecified = true;
dmns.Width = 37;
dmns.WidthSpecified = true;
dmns.Thickness = 3.5;
return dmns;
case CommonTypes.MediaType.PlayStationMemoryCard:
case CommonTypes.MediaType.PlayStationMemoryCard2:
dmns.Height = 55.7;
dmns.HeightSpecified = true;
dmns.Width = 41.5;
dmns.WidthSpecified = true;
dmns.Thickness = 7;
return dmns;
case CommonTypes.MediaType.CFast:
case CommonTypes.MediaType.CompactFlash:
dmns.Height = 36;
dmns.HeightSpecified = true;
dmns.Width = 43;
dmns.WidthSpecified = true;
dmns.Thickness = 3.3;
return dmns;
case CommonTypes.MediaType.CompactFlashType2:
dmns.Height = 36;
dmns.HeightSpecified = true;
dmns.Width = 43;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.ZXMicrodrive:
dmns.Height = 36;
dmns.HeightSpecified = true;
dmns.Width = 43;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.MemoryStick:
case CommonTypes.MediaType.MemoryStickPro:
dmns.Height = 21;
dmns.HeightSpecified = true;
dmns.Width = 50;
dmns.WidthSpecified = true;
dmns.Thickness = 2.6;
return dmns;
case CommonTypes.MediaType.PocketZip:
dmns.Height = 54.5;
dmns.HeightSpecified = true;
dmns.Width = 50;
dmns.WidthSpecified = true;
dmns.Thickness = 2;
return dmns;
case CommonTypes.MediaType.ExpressCard54:
dmns.Height = 75;
dmns.HeightSpecified = true;
dmns.Width = 54;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.PCCardTypeI:
dmns.Height = 85.6;
dmns.HeightSpecified = true;
dmns.Width = 54;
dmns.WidthSpecified = true;
dmns.Thickness = 3.3;
return dmns;
case CommonTypes.MediaType.PCCardTypeII:
dmns.Height = 85.6;
dmns.HeightSpecified = true;
dmns.Width = 54;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.PCCardTypeIII:
dmns.Height = 85.6;
dmns.HeightSpecified = true;
dmns.Width = 54;
dmns.WidthSpecified = true;
dmns.Thickness = 10.5;
return dmns;
case CommonTypes.MediaType.PCCardTypeIV:
dmns.Height = 85.6;
dmns.HeightSpecified = true;
dmns.Width = 54;
dmns.WidthSpecified = true;
dmns.Thickness = 16;
return dmns;
case CommonTypes.MediaType.DataStore:
dmns.Height = 86.5;
dmns.HeightSpecified = true;
dmns.Width = 54;
dmns.WidthSpecified = true;
dmns.Thickness = 2.5;
return dmns;
case CommonTypes.MediaType.VideoFloppy:
dmns.Height = 54;
dmns.HeightSpecified = true;
dmns.Width = 60;
dmns.WidthSpecified = true;
dmns.Thickness = 3.5;
return dmns;
case CommonTypes.MediaType.VXA1:
case CommonTypes.MediaType.VXA2:
case CommonTypes.MediaType.VXA3:
dmns.Height = 95;
dmns.HeightSpecified = true;
dmns.Width = 62.5;
dmns.WidthSpecified = true;
dmns.Thickness = 15;
return dmns;
case CommonTypes.MediaType.MiniDV:
dmns.Height = 47.5;
dmns.HeightSpecified = true;
dmns.Width = 66;
dmns.WidthSpecified = true;
dmns.Thickness = 12;
return dmns;
case CommonTypes.MediaType.Wafer:
dmns.Height = 46.8;
dmns.HeightSpecified = true;
dmns.Width = 67.1;
dmns.WidthSpecified = true;
dmns.Thickness = 7.9;
return dmns;
case CommonTypes.MediaType.NintendoDiskCard:
dmns.Height = 76.2;
dmns.HeightSpecified = true;
dmns.Width = 71.12;
dmns.WidthSpecified = true;
dmns.Thickness = 0;
return dmns;
case CommonTypes.MediaType.HiMD:
case CommonTypes.MediaType.MD:
case CommonTypes.MediaType.MDData:
case CommonTypes.MediaType.MDData2:
dmns.Height = 68;
dmns.HeightSpecified = true;
dmns.Width = 71.5;
dmns.WidthSpecified = true;
dmns.Thickness = 4.8;
return dmns;
case CommonTypes.MediaType.DAT160:
case CommonTypes.MediaType.DAT320:
case CommonTypes.MediaType.DAT72:
case CommonTypes.MediaType.DDS1:
case CommonTypes.MediaType.DDS2:
case CommonTypes.MediaType.DDS3:
case CommonTypes.MediaType.DDS4:
case CommonTypes.MediaType.DigitalAudioTape:
dmns.Height = 54;
dmns.HeightSpecified = true;
dmns.Width = 73;
dmns.WidthSpecified = true;
dmns.Thickness = 10.5;
return dmns;
case CommonTypes.MediaType.CompactFloppy:
dmns.Height = 100;
dmns.HeightSpecified = true;
dmns.Width = 80;
dmns.WidthSpecified = true;
dmns.Thickness = 5;
return dmns;
case CommonTypes.MediaType.DECtapeII:
dmns.Height = 60;
dmns.HeightSpecified = true;
dmns.Width = 81;
dmns.WidthSpecified = true;
dmns.Thickness = 13;
return dmns;
case CommonTypes.MediaType.Ditto:
dmns.Height = 60;
dmns.HeightSpecified = true;
dmns.Width = 81;
dmns.WidthSpecified = true;
dmns.Thickness = 14;
return dmns;
case CommonTypes.MediaType.DittoMax:
dmns.Height = 126;
dmns.HeightSpecified = true;
dmns.Width = 81;
dmns.WidthSpecified = true;
dmns.Thickness = 14;
return dmns;
case CommonTypes.MediaType.RDX:
case CommonTypes.MediaType.RDX320:
dmns.Height = 119;
dmns.HeightSpecified = true;
dmns.Width = 87;
dmns.WidthSpecified = true;
dmns.Thickness = 23;
return dmns;
case CommonTypes.MediaType.LS120:
case CommonTypes.MediaType.LS240:
dmns.Height = 94;
dmns.HeightSpecified = true;
dmns.Width = 90;
dmns.WidthSpecified = true;
dmns.Thickness = 3.5;
return dmns;
case CommonTypes.MediaType.Travan:
case CommonTypes.MediaType.Travan3:
case CommonTypes.MediaType.Travan4:
case CommonTypes.MediaType.Travan5:
case CommonTypes.MediaType.Travan7:
dmns.Height = 72;
dmns.HeightSpecified = true;
dmns.Width = 92;
dmns.WidthSpecified = true;
dmns.Thickness = 15;
return dmns;
case CommonTypes.MediaType.Travan1Ex:
dmns.Height = 0;
dmns.HeightSpecified = true;
dmns.Width = 92;
dmns.WidthSpecified = true;
dmns.Thickness = 15;
return dmns;
case CommonTypes.MediaType.Travan3Ex:
dmns.Height = 0;
dmns.HeightSpecified = true;
dmns.Width = 92;
dmns.WidthSpecified = true;
dmns.Thickness = 15;
return dmns;
case CommonTypes.MediaType.ADR2120:
case CommonTypes.MediaType.ADR260:
case CommonTypes.MediaType.ADR30:
case CommonTypes.MediaType.ADR50:
dmns.Height = 129;
dmns.HeightSpecified = true;
dmns.Width = 93;
dmns.WidthSpecified = true;
dmns.Thickness = 14.5;
return dmns;
case CommonTypes.MediaType.Data8:
case CommonTypes.MediaType.AIT1:
case CommonTypes.MediaType.AIT1Turbo:
case CommonTypes.MediaType.AIT2:
case CommonTypes.MediaType.AIT2Turbo:
case CommonTypes.MediaType.AIT3:
case CommonTypes.MediaType.AIT3Ex:
case CommonTypes.MediaType.AIT3Turbo:
case CommonTypes.MediaType.AIT4:
case CommonTypes.MediaType.AIT5:
case CommonTypes.MediaType.AITETurbo:
case CommonTypes.MediaType.Exatape106m:
case CommonTypes.MediaType.Exatape160mXL:
case CommonTypes.MediaType.Exatape112m:
case CommonTypes.MediaType.Exatape125m:
case CommonTypes.MediaType.Exatape150m:
case CommonTypes.MediaType.Exatape15m:
case CommonTypes.MediaType.Exatape170m:
case CommonTypes.MediaType.Exatape225m:
case CommonTypes.MediaType.Exatape22m:
case CommonTypes.MediaType.Exatape22mAME:
case CommonTypes.MediaType.Exatape28m:
case CommonTypes.MediaType.Exatape40m:
case CommonTypes.MediaType.Exatape45m:
case CommonTypes.MediaType.Exatape54m:
case CommonTypes.MediaType.Exatape75m:
case CommonTypes.MediaType.Exatape76m:
case CommonTypes.MediaType.Exatape80m:
dmns.Height = 62.5;
dmns.HeightSpecified = true;
dmns.Width = 95;
dmns.WidthSpecified = true;
dmns.Thickness = 15;
return dmns;
case CommonTypes.MediaType.EZ135:
case CommonTypes.MediaType.EZ230:
dmns.Height = 97;
dmns.HeightSpecified = true;
dmns.Width = 98;
dmns.WidthSpecified = true;
dmns.Thickness = 9.5;
return dmns;
case CommonTypes.MediaType.ZIP100:
case CommonTypes.MediaType.ZIP250:
case CommonTypes.MediaType.ZIP750:
dmns.Height = 98.5;
dmns.HeightSpecified = true;
dmns.Width = 98;
dmns.WidthSpecified = true;
dmns.Thickness = 6.5;
return dmns;
case CommonTypes.MediaType.Jaz:
case CommonTypes.MediaType.Jaz2:
dmns.Height = 102;
dmns.HeightSpecified = true;
dmns.Width = 98;
dmns.WidthSpecified = true;
dmns.Thickness = 12;
return dmns;
case CommonTypes.MediaType.Orb:
case CommonTypes.MediaType.Orb5:
dmns.Height = 104;
dmns.HeightSpecified = true;
dmns.Width = 98;
dmns.WidthSpecified = true;
dmns.Thickness = 8;
return dmns;
case CommonTypes.MediaType.SparQ:
dmns.Height = 98;
dmns.HeightSpecified = true;
dmns.Width = 100;
dmns.WidthSpecified = true;
dmns.Thickness = 9.7;
return dmns;
case CommonTypes.MediaType.SLR1:
case CommonTypes.MediaType.SLR2:
case CommonTypes.MediaType.SLR3:
case CommonTypes.MediaType.SLR32:
case CommonTypes.MediaType.SLR32SL:
case CommonTypes.MediaType.SLR4:
case CommonTypes.MediaType.SLR5:
case CommonTypes.MediaType.SLR5SL:
case CommonTypes.MediaType.SLR6:
case CommonTypes.MediaType.SLRtape100:
case CommonTypes.MediaType.SLRtape140:
case CommonTypes.MediaType.SLRtape24:
case CommonTypes.MediaType.SLRtape24SL:
case CommonTypes.MediaType.SLRtape40:
case CommonTypes.MediaType.SLRtape50:
case CommonTypes.MediaType.SLRtape60:
case CommonTypes.MediaType.SLRtape7:
case CommonTypes.MediaType.SLRtape75:
case CommonTypes.MediaType.SLRtape7SL:
dmns.Height = 150;
dmns.HeightSpecified = true;
dmns.Width = 100;
dmns.WidthSpecified = true;
dmns.Thickness = 18;
return dmns;
case CommonTypes.MediaType.N64DD:
dmns.Height = 103.124;
dmns.HeightSpecified = true;
dmns.Width = 101.092;
dmns.WidthSpecified = true;
dmns.Thickness = 10.16;
return dmns;
case CommonTypes.MediaType.CompactTapeI:
case CommonTypes.MediaType.CompactTapeII:
case CommonTypes.MediaType.DLTtapeIII:
case CommonTypes.MediaType.DLTtapeIIIxt:
case CommonTypes.MediaType.DLTtapeIV:
case CommonTypes.MediaType.DLTtapeS4:
case CommonTypes.MediaType.SDLT1:
case CommonTypes.MediaType.SDLT2:
case CommonTypes.MediaType.VStapeI:
dmns.Height = 105;
dmns.HeightSpecified = true;
dmns.Width = 105;
dmns.WidthSpecified = true;
dmns.Thickness = 25;
return dmns;
case CommonTypes.MediaType.LTO:
case CommonTypes.MediaType.LTO2:
case CommonTypes.MediaType.LTO3:
case CommonTypes.MediaType.LTO3WORM:
case CommonTypes.MediaType.LTO4:
case CommonTypes.MediaType.LTO4WORM:
case CommonTypes.MediaType.LTO5:
case CommonTypes.MediaType.LTO5WORM:
case CommonTypes.MediaType.LTO6:
case CommonTypes.MediaType.LTO6WORM:
case CommonTypes.MediaType.LTO7:
case CommonTypes.MediaType.LTO7WORM:
dmns.Height = 101.6;
dmns.HeightSpecified = true;
dmns.Width = 105.41;
dmns.WidthSpecified = true;
dmns.Thickness = 21.59;
return dmns;
case CommonTypes.MediaType.IBM3480:
case CommonTypes.MediaType.IBM3490:
case CommonTypes.MediaType.IBM3490E:
case CommonTypes.MediaType.IBM3592:
dmns.Height = 125.73;
dmns.HeightSpecified = true;
dmns.Width = 107.95;
dmns.WidthSpecified = true;
dmns.Thickness = 25.4;
return dmns;
case CommonTypes.MediaType.T9840A:
case CommonTypes.MediaType.T9840B:
case CommonTypes.MediaType.T9840C:
case CommonTypes.MediaType.T9840D:
case CommonTypes.MediaType.T9940A:
case CommonTypes.MediaType.T9940B:
dmns.Height = 124.46;
dmns.HeightSpecified = true;
dmns.Width = 109.22;
dmns.WidthSpecified = true;
dmns.Thickness = 25.4;
return dmns;
case CommonTypes.MediaType.CompactCassette:
case CommonTypes.MediaType.Dcas25:
case CommonTypes.MediaType.Dcas85:
case CommonTypes.MediaType.Dcas103:
dmns.Height = 63.5;
dmns.HeightSpecified = true;
dmns.Width = 128;
dmns.WidthSpecified = true;
dmns.Thickness = 12;
return dmns;
case CommonTypes.MediaType.IBM3470:
dmns.Height = 58.42;
dmns.HeightSpecified = true;
dmns.Width = 137.16;
dmns.WidthSpecified = true;
dmns.Thickness = 16.51;
return dmns;
case CommonTypes.MediaType.Bernoulli2:
dmns.Height = 136;
dmns.HeightSpecified = true;
dmns.Width = 140;
dmns.WidthSpecified = true;
dmns.Thickness = 9;
return dmns;
case CommonTypes.MediaType.MLR1:
case CommonTypes.MediaType.MLR3:
case CommonTypes.MediaType.MLR1SL:
dmns.Height = 101.6;
dmns.HeightSpecified = true;
dmns.Width = 152.4;
dmns.WidthSpecified = true;
dmns.Thickness = 15.24;
return dmns;
case CommonTypes.MediaType.QIC11:
case CommonTypes.MediaType.QIC120:
case CommonTypes.MediaType.QIC1350:
case CommonTypes.MediaType.QIC150:
case CommonTypes.MediaType.QIC24:
case CommonTypes.MediaType.QIC525:
dmns.Height = 101.6;
dmns.HeightSpecified = true;
dmns.Width = 154.2;
dmns.WidthSpecified = true;
dmns.Thickness = 16.6;
return dmns;
case CommonTypes.MediaType.Bernoulli:
dmns.Height = 275;
dmns.HeightSpecified = true;
dmns.Width = 210;
dmns.WidthSpecified = true;
dmns.Thickness = 0;
return dmns;
case CommonTypes.MediaType.DTF:
case CommonTypes.MediaType.DTF2:
dmns.Height = 144.78;
dmns.HeightSpecified = true;
dmns.Width = 254;
dmns.WidthSpecified = true;
dmns.Thickness = 25.4;
return dmns;
case CommonTypes.MediaType.LD:
case CommonTypes.MediaType.LDROM:
case CommonTypes.MediaType.LDROM2:
case CommonTypes.MediaType.MegaLD:
case CommonTypes.MediaType.LVROM:
dmns.Diameter = 300;
dmns.DiameterSpecified = true;
dmns.Thickness = 2.5;
return dmns;
#region CD/DVD/BD
case CommonTypes.MediaType.CDDA:
case CommonTypes.MediaType.CDG:
case CommonTypes.MediaType.CDEG:
case CommonTypes.MediaType.CDI:
case CommonTypes.MediaType.CDROM:
case CommonTypes.MediaType.CDROMXA:
case CommonTypes.MediaType.CDPLUS:
case CommonTypes.MediaType.CDMO:
case CommonTypes.MediaType.CDR:
case CommonTypes.MediaType.CDRW:
case CommonTypes.MediaType.CDMRW:
case CommonTypes.MediaType.VCD:
case CommonTypes.MediaType.SVCD:
case CommonTypes.MediaType.PCD:
case CommonTypes.MediaType.SACD:
case CommonTypes.MediaType.DDCD:
case CommonTypes.MediaType.DDCDR:
case CommonTypes.MediaType.DDCDRW:
case CommonTypes.MediaType.DTSCD:
case CommonTypes.MediaType.CDMIDI:
case CommonTypes.MediaType.CDV:
case CommonTypes.MediaType.CD:
case CommonTypes.MediaType.DVDROM:
case CommonTypes.MediaType.DVDR:
case CommonTypes.MediaType.DVDRW:
case CommonTypes.MediaType.DVDPR:
case CommonTypes.MediaType.DVDPRW:
case CommonTypes.MediaType.DVDPRWDL:
case CommonTypes.MediaType.DVDRDL:
case CommonTypes.MediaType.DVDPRDL:
case CommonTypes.MediaType.DVDRAM:
case CommonTypes.MediaType.DVDRWDL:
case CommonTypes.MediaType.DVDDownload:
case CommonTypes.MediaType.HDDVDROM:
case CommonTypes.MediaType.HDDVDRAM:
case CommonTypes.MediaType.HDDVDR:
case CommonTypes.MediaType.HDDVDRW:
case CommonTypes.MediaType.HDDVDRDL:
case CommonTypes.MediaType.HDDVDRWDL:
case CommonTypes.MediaType.BDROM:
case CommonTypes.MediaType.BDR:
case CommonTypes.MediaType.BDRE:
case CommonTypes.MediaType.BDRXL:
case CommonTypes.MediaType.BDREXL:
case CommonTypes.MediaType.PS1CD:
case CommonTypes.MediaType.PS2CD:
case CommonTypes.MediaType.PS2DVD:
case CommonTypes.MediaType.PS3DVD:
case CommonTypes.MediaType.PS3BD:
case CommonTypes.MediaType.PS4BD:
case CommonTypes.MediaType.XGD:
case CommonTypes.MediaType.XGD2:
case CommonTypes.MediaType.XGD3:
case CommonTypes.MediaType.XGD4:
case CommonTypes.MediaType.MEGACD:
case CommonTypes.MediaType.SATURNCD:
case CommonTypes.MediaType.GDROM:
case CommonTypes.MediaType.GDR:
case CommonTypes.MediaType.SuperCDROM2:
case CommonTypes.MediaType.JaguarCD:
case CommonTypes.MediaType.ThreeDO:
case CommonTypes.MediaType.WOD:
case CommonTypes.MediaType.WUOD:
case CommonTypes.MediaType.PCFX:
dmns.Diameter = 120;
dmns.DiameterSpecified = true;
dmns.Thickness = 1.2;
return dmns;
case CommonTypes.MediaType.GOD:
dmns.Diameter = 80;
dmns.DiameterSpecified = true;
dmns.Thickness = 1.2;
return dmns;
#endregion CD/DVD/BD
#region Apple Hard Disks
// TODO: Find Apple Widget size
case CommonTypes.MediaType.AppleProfile:
dmns.Height = 223.8;
dmns.HeightSpecified = true;
dmns.Width = 438.9;
dmns.WidthSpecified = true;
dmns.Thickness = 111.5;
return dmns;
case CommonTypes.MediaType.AppleHD20:
dmns.Height = 246.4;
dmns.HeightSpecified = true;
dmns.Width = 266.7;
dmns.WidthSpecified = true;
dmns.Thickness = 78.7;
return dmns;
#endregion Apple Hard Disks
case CommonTypes.MediaType.UMD:
dmns.Height = 64;
dmns.HeightSpecified = true;
dmns.Width = 63;
dmns.WidthSpecified = true;
dmns.Thickness = 4;
return dmns;
default: return null;
}
}
}
}

1829
Metadata/MediaType.cs Normal file

File diff suppressed because it is too large Load Diff

53
Metadata/Resume.cs Normal file
View File

@@ -0,0 +1,53 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Resume.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : XML metadata.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines XML format of a dump resume file.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using Schemas;
namespace DiscImageChef.CommonTypes.Metadata
{
[Serializable]
[XmlRoot("DicResume", Namespace = "", IsNullable = false)]
public class Resume
{
[XmlElement(DataType = "dateTime")] public DateTime CreationDate;
[XmlElement(DataType = "dateTime")] public DateTime LastWriteDate;
public bool Removable;
public ulong LastBlock;
public ulong NextBlock;
[XmlArrayItem("DumpTry")] public List<DumpHardwareType> Tries;
[XmlArrayItem("Block")] public List<ulong> BadBlocks;
}
}

173
Metadata/Statistics.cs Normal file
View File

@@ -0,0 +1,173 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Statistics.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : XML metadata.
//
// --[ Description ] ----------------------------------------------------------
//
// Define XML for statistics.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.Xml.Serialization;
namespace DiscImageChef.CommonTypes.Metadata
{
[XmlRoot("DicStats", Namespace = "", IsNullable = false)]
public class Stats
{
public CommandsStats Commands;
[XmlArrayItem("OperatingSystem")]
public List<OsStats> OperatingSystems { get; set; }
[XmlArrayItem("Version")]
public List<NameValueStats> Versions { get; set; }
[XmlArrayItem("Filesystem")]
public List<NameValueStats> Filesystems { get; set; }
[XmlArrayItem("Scheme")]
public List<NameValueStats> Partitions { get; set; }
[XmlArrayItem("Format")]
public List<NameValueStats> MediaImages { get; set; }
[XmlArrayItem("Filter", IsNullable = true)]
public List<NameValueStats> Filters { get; set; }
[XmlArrayItem("Device", IsNullable = true)]
public List<DeviceStats> Devices { get; set; }
[XmlArrayItem("Media")]
public List<MediaStats> Medias { get; set; }
public BenchmarkStats Benchmark { get; set; }
public MediaScanStats MediaScan { get; set; }
public VerifyStats Verify { get; set; }
}
public class CommandsStats
{
public long Analyze;
public long Benchmark;
public long Checksum;
public long Compare;
public long ConvertImage;
public long CreateSidecar;
public long Decode;
public long DeviceInfo;
public long DeviceReport;
public long DumpMedia;
public long Entropy;
public long ExtractFiles;
public long Formats;
public long ImageInfo;
public long ListDevices;
public long ListEncodings;
public long Ls;
public long MediaInfo;
public long MediaScan;
public long PrintHex;
public long Verify;
}
public class VerifiedItems
{
public long Correct;
public long Failed;
}
public class VerifyStats
{
public VerifiedItems MediaImages;
public ScannedSectors Sectors;
}
public class ScannedSectors
{
public long Correct;
public long Error;
public long Total;
public long Unverifiable;
}
public class TimeStats
{
public long LessThan10ms;
public long LessThan150ms;
public long LessThan3ms;
public long LessThan500ms;
public long LessThan50ms;
public long MoreThan500ms;
}
public class MediaScanStats
{
public ScannedSectors Sectors;
public TimeStats Times;
}
public class ChecksumStats
{
[XmlAttribute] public string algorithm;
[XmlText] public double Value;
}
public class BenchmarkStats
{
public double All;
[XmlElement("Checksum")] public List<ChecksumStats> Checksum;
public double Entropy;
public long MaxMemory;
public long MinMemory;
public double Sequential;
}
public class MediaStats
{
[XmlAttribute] public bool real;
[XmlAttribute] public string type;
[XmlText] public long Value;
}
public class DeviceStats
{
[XmlIgnore] public bool ManufacturerSpecified;
public string Manufacturer { get; set; }
public string Model { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
}
public class NameValueStats
{
[XmlAttribute]
public string name { get; set; }
[XmlText]
public long Value { get; set; }
}
public class OsStats
{
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string version { get; set; }
[XmlText]
public long Value { get; set; }
}
}

54
Metadata/Version.cs Normal file
View File

@@ -0,0 +1,54 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Statistics.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : XML metadata.
//
// --[ Description ] ----------------------------------------------------------
//
// Returns DiscImageChef version in XML software type format.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using DiscImageChef.CommonTypes.Interop;
using Schemas;
namespace DiscImageChef.CommonTypes.Metadata
{
public static class Version
{
/// <summary>
/// Gets XML software type for the running version
/// </summary>
/// <returns>XML software type</returns>
public static SoftwareType GetSoftwareType()
{
return new SoftwareType
{
Name = "DiscImageChef",
OperatingSystem = DetectOS.GetRealPlatformID().ToString(),
Version = typeof(Version).Assembly.GetName().Version.ToString()
};
}
}
}

168
PluginBase.cs Normal file
View File

@@ -0,0 +1,168 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : PluginBase.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Core algorithms.
//
// --[ Description ] ----------------------------------------------------------
//
// Class to hold all installed plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.Console;
using DiscImageChef.Partitions;
namespace DiscImageChef.CommonTypes
{
/// <summary>
/// Contain all plugins (filesystem, partition and image)
/// </summary>
public class PluginBase
{
/// <summary>
/// List of all media image plugins
/// </summary>
public readonly SortedDictionary<string, IMediaImage> ImagePluginsList;
/// <summary>
/// List of all partition plugins
/// </summary>
public readonly SortedDictionary<string, IPartition> PartPluginsList;
/// <summary>
/// List of all filesystem plugins
/// </summary>
public readonly SortedDictionary<string, IFilesystem> PluginsList;
/// <summary>
/// List of read-only filesystem plugins
/// </summary>
public readonly SortedDictionary<string, IReadOnlyFilesystem> ReadOnlyFilesystems;
/// <summary>
/// List of writable media image plugins
/// </summary>
public readonly SortedDictionary<string, IWritableImage> WritableImages;
/// <summary>
/// Initializes the plugins lists
/// </summary>
public PluginBase()
{
PluginsList = new SortedDictionary<string, IFilesystem>();
ReadOnlyFilesystems = new SortedDictionary<string, IReadOnlyFilesystem>();
PartPluginsList = new SortedDictionary<string, IPartition>();
ImagePluginsList = new SortedDictionary<string, IMediaImage>();
WritableImages = new SortedDictionary<string, IWritableImage>();
// We need to manually load assemblies :(
AppDomain.CurrentDomain.Load("DiscImageChef.DiscImages");
AppDomain.CurrentDomain.Load("DiscImageChef.Filesystems");
AppDomain.CurrentDomain.Load("DiscImageChef.Partitions");
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach(Assembly assembly in assemblies)
{
foreach(Type type in assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IMediaImage)))
.Where(t => t.IsClass))
try
{
IMediaImage plugin =
(IMediaImage)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterImagePlugin(plugin);
}
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
foreach(Type type in assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IPartition)))
.Where(t => t.IsClass))
try
{
IPartition plugin = (IPartition)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterPartPlugin(plugin);
}
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
foreach(Type type in assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IFilesystem)))
.Where(t => t.IsClass))
try
{
IFilesystem plugin =
(IFilesystem)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterPlugin(plugin);
}
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
foreach(Type type in assembly
.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IReadOnlyFilesystem)))
.Where(t => t.IsClass))
try
{
IReadOnlyFilesystem plugin =
(IReadOnlyFilesystem)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterReadOnlyFilesystem(plugin);
}
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
foreach(Type type in assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IWritableImage)))
.Where(t => t.IsClass))
try
{
IWritableImage plugin =
(IWritableImage)type.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
RegisterWritableMedia(plugin);
}
catch(Exception exception) { DicConsole.ErrorWriteLine("Exception {0}", exception); }
}
}
void RegisterImagePlugin(IMediaImage plugin)
{
if(!ImagePluginsList.ContainsKey(plugin.Name.ToLower()))
ImagePluginsList.Add(plugin.Name.ToLower(), plugin);
}
void RegisterPlugin(IFilesystem plugin)
{
if(!PluginsList.ContainsKey(plugin.Name.ToLower())) PluginsList.Add(plugin.Name.ToLower(), plugin);
}
void RegisterReadOnlyFilesystem(IReadOnlyFilesystem plugin)
{
if(!ReadOnlyFilesystems.ContainsKey(plugin.Name.ToLower()))
ReadOnlyFilesystems.Add(plugin.Name.ToLower(), plugin);
}
void RegisterWritableMedia(IWritableImage plugin)
{
if(!WritableImages.ContainsKey(plugin.Name.ToLower())) WritableImages.Add(plugin.Name.ToLower(), plugin);
}
void RegisterPartPlugin(IPartition partplugin)
{
if(!PartPluginsList.ContainsKey(partplugin.Name.ToLower()))
PartPluginsList.Add(partplugin.Name.ToLower(), partplugin);
}
}
}

321
Structs/Filesystems.cs Normal file
View File

@@ -0,0 +1,321 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Structs.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : DiscImageChef filesystem plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains enumerations and structures of common usage by filesystem
// plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace DiscImageChef.CommonTypes.Structs
{
/// <summary>
/// File attributes.
/// </summary>
[Flags]
public enum FileAttributes : ulong
{
/// <summary>File is an alias (Mac OS)</summary>
Alias = 0x01,
/// <summary>Indicates that the file can only be writable appended</summary>
AppendOnly = 0x02,
/// <summary>File is candidate for archival/backup</summary>
Archive = 0x04,
/// <summary>File is a block device</summary>
BlockDevice = 0x08,
/// <summary>File is stored on filesystem block units instead of device sectors</summary>
BlockUnits = 0x10,
/// <summary>Directory is a bundle or file contains a BNDL resource</summary>
Bundle = 0x20,
/// <summary>File is a char device</summary>
CharDevice = 0x40,
/// <summary>File is compressed</summary>
Compressed = 0x80,
/// <summary>File is compressed and should not be uncompressed on read</summary>
CompressedRaw = 0x100,
/// <summary>File has compression errors</summary>
CompressionError = 0x200,
/// <summary>Compressed file is dirty</summary>
CompressionDirty = 0x400,
/// <summary>File is a device</summary>
Device = 0x800,
/// <summary>File is a directory</summary>
Directory = 0x1000,
/// <summary>File is encrypted</summary>
Encrypted = 0x2000,
/// <summary>File is stored on disk using extents</summary>
Extents = 0x4000,
/// <summary>File is a FIFO</summary>
FIFO = 0x8000,
/// <summary>File is a normal file</summary>
File = 0x10000,
/// <summary>File is a Mac OS file containing desktop databases that has already been added to the desktop database</summary>
HasBeenInited = 0x20000,
/// <summary>File contains an icon resource / EA</summary>
HasCustomIcon = 0x40000,
/// <summary>File is a Mac OS extension or control panel lacking INIT resources</summary>
HasNoINITs = 0x80000,
/// <summary>File is hidden/invisible</summary>
Hidden = 0x100000,
/// <summary>File cannot be written, deleted, modified or linked to</summary>
Immutable = 0x200000,
/// <summary>Directory is indexed using hashed trees</summary>
IndexedDirectory = 0x400000,
/// <summary>File contents are stored alongside its inode (or equivalent)</summary>
Inline = 0x800000,
/// <summary>File contains integrity checks</summary>
IntegrityStream = 0x1000000,
/// <summary>File is on desktop</summary>
IsOnDesk = 0x2000000,
/// <summary>File changes are written to filesystem journal before being written to file itself</summary>
Journaled = 0x4000000,
/// <summary>Access time will not be modified</summary>
NoAccessTime = 0x8000000,
/// <summary>File will not be subject to copy-on-write</summary>
NoCopyOnWrite = 0x10000000,
/// <summary>File will not be backed up</summary>
NoDump = 0x20000000,
/// <summary>File contents should not be scrubbed</summary>
NoScrub = 0x40000000,
/// <summary>File contents should not be indexed</summary>
NotIndexed = 0x80000000,
/// <summary>File is offline</summary>
Offline = 0x100000000,
/// <summary>File is password protected, but contents are not encrypted on disk</summary>
Password = 0x200000000,
/// <summary>File is read-only</summary>
ReadOnly = 0x400000000,
/// <summary>File is a reparse point</summary>
ReparsePoint = 0x800000000,
/// <summary>When file is removed its content will be overwritten with zeroes</summary>
Secured = 0x1000000000,
/// <summary>File contents are sparse</summary>
Sparse = 0x2000000000,
/// <summary>File is a shadow (OS/2)</summary>
Shadow = 0x4000000000,
/// <summary>File is shared</summary>
Shared = 0x8000000000,
/// <summary>File is a stationery</summary>
Stationery = 0x10000000000,
/// <summary>File is a symbolic link</summary>
Symlink = 0x20000000000,
/// <summary>File writes are synchronously written to disk</summary>
Sync = 0x40000000000,
/// <summary>File belongs to the operating system</summary>
System = 0x80000000000,
/// <summary>If file end is a partial block its content will be merged with other files</summary>
TailMerged = 0x100000000000,
/// <summary>File is temporary</summary>
Temporary = 0x200000000000,
/// <summary>Subdirectories inside of this directory are not related and should be allocated elsewhere</summary>
TopDirectory = 0x400000000000,
/// <summary>If file is deleted, contents should be stored, for a possible future undeletion</summary>
Undeletable = 0x800000000000,
/// <summary>File is a pipe</summary>
Pipe = 0x1000000000000
}
/// <summary>
/// Information about a file entry
/// </summary>
public class FileEntryInfo
{
/// <summary>File attributes</summary>
public FileAttributes Attributes;
/// <summary>File length in blocks</summary>
public long Blocks;
/// <summary>File block size in bytes</summary>
public long BlockSize;
/// <summary>If file points to a device, device number</summary>
public ulong DeviceNo;
/// <summary>POSIX group ID</summary>
public ulong GID;
/// <summary>inode number for this file</summary>
public ulong Inode;
/// <summary>File length in bytes</summary>
public long Length;
/// <summary>Number of hard links pointing to this file</summary>
public ulong Links;
/// <summary>POSIX permissions/mode for this file</summary>
public uint Mode;
/// <summary>POSIX owner ID</summary>
public ulong UID;
/// <summary>File creation date in UTC</summary>
public DateTime CreationTimeUtc { get; set; }
/// <summary>File last access date in UTC</summary>
public DateTime AccessTimeUtc { get; set; }
/// <summary>File attributes change date in UTC</summary>
public DateTime StatusChangeTimeUtc { get; set; }
/// <summary>File last backup date in UTC</summary>
public DateTime BackupTimeUtc { get; set; }
/// <summary>File last modification date in UTC</summary>
public DateTime LastWriteTimeUtc { get; set; }
/// <summary>File creation date</summary>
public DateTime CreationTime
{
get => CreationTimeUtc.ToLocalTime();
set => CreationTimeUtc = value.ToUniversalTime();
}
/// <summary>File last access date</summary>
public DateTime AccessTime
{
get => AccessTimeUtc.ToLocalTime();
set => AccessTimeUtc = value.ToUniversalTime();
}
/// <summary>File attributes change date</summary>
public DateTime StatusChangeTime
{
get => StatusChangeTimeUtc.ToLocalTime();
set => StatusChangeTimeUtc = value.ToUniversalTime();
}
/// <summary>File last backup date</summary>
public DateTime BackupTime
{
get => BackupTimeUtc.ToLocalTime();
set => BackupTimeUtc = value.ToUniversalTime();
}
/// <summary>File last modification date</summary>
public DateTime LastWriteTime
{
get => LastWriteTimeUtc.ToLocalTime();
set => LastWriteTimeUtc = value.ToUniversalTime();
}
}
public class FileSystemInfo
{
/// <summary>Blocks for this filesystem</summary>
public long Blocks;
/// <summary>Maximum length of filenames on this filesystem</summary>
public ushort FilenameLength;
/// <summary>Files on this filesystem</summary>
public ulong Files;
/// <summary>Blocks free on this filesystem</summary>
public long FreeBlocks;
/// <summary>Free inodes on this filesystem</summary>
public ulong FreeFiles;
/// <summary>Filesystem ID</summary>
public FileSystemId Id;
/// <summary>ID of plugin for this file</summary>
public Guid PluginId;
/// <summary>Filesystem type</summary>
public string Type;
public FileSystemInfo()
{
Id = new FileSystemId();
}
}
[StructLayout(LayoutKind.Explicit)]
public struct FileSystemId
{
[FieldOffset(0)] public bool IsInt;
[FieldOffset(1)] public bool IsLong;
[FieldOffset(2)] public bool IsGuid;
[FieldOffset(3)] public uint Serial32;
[FieldOffset(3)] public ulong Serial64;
[FieldOffset(3)] public Guid uuid;
}
/// <summary>
/// Errors
/// </summary>
public enum Errno
{
/// <summary>No error happened</summary>
NoError = 0,
/// <summary>Access denied</summary>
AccessDenied = -13,
/// <summary>Busy, cannot complete</summary>
Busy = -16,
/// <summary>File is too large</summary>
FileTooLarge = -27,
/// <summary>Invalid argument</summary>
InvalidArgument = -22,
/// <summary>I/O error</summary>
InOutError = -5,
/// <summary>Is a directory (e.g.: trying to Read() a dir)</summary>
IsDirectory = -21,
/// <summary>Name is too long</summary>
NameTooLong = -36,
/// <summary>There is no data available</summary>
NoData = 61,
/// <summary>There is no such attribute</summary>
NoSuchExtendedAttribute = NoData,
/// <summary>No such device</summary>
NoSuchDevice = -19,
/// <summary>No such file or directory</summary>
NoSuchFile = -2,
/// <summary>Is not a directory (e.g.: trying to ReadDir() a file)</summary>
NotDirectory = -20,
/// <summary>Not implemented</summary>
NotImplemented = -38,
/// <summary>Not supported</summary>
NotSupported = -252,
/// <summary>Link is severed</summary>
SeveredLink = -67,
/// <summary>Access denied</summary>
EACCES = AccessDenied,
/// <summary>Busy, cannot complete</summary>
EBUSY = Busy,
/// <summary>File is too large</summary>
EFBIG = FileTooLarge,
/// <summary>Invalid argument</summary>
EINVAL = InvalidArgument,
/// <summary>I/O error</summary>
EIO = InOutError,
/// <summary>Is a directory (e.g.: trying to Read() a dir)</summary>
EISDIR = IsDirectory,
/// <summary>Name is too long</summary>
ENAMETOOLONG = NameTooLong,
/// <summary>There is no such attribute</summary>
ENOATTR = NoSuchExtendedAttribute,
/// <summary>There is no data available</summary>
ENODATA = NoData,
/// <summary>No such device</summary>
ENODEV = NoSuchDevice,
/// <summary>No such file or directory</summary>
ENOENT = NoSuchFile,
/// <summary>Link is severed</summary>
ENOLINK = SeveredLink,
/// <summary>Not implemented</summary>
ENOSYS = NotImplemented,
/// <summary>Is not a directory (e.g.: trying to ReadDir() a file)</summary>
ENOTDIR = NotDirectory,
/// <summary>Not supported</summary>
ENOTSUP = NotSupported
}
}

188
Structs/Images.cs Normal file
View File

@@ -0,0 +1,188 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : IMediaImage.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Disc image plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Defines structures to be used by disc image plugins.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Interfaces;
namespace DiscImageChef.CommonTypes.Structs
{
/// <summary>
/// Contains information about a dump image and its contents
/// </summary>
public struct ImageInfo
{
/// <summary>Image contains partitions (or tracks for optical media)</summary>
public bool HasPartitions;
/// <summary>Image contains sessions (optical media only)</summary>
public bool HasSessions;
/// <summary>Size of the image without headers</summary>
public ulong ImageSize;
/// <summary>Sectors contained in the image</summary>
public ulong Sectors;
/// <summary>Size of sectors contained in the image</summary>
public uint SectorSize;
/// <summary>Media tags contained by the image</summary>
public List<MediaTagType> ReadableMediaTags;
/// <summary>Sector tags contained by the image</summary>
public List<SectorTagType> ReadableSectorTags;
/// <summary>Image version</summary>
public string Version;
/// <summary>Application that created the image</summary>
public string Application;
/// <summary>Version of the application that created the image</summary>
public string ApplicationVersion;
/// <summary>Who (person) created the image?</summary>
public string Creator;
/// <summary>Image creation time</summary>
public DateTime CreationTime;
/// <summary>Image last modification time</summary>
public DateTime LastModificationTime;
/// <summary>Title of the media represented by the image</summary>
public string MediaTitle;
/// <summary>Image comments</summary>
public string Comments;
/// <summary>Manufacturer of the media represented by the image</summary>
public string MediaManufacturer;
/// <summary>Model of the media represented by the image</summary>
public string MediaModel;
/// <summary>Serial number of the media represented by the image</summary>
public string MediaSerialNumber;
/// <summary>Barcode of the media represented by the image</summary>
public string MediaBarcode;
/// <summary>Part number of the media represented by the image</summary>
public string MediaPartNumber;
/// <summary>Media type represented by the image</summary>
public MediaType MediaType;
/// <summary>Number in sequence for the media represented by the image</summary>
public int MediaSequence;
/// <summary>Last media of the sequence the media represented by the image corresponds to</summary>
public int LastMediaSequence;
/// <summary>Manufacturer of the drive used to read the media represented by the image</summary>
public string DriveManufacturer;
/// <summary>Model of the drive used to read the media represented by the image</summary>
public string DriveModel;
/// <summary>Serial number of the drive used to read the media represented by the image</summary>
public string DriveSerialNumber;
/// <summary>Firmware revision of the drive used to read the media represented by the image</summary>
public string DriveFirmwareRevision;
/// <summary>Type of the media represented by the image to use in XML sidecars</summary>
public XmlMediaType XmlMediaType;
// CHS geometry...
/// <summary>Cylinders of the media represented by the image</summary>
public uint Cylinders;
/// <summary>Heads of the media represented by the image</summary>
public uint Heads;
/// <summary>Sectors per track of the media represented by the image (for variable image, the smallest)</summary>
public uint SectorsPerTrack;
}
/// <summary>
/// Session defining structure.
/// </summary>
public struct Session
{
/// <summary>Session number, 1-started</summary>
public ushort SessionSequence;
/// <summary>First track present on this session</summary>
public uint StartTrack;
/// <summary>Last track present on this session</summary>
public uint EndTrack;
/// <summary>First sector present on this session</summary>
public ulong StartSector;
/// <summary>Last sector present on this session</summary>
public ulong EndSector;
}
/// <summary>
/// Track defining structure.
/// </summary>
public struct Track
{
/// <summary>Track number, 1-started</summary>
public uint TrackSequence;
/// <summary>Partition type</summary>
public TrackType TrackType;
/// <summary>Track starting sector</summary>
public ulong TrackStartSector;
/// <summary>Track ending sector</summary>
public ulong TrackEndSector;
/// <summary>Track pre-gap</summary>
public ulong TrackPregap;
/// <summary>Session this track belongs to</summary>
public ushort TrackSession;
/// <summary>Information that does not find space in this struct</summary>
public string TrackDescription;
/// <summary>Indexes, 00 to 99 and sector offset</summary>
public Dictionary<int, ulong> Indexes;
/// <summary>Which filter stores this track</summary>
public IFilter TrackFilter;
/// <summary>Which file stores this track</summary>
public string TrackFile;
/// <summary>Starting at which byte is this track stored</summary>
public ulong TrackFileOffset;
/// <summary>What kind of file is storing this track</summary>
public string TrackFileType;
/// <summary>How many main channel / user data bytes are per sector in this track</summary>
public int TrackBytesPerSector;
/// <summary>How many main channel bytes per sector are in the file with this track</summary>
public int TrackRawBytesPerSector;
/// <summary>Which filter stores this track's subchannel</summary>
public IFilter TrackSubchannelFilter;
/// <summary>Which file stores this track's subchannel</summary>
public string TrackSubchannelFile;
/// <summary>Starting at which byte are this track's subchannel stored</summary>
public ulong TrackSubchannelOffset;
/// <summary>Type of subchannel stored for this track</summary>
public TrackSubchannelType TrackSubchannelType;
}
/// <summary>
/// Floppy physical characteristics structure.
/// </summary>
public struct FloppyInfo
{
/// <summary>Physical floppy type.</summary>
public FloppyTypes Type;
/// <summary>Bitrate in bits per second used to write the floppy, 0 if unknown or track-variable.</summary>
public uint Bitrate;
/// <summary>Physical magnetic density (coercitivity) of floppy medium.</summary>
public FloppyDensities Coercitivity;
/// <summary>How many physical tracks are actually written in the floppy image.</summary>
public ushort Tracks;
/// <summary>How many physical heads are actually written in the floppy image.</summary>
public byte Heads;
/// <summary>How many tracks per inch are actually written in the floppy image.</summary>
public ushort TrackDensity;
}
}