/// <summary> /// Populates the current instance with the contents of the /// raw ID3v2 frame. /// </summary> /// <param name="data"> /// A <see cref="ByteVector" /> object containing the raw /// extended header structure. /// </param> /// <param name="version"> /// A <see cref="byte" /> value indicating the ID3v2 version. /// </param> protected void Parse(ByteVector data, byte version) { if (data == null) { throw new ArgumentNullException("data"); } size = (version == 3 ? 4u : 0u) + SynchData.ToUInt(data.Mid(0, 4)); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="Header" /> by reading it from raw header data. /// </summary> /// <param name="data"> /// A <see cref="ByteVector" /> object containing the raw /// data to build the new instance from. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="data" /> is <see langword="null" />. /// </exception> /// <exception cref="CorruptFileException"> /// <paramref name="data" /> is smaller than <see /// cref="Size" />, does not begin with <see /// cref="FileIdentifier" />, contains invalid flag data, /// or contains invalid size data. /// </exception> public Header(ByteVector data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Count < Size) { throw new CorruptFileException( "Provided data is smaller than object size."); } if (!data.StartsWith(FileIdentifier)) { throw new CorruptFileException( "Provided data does not start with the file identifier"); } major_version = data [3]; revision_number = data [4]; flags = (HeaderFlags)data [5]; if (major_version == 2 && ((int)flags & 127) != 0) { throw new CorruptFileException( "Invalid flags set on version 2 tag."); } if (major_version == 3 && ((int)flags & 15) != 0) { throw new CorruptFileException( "Invalid flags set on version 3 tag."); } if (major_version == 4 && ((int)flags & 7) != 0) { throw new CorruptFileException( "Invalid flags set on version 4 tag."); } for (int i = 6; i < 10; i++) { if (data [i] >= 128) { throw new CorruptFileException( "One of the bytes in the header was greater than the allowed 128."); } } tag_size = SynchData.ToUInt(data.Mid(6, 4)); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="FrameHeader" /> by reading it from raw header data /// of a specified version. /// </summary> /// <param name="data"> /// A <see cref="ByteVector" /> object containing the raw /// data to build the new instance from. /// </param> /// <param name="version"> /// A <see cref="byte" /> value containing the ID3v2 version /// with which the data in <paramref name="data" /> was /// encoded. /// </param> /// <remarks> /// If the data size is smaller than the size of a full /// header, the data is just treated as a frame identifier /// and the remaining values are zeroed. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="data" /> is <see langword="null" />. /// </exception> /// <exception cref="CorruptFileException"> /// <paramref name="data" /> is smaller than the size of a /// frame identifier or <paramref name="version" /> is less /// than 2 or more than 4. /// </exception> public FrameHeader(ByteVector data, byte version) { if (data == null) { throw new ArgumentNullException("data"); } flags = 0; frame_size = 0; if (version < 2 || version > 4) { throw new CorruptFileException( "Unsupported tag version."); } if (data.Count < (version == 2 ? 3 : 4)) { throw new CorruptFileException( "Data must contain at least a frame ID."); } switch (version) { case 2: // Set the frame ID -- the first three bytes frame_id = ConvertId(data.Mid(0, 3), version, false); // If the full header information was not passed // in, do not continue to the steps to parse the // frame size and flags. if (data.Count < 6) { return; } frame_size = data.Mid(3, 3).ToUInt(); return; case 3: // Set the frame ID -- the first four bytes frame_id = ConvertId(data.Mid(0, 4), version, false); // If the full header information was not passed // in, do not continue to the steps to parse the // frame size and flags. if (data.Count < 10) { return; } // Store the flags internally as version 2.4. frame_size = data.Mid(4, 4).ToUInt(); flags = (FrameFlags)( ((data [8] << 7) & 0x7000) | ((data [9] >> 4) & 0x000C) | ((data [9] << 1) & 0x0040)); return; case 4: // Set the frame ID -- the first four bytes frame_id = new ReadOnlyByteVector( data.Mid(0, 4)); // If the full header information was not passed // in, do not continue to the steps to parse the // frame size and flags. if (data.Count < 10) { return; } frame_size = SynchData.ToUInt(data.Mid(4, 4)); flags = (FrameFlags)data.Mid(8, 2).ToUShort(); return; default: throw new CorruptFileException( "Unsupported tag version."); } }