/// <summary> /// Reads an ID3v2 tag from a stream. Returns null if no ID3v2 tag can be found /// in the stream. /// </summary> /// <param name="stream">The stream to read.</param> /// <returns>The tag read from the stream, or null if no ID3v2 tag can be found.</returns> public static ID3v2Tag ReadTag(Stream stream) { ID3Versions version = LookForTag(stream); ID3v2Tag tag = null; if ((version & ID3Versions.V2) == ID3Versions.V2) { tag = new ID3v2Tag(); tag.headerFlags = ReadFlags(stream, version); int tagSize = ReadTagSize(stream); // Go to the first byte after the header stream.Seek(TAG_HEADER_LENGTH, SeekOrigin.Begin); while (stream.Position < tagSize) { ID3v2Frame newFrame = ID3v2Frame.ReadFrame(stream, version); if (newFrame != null) { tag.AddFrame(newFrame); } else { break; } } } return(tag); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="tag">The tag to copy.</param> public ID3v2Tag(ID3Tag tag) : base(tag) { ID3v2Tag v2Tag = tag as ID3v2Tag; if (v2Tag != null) { this.paddingSize = v2Tag.paddingSize; this.headerFlags = v2Tag.headerFlags; this.frames = new Dictionary <FrameType, ID3v2Frame>(v2Tag.FrameCount); foreach (ID3v2Frame frame in v2Tag.Frames) { this.AddFrame(frame.Copy()); } } }
/// <summary> /// Examines the stream to see if there is sufficient space for the tag to be written. /// If there is not enough space, sufficient space is made. /// </summary> /// <param name="stream">The stream to check for space.</param> /// <param name="writeVersion">The version to use in calculating space required.</param> private void EnsureSpace(Stream stream, ID3Versions writeVersion) { ID3Versions existingTagVersion = ID3v2Tag.LookForTag(stream); if ((existingTagVersion & ID3Versions.V2) == ID3Versions.V2) { int existingSize = ReadTagSize(stream); if (existingSize < this.GetTotalSize(writeVersion)) { SmartPadding(stream, existingSize, writeVersion); } else { this.PaddingSize += existingSize - this.GetTotalSize(writeVersion); } } else { SmartPadding(stream, 0, writeVersion); } }
/// <summary> /// Removes any ID3v2 tag from a stream. /// </summary> /// <param name="stream">The stream whose ID3v2 tag will be removed.</param> public static void RemoveTag(Stream stream) { ID3Versions version = ID3v2Tag.LookForTag(stream); if ((version & ID3Versions.V2) == ID3Versions.V2) { int tagSize = ReadTagSize(stream); long newSize = stream.Length - tagSize; int bufLength; long startPosition; byte[] buffer; stream.Seek(tagSize, SeekOrigin.Begin); while (stream.Position < stream.Length) { bufLength = 10000; if (stream.Position + bufLength > stream.Length) { bufLength = (int)(stream.Length - stream.Position); } buffer = new byte[bufLength]; stream.Read(buffer, 0, bufLength); startPosition = stream.Position; stream.Position = startPosition - (tagSize + bufLength); stream.Write(buffer, 0, bufLength); stream.Position = startPosition; } stream.Flush(); stream.SetLength(newSize); } else { throw new TagNotFoundException("No tag found"); } }