protected ByteVector FieldData(ByteVector frameData, int offset, byte version) { if (frameData == null) { throw new ArgumentNullException("frameData"); } int data_offset = offset + (int)FrameHeader.Size(version); int data_length = (int)Size; if ((Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator)) != 0) { data_offset += 4; data_length -= 4; } if ((Flags & FrameFlags.GroupingIdentity) != 0) { if (frameData.Count >= data_offset) { throw new TagLib.CorruptFileException("Frame data incomplete."); } group_id = frameData[data_offset++]; data_length--; } if ((Flags & FrameFlags.Encryption) != 0) { if (frameData.Count >= data_offset) { throw new TagLib.CorruptFileException("Frame data incomplete."); } encryption_id = frameData[data_offset++]; data_length--; } data_length = Math.Min(data_length, frameData.Count - data_offset); if (data_length < 0) { throw new CorruptFileException("Frame size less than zero."); } ByteVector data = frameData.Mid(data_offset, data_length); if ((Flags & FrameFlags.Unsynchronisation) != 0) { int before_length = data.Count; SynchData.ResynchByteVector(data); data_length -= (data.Count - before_length); } if ((Flags & FrameFlags.Encryption) != 0) { throw new NotImplementedException(); } if ((Flags & FrameFlags.Compression) != 0) { throw new NotImplementedException(); } return(data); }
/// <summary> /// Extracts the field data from the raw data portion of an /// ID3v2 frame. /// </summary> /// <param name="frameData"> /// A <see cref="ByteVector" /> object containing fraw frame /// data. /// </param> /// <param name="offset"> /// A <see cref="int" /> value containing the index at which /// the data is contained. /// </param> /// <param name="version"> /// A <see cref="byte" /> value containing the ID3v2 version /// of the data. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// extracted field data. /// </returns> /// <remarks> /// This method is necessary for extracting extra data /// prepended to the frame such as the grouping ID. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="frameData" /> is <see langword="null" />. /// </exception> protected ByteVector FieldData(ByteVector frameData, int offset, byte version) { if (frameData == null) { throw new ArgumentNullException(nameof(frameData)); } int data_offset = offset + (int)FrameHeader.Size(version); int data_length = (int)Size; if ((Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator)) != 0) { data_offset += 4; data_length -= 4; } if ((Flags & FrameFlags.GroupingIdentity) != 0) { if (frameData.Count >= data_offset) { throw new CorruptFileException("Frame data incomplete."); } group_id = frameData[data_offset++]; data_length--; } if ((Flags & FrameFlags.Encryption) != 0) { if (frameData.Count >= data_offset) { throw new CorruptFileException("Frame data incomplete."); } encryption_id = frameData[data_offset++]; data_length--; } data_length = Math.Min(data_length, frameData.Count - data_offset); if (data_length < 0) { throw new CorruptFileException("Frame size less than zero."); } ByteVector data = frameData.Mid(data_offset, data_length); if ((Flags & FrameFlags.Unsynchronisation) != 0) { int before_length = data.Count; SynchData.ResynchByteVector(data); data_length -= (data.Count - before_length); } // FIXME: Implement encryption. if ((Flags & FrameFlags.Encryption) != 0) { throw new NotImplementedException(); } // FIXME: Implement compression. if ((Flags & FrameFlags.Compression) != 0) { throw new NotImplementedException(); } /* * if(d->header->compression()) { * ByteVector data(frameDataLength); * uLongf uLongTmp = frameDataLength; * ::uncompress((Bytef *) data.data(), * (uLongf *) &uLongTmp, * (Bytef *) frameData.data() + frameDataOffset, * size()); * return data; * } */ return(data); }
protected ByteVector FieldData(ByteVector frameData, int offset, byte version) { if (frameData == null) { throw new ArgumentNullException("frameData"); } int data_offset = offset + (int)FrameHeader.Size(version); int data_length = (int)Size; /*int uncompressed_data_length;*/ if ((Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator)) != 0) { /*uncompressed_data_length = (int) frame_data.Mid (data_offset, 4).ToUInt () + 4;*/ data_offset += 4; data_offset -= 4; } if ((Flags & FrameFlags.GroupingIdentity) != 0) { group_id = frameData [data_offset++]; data_length--; } if ((Flags & FrameFlags.Encryption) != 0) { encryption_id = frameData [data_offset++]; data_length--; } if (data_length > frameData.Count - data_offset) { throw new CorruptFileException("Frame size exceeds bounds."); } if (data_length < 0) { throw new CorruptFileException("Frame size less than zero."); } ByteVector data = frameData.Mid(data_offset, data_length); if ((Flags & FrameFlags.Unsychronisation) != 0) { SynchData.ResynchByteVector(data); } // FIXME: Implement encryption. if ((Flags & FrameFlags.Encryption) != 0) { throw new NotImplementedException(); } // FIXME: Implement compression. if ((Flags & FrameFlags.Compression) != 0) { throw new NotImplementedException(); } /* * if(d->header->compression()) { * ByteVector data(frameDataLength); * uLongf uLongTmp = frameDataLength; * ::uncompress((Bytef *) data.data(), * (uLongf *) &uLongTmp, * (Bytef *) frameData.data() + frameDataOffset, * size()); * return data; * } */ return(data); }
protected void Parse(ByteVector data) { if (data == null) { throw new ArgumentNullException("data"); } bool fullTagUnsynch = (header.MajorVersion < 4) && ((header.Flags & HeaderFlags.Unsynchronisation) != 0); if (fullTagUnsynch) { SynchData.ResynchByteVector(data); } int frame_data_position = 0; int frame_data_length = data.Count; if ((header.Flags & HeaderFlags.ExtendedHeader) != 0) { extended_header = new ExtendedHeader(data, header.MajorVersion); if (extended_header.Size <= data.Count) { frame_data_position += (int)extended_header.Size; frame_data_length -= (int)extended_header.Size; } } TextInformationFrame tdrc = null; TextInformationFrame tyer = null; TextInformationFrame tdat = null; TextInformationFrame time = null; while (frame_data_position < frame_data_length - FrameHeader.Size(header.MajorVersion)) { if (data[frame_data_position] == 0) { break; } Frame frame = null; try { frame = FrameFactory.CreateFrame(data, ref frame_data_position, header.MajorVersion, fullTagUnsynch); } catch (NotImplementedException) { continue; } catch (CorruptFileException) { continue; } if (frame == null) { break; } if (frame.Size == 0) { continue; } AddFrame(frame); if (header.MajorVersion == 4) { continue; } if (tdrc == null && frame.FrameId.Equals(FrameType.TDRC)) { tdrc = frame as TextInformationFrame; } else if (tyer == null && frame.FrameId.Equals(FrameType.TYER)) { tyer = frame as TextInformationFrame; } else if (tdat == null && frame.FrameId.Equals(FrameType.TDAT)) { tdat = frame as TextInformationFrame; } else if (time == null && frame.FrameId.Equals(FrameType.TIME)) { time = frame as TextInformationFrame; } } if (tdrc == null || tdat == null || tdrc.ToString().Length > 4) { return; } string year = tdrc.ToString(); if (year.Length != 4) { return; } StringBuilder tdrc_text = new StringBuilder(); tdrc_text.Append(year); if (tdat != null) { string tdat_text = tdat.ToString(); if (tdat_text.Length == 4) { tdrc_text.Append("-").Append(tdat_text, 0, 2).Append("-").Append(tdat_text, 2, 2); if (time != null) { string time_text = time.ToString(); if (time_text.Length == 4) { tdrc_text.Append("T").Append(time_text, 0, 2).Append(":").Append(time_text, 2, 2); } RemoveFrames(FrameType.TIME); } } RemoveFrames(FrameType.TDAT); } tdrc.Text = new string[] { tdrc_text.ToString() }; }