using System; using System.IO; using SabreTools.Data.Models.AACS; namespace SabreTools.Wrappers { public partial class AACSMediaKeyBlock : WrapperBase { #region Descriptive Properties /// public override string DescriptionString => "AACS Media Key Block"; #endregion #region Extension Properties /// /// Media key block records /// public Record[] Records => Model.Records; /// /// Reported version of the media key block /// public string? Version { get { // Use the cached value, if it exists if (field is not null) return field; // Find the type and version record, if possible var record = Array.Find(Records, r => r.RecordType == RecordType.TypeAndVersion); if (record is TypeAndVersionRecord tavr) { field = tavr.VersionNumber.ToString(); return field; } return field; } } = null; #endregion #region Constructors /// public AACSMediaKeyBlock(MediaKeyBlock model, byte[] data) : base(model, data) { } /// public AACSMediaKeyBlock(MediaKeyBlock model, byte[] data, int offset) : base(model, data, offset) { } /// public AACSMediaKeyBlock(MediaKeyBlock model, byte[] data, int offset, int length) : base(model, data, offset, length) { } /// public AACSMediaKeyBlock(MediaKeyBlock model, Stream data) : base(model, data) { } /// public AACSMediaKeyBlock(MediaKeyBlock model, Stream data, long offset) : base(model, data, offset) { } /// public AACSMediaKeyBlock(MediaKeyBlock model, Stream data, long offset, long length) : base(model, data, offset, length) { } #endregion #region Static Constructors /// /// Create an AACS media key block from a byte array and offset /// /// Byte array representing the archive /// Offset within the array to parse /// An AACS media key block wrapper on success, null on failure public static AACSMediaKeyBlock? Create(byte[]? data, int offset) { // If the data is invalid if (data is null || data.Length == 0) return null; // If the offset is out of bounds if (offset < 0 || offset >= data.Length) return null; // Create a memory stream and use that var dataStream = new MemoryStream(data, offset, data.Length - offset); return Create(dataStream); } /// /// Create an AACS media key block from a Stream /// /// Stream representing the archive /// An AACS media key block wrapper on success, null on failure public static AACSMediaKeyBlock? Create(Stream? data) { // If the data is invalid if (data is null || !data.CanRead) return null; try { // Cache the current offset long currentOffset = data.Position; var model = new Serialization.Readers.AACS().Deserialize(data); if (model is null) return null; return new AACSMediaKeyBlock(model, data, currentOffset); } catch { return null; } } #endregion } }