// Decompiled with JetBrains decompiler // Type: ImageReader.ISO9660.VolumeDescriptors.VolumeDescriptorConverter // Assembly: ImageReader, Version=1.5.2.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08 // MVID: E0717604-B50B-4CB4-B85C-C17F43D5C04B // Assembly location: ImageReader.dll using ImageReader.ISO9660.DirectoryRecords; using System; using System.Text; namespace ImageReader.ISO9660.VolumeDescriptors { public class VolumeDescriptorConverter { private static readonly string STANDARD_IDENTIFIER = "CD001"; private static readonly byte VOLUME_DESCRIPTOR_VERSION = 1; private static readonly byte FILE_STRUCTURE_VERSION = 1; private static readonly ushort OFFSET_VOLUME_DESCRIPTOR_TYPE = 0; private static readonly ushort OFFSET_STANDARD_IDENTIFIER = 1; private static readonly ushort OFFSET_VOLUME_DESCRIPTOR_VERSION = 6; private static readonly ushort OFFSET_SYSTEM_IDENTIFIER = 8; private static readonly ushort OFFSET_VOLUME_IDENTIFIER = 40; private static readonly ushort OFFSET_TYPE_L_VOLUME_SPACE_SIZE = 80; private static readonly ushort OFFSET_TYPE_M_VOLUME_SPACE_SIZE = 84; private static readonly ushort OFFSET_TYPE_L_VOLUME_SET_SIZE = 120; private static readonly ushort OFFSET_TYPE_M_VOLUME_SET_SIZE = 122; private static readonly ushort OFFSET_TYPE_L_VOLUME_SEQUENCE_NUMBER = 124; private static readonly ushort OFFSET_TYPE_M_VOLUME_SEQUENCE_NUMBER = 126; private static readonly ushort OFFSET_TYPE_L_LOGICAL_BLOCK_SIZE = 128; private static readonly ushort OFFSET_TYPE_M_LOGICAL_BLOCK_SIZE = 130; private static readonly ushort OFFSET_TYPE_L_PATH_TABLE_SIZE = 132; private static readonly ushort OFFSET_TYPE_M_PATH_TABLE_SIZE = 136; private static readonly ushort OFFSET_TYPE_L_PATH_TABLE = 140; private static readonly ushort OFFSET_TYPE_L_OPTIONAL_PATH_TABLE = 144; private static readonly ushort OFFSET_TYPE_M_PATH_TABLE = 148; private static readonly ushort OFFSET_TYPE_M_OPTIONAL_PATH_TABLE = 152; private static readonly ushort OFFSET_ROOT_DIRECTORY_RECORD = 156; private static readonly ushort OFFSET_VOLUME_SET_IDENTIFIER = 190; private static readonly ushort OFFSET_PUBLISHER_IDENTIFIER = 318; private static readonly ushort OFFSET_PREPARER_IDENTIFIER = 446; private static readonly ushort OFFSET_APPLICATION_IDENTIFIER = 574; private static readonly ushort OFFSET_COPYRIGHT_FILE_IDENTIFIER = 702; private static readonly ushort OFFSET_ABSTRACT_FILE_IDENTIFIER = 739; private static readonly ushort OFFSET_BIBLIOGRAPHIC_FILE_IDENTIFIER = 776; private static readonly ushort OFFSET_VOLUME_CREATION_DATE = 813; private static readonly ushort OFFSET_VOLUME_MODIFICATION_DATE = 830; private static readonly ushort OFFSET_VOLUME_EXPIRATION_DATE = 847; private static readonly ushort OFFSET_VOLUME_EFFECTIVE_DATE = 864; private static readonly ushort OFFSET_FILE_STRUCTURE_VERSION = 881; public static PrimaryVolumeDescriptor ToPrimaryVolumeDescriptor( byte[] buffer, int startIndex) { if (startIndex < 0 || buffer.Length - startIndex < (int) VolumeDescriptor.VolumeDescriptorSize) throw new ArgumentOutOfRangeException(); PrimaryVolumeDescriptor volumeDescriptor = new PrimaryVolumeDescriptor() { Type = (VolumeDescriptorType) buffer[startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_DESCRIPTOR_TYPE], StandardIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_STANDARD_IDENTIFIER, 5), Version = (sbyte) buffer[startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_DESCRIPTOR_VERSION], SystemIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_SYSTEM_IDENTIFIER, 32).Trim(), Identifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_IDENTIFIER, 32).Trim(), volumeSpaceSizeTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_VOLUME_SPACE_SIZE), volumeSpaceSizeTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_VOLUME_SPACE_SIZE), volumeSetSizeTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_VOLUME_SET_SIZE), VolumeSetSizeTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_VOLUME_SET_SIZE), volumeSequenceNumberTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_VOLUME_SEQUENCE_NUMBER), volumeSequenceNumberTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_VOLUME_SEQUENCE_NUMBER), logicalBlockSizeTypeL = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_LOGICAL_BLOCK_SIZE), logicalBlockSizeTypeM = BitConverter.ToUInt16(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_LOGICAL_BLOCK_SIZE), pathTableSizeTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_PATH_TABLE_SIZE), pathTableSizeTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_PATH_TABLE_SIZE), pathTableLocationTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_PATH_TABLE), optionalPathTableLocationTypeL = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_L_OPTIONAL_PATH_TABLE), pathTableLocationTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_PATH_TABLE), optionalPathTableLocationTypeM = BitConverter.ToUInt32(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_TYPE_M_OPTIONAL_PATH_TABLE), SetIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_SET_IDENTIFIER, 128).Trim(), PublisherIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_PUBLISHER_IDENTIFIER, 128).Trim(), PreparerIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_PREPARER_IDENTIFIER, 128).Trim(), ApplicationIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_APPLICATION_IDENTIFIER, 128).Trim(), CopyrightFileIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_COPYRIGHT_FILE_IDENTIFIER, 37).Trim(), AbstractFileIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_ABSTRACT_FILE_IDENTIFIER, 37).Trim(), BibliographicFileIdentifier = Encoding.Default.GetString(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_BIBLIOGRAPHIC_FILE_IDENTIFIER, 37).Trim(), CreationDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_CREATION_DATE), ModificationDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_MODIFICATION_DATE), ExpirationDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_EXPIRATION_DATE), EffectiveDateTime = VolumeDescriptorConverter.VolumeDescriptorDateTimeConverter.ToDateTime(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_VOLUME_EFFECTIVE_DATE), FileStructureVersion = (sbyte) buffer[startIndex + (int) VolumeDescriptorConverter.OFFSET_FILE_STRUCTURE_VERSION] }; volumeDescriptor.rootDirectoryRecord = DirectoryRecordConverter.ToRootDirectoryRecord(buffer, startIndex + (int) VolumeDescriptorConverter.OFFSET_ROOT_DIRECTORY_RECORD); if (!VolumeDescriptorConverter.STANDARD_IDENTIFIER.Equals(volumeDescriptor.StandardIdentifier) || volumeDescriptor.Type != VolumeDescriptorType.PRIMARY_VOLUME_DESCRIPTOR || (int) volumeDescriptor.Version != (int) VolumeDescriptorConverter.VOLUME_DESCRIPTOR_VERSION) throw new FormatException(); return volumeDescriptor; } private sealed class VolumeDescriptorDateTimeConverter { private static readonly Logger.ILog logger = Logger.CreateLog(); private const int DATETIME_SIZE = 17; private const int OFFSET_YEAR = 0; private const int OFFSET_MONTH = 4; private const int OFFSET_DAY = 6; private const int OFFSET_HOUR = 8; private const int OFFSET_MINUTE = 10; private const int OFFSET_SECOND = 12; private const int OFFSET_HUNDREDTHS_OF_SECOND = 14; private const int OFFSET_TIME_ZONE = 16; internal static DateTime? ToDateTime(byte[] buffer, int startIndex) { if (startIndex < 0 || buffer.Length - startIndex < 17) throw new ArgumentOutOfRangeException(); string str = Encoding.Default.GetString(buffer, startIndex, 16); ushort result1; ushort.TryParse(str.Substring(0, 4), out result1); byte result2; byte.TryParse(str.Substring(4, 2), out result2); byte result3; byte.TryParse(str.Substring(6, 2), out result3); byte result4; byte.TryParse(str.Substring(8, 2), out result4); byte result5; byte.TryParse(str.Substring(10, 2), out result5); byte result6; byte.TryParse(str.Substring(12, 2), out result6); byte result7; byte.TryParse(str.Substring(14, 2), out result7); try { return new DateTime?(new DateTime((int) result1, (int) result2, (int) result3, (int) result4, (int) result5, (int) result6, (int) result7 * 100, DateTimeKind.Local)); } catch (Exception ex) { logger.Warn(ex); return new DateTime?(); } } } } }