public static async Task SkipAsync(IBinaryStream stream) { stream.Position += 3; var majorVersion = await stream.ReadByteAsync().ConfigureAwait(false); var revision = await stream.ReadByteAsync().ConfigureAwait(false); var flags = await stream.ReadByteAsync().ConfigureAwait(false); var size = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false)); var newStreamPosition = stream.Position + size; if (await stream.GetLengthAsync().ConfigureAwait(false) < newStreamPosition) { newStreamPosition = await stream.GetLengthAsync().ConfigureAwait(false); } stream.Position = newStreamPosition; }
public static async Task <Id3v2> ParseAsync(IBinaryStream stream) { stream.Position += 3; var id3v2 = new Id3v2(); var majorVersion = await stream.ReadByteAsync().ConfigureAwait(false); var revision = await stream.ReadByteAsync().ConfigureAwait(false); var flags = await stream.ReadByteAsync().ConfigureAwait(false); var size = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false)); var endingPosition = stream.Position + size; while (stream.Position < endingPosition) { var frameId = await stream.ReadStringAsync(4).ConfigureAwait(false); if (!Id3v2.IsValidAlphaNumeric(frameId)) { stream.Position = endingPosition; break; } var frameSize = 0U; switch (majorVersion) { case 4: frameSize = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false)); break; case 3: frameSize = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false); break; default: throw new NotSupportedException(); } var frameFlags = await stream.ReadUInt16Async(ByteOrder.LittleEndian).ConfigureAwait(false); switch (frameId) { case "TIT2": id3v2.Title = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TALB": id3v2.Album = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TOAL": break; case "TPE1": id3v2.Artist = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TPE2": id3v2.AlbumArtist = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TRCK": var track = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); if (track != null) { id3v2.Track = ParseTrack(track); } break; case "TYER": var year = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); if (year != null) { id3v2.Year = ParseYear(year); } break; case "APIC": var readBytes = 0U; var encoding = (FrameEncoding)await stream.ReadByteAsync().ConfigureAwait(false); readBytes++; while (await stream.ReadByteAsync().ConfigureAwait(false) != 0) // MIME type <text string> $00 { readBytes++; } readBytes++; var pictureType = await stream.ReadByteAsync().ConfigureAwait(false); readBytes++; while (await stream.ReadByteAsync().ConfigureAwait(false) != 0) // <text string according to encoding> $00 (00) { readBytes++; } id3v2.Cover = new DataLocation(stream.Position, frameSize - readBytes - 1); stream.Position += frameSize - readBytes - 1; break; case "TCON": case "COMM": default: stream.Position += frameSize; break; } } return(id3v2); }