// Token: 0x06003227 RID: 12839 RVA: 0x00146D2C File Offset: 0x00144F2C internal void Read(MidiReader reader, ReadingSettings settings) { uint num = reader.ReadDword(); long position = reader.Position; this.ReadContent(reader, settings, num); long num2 = reader.Position - position; if (settings.InvalidChunkSizePolicy == InvalidChunkSizePolicy.Abort && num2 != (long)((ulong)num)) { throw new InvalidChunkSizeException((long)((ulong)num), num2); } long num3 = (long)((ulong)num - (ulong)num2); if (num3 > 0L) { reader.Position += num3; } }
/// <summary> /// Reads chunk from the <see cref="MidiReader"/>'s underlying stream according to /// specified <see cref="ReadingSettings"/>. /// </summary> /// <param name="reader">Reader to read the chunk's data with.</param> /// <param name="settings">Settings according to which the chunk's data must be read.</param> /// <exception cref="ObjectDisposedException">Method was called after <paramref name="reader"/> /// was disposed.</exception> /// <exception cref="IOException">An I/O error occurred on the <paramref name="reader"/>'s /// underlying stream.</exception> /// <exception cref="InvalidChunkSizeException">Actual chunk's size differs from the one declared /// in its header.</exception> /// <exception cref="NotEnoughBytesException">Size of the chunk cannot be read since the reader's /// underlying stream doesn't have enough bytes.</exception> internal void Read(MidiReader reader, ReadingSettings settings) { var size = reader.ReadDword(); var readerPosition = reader.Position; ReadContent(reader, settings, size); var bytesRead = reader.Position - readerPosition; if (settings.InvalidChunkSizePolicy == InvalidChunkSizePolicy.Abort && bytesRead != size) { throw new InvalidChunkSizeException(size, bytesRead); } // Skip unread bytes var bytesUnread = size - bytesRead; if (bytesUnread > 0) { reader.Position += bytesUnread; } }
// Token: 0x0600340E RID: 13326 RVA: 0x001488A0 File Offset: 0x00146AA0 public static MidiFile Read(Stream stream, ReadingSettings settings = null) { if (settings == null) { settings = new ReadingSettings { InvalidChannelEventParameterValuePolicy = InvalidChannelEventParameterValuePolicy.SnapToLimits, InvalidChunkSizePolicy = InvalidChunkSizePolicy.Ignore, NotEnoughBytesPolicy = NotEnoughBytesPolicy.Ignore, InvalidMetaEventParameterValuePolicy = InvalidMetaEventParameterValuePolicy.SnapToLimits, UnexpectedTrackChunksCountPolicy = UnexpectedTrackChunksCountPolicy.Ignore, TextEncoding = Encoding.UTF8 }; } MidiFile midiFile = new MidiFile(); int? num = null; int num2 = 0; bool flag = false; try { using (MidiReader midiReader = new MidiReader(stream)) { long? num3 = null; string text = midiReader.ReadString("RIFF".Length); if (text == "RIFF") { midiReader.Position += 12L; uint num4 = midiReader.ReadDword(); num3 = new long?(midiReader.Position + (long)((ulong)num4)); } else { midiReader.Position -= (long)text.Length; } while (!midiReader.EndReached) { if (num3 != null) { long position = midiReader.Position; long?num5 = num3; if (!(position < num5.GetValueOrDefault() & num5 != null)) { break; } } MidiChunk midiChunk = MidiFile.ReadChunk(midiReader, settings, num2, num); if (midiChunk != null) { HeaderChunk headerChunk = midiChunk as HeaderChunk; if (headerChunk != null) { if (!flag) { num = new int?((int)headerChunk.TracksNumber); midiFile.TimeDivision = headerChunk.TimeDivision; midiFile._originalFormat = new ushort?(headerChunk.FileFormat); } flag = true; } else { if (midiChunk is TrackChunk) { num2++; } midiFile.Chunks.Add(midiChunk); } } } if (num != null) { int num6 = num2; int?num7 = num; if (!(num6 == num7.GetValueOrDefault() & num7 != null)) { MidiFile.ReactOnUnexpectedTrackChunksCount(settings.UnexpectedTrackChunksCountPolicy, num2, num.Value); } } if (!flag) { midiFile.TimeDivision = null; if (settings.NoHeaderChunkPolicy == NoHeaderChunkPolicy.Abort) { throw new NoHeaderChunkException(); } } } } catch (NotEnoughBytesException exception) { MidiFile.ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, exception); } catch (EndOfStreamException exception2) { MidiFile.ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, exception2); } return(midiFile); }
// Token: 0x06003410 RID: 13328 RVA: 0x00148C28 File Offset: 0x00146E28 private static MidiChunk ReadChunk(MidiReader reader, ReadingSettings settings, int actualTrackChunksCount, int?expectedTrackChunksCount) { MidiChunk midiChunk = null; try { string text = reader.ReadString(4); if (text.Length < 4) { NotEnoughBytesPolicy notEnoughBytesPolicy = settings.NotEnoughBytesPolicy; if (notEnoughBytesPolicy == NotEnoughBytesPolicy.Abort) { throw new NotEnoughBytesException("Chunk ID cannot be read since the reader's underlying stream doesn't have enough bytes.", 4L, (long)text.Length); } if (notEnoughBytesPolicy == NotEnoughBytesPolicy.Ignore) { return(null); } } if (!(text == "MThd")) { if (!(text == "MTrk")) { midiChunk = MidiFile.TryCreateChunk(text, settings.CustomChunkTypes); } else { midiChunk = new TrackChunk(); } } else { midiChunk = new HeaderChunk(); } if (midiChunk == null) { switch (settings.UnknownChunkIdPolicy) { case UnknownChunkIdPolicy.ReadAsUnknownChunk: midiChunk = new UnknownChunk(text); break; case UnknownChunkIdPolicy.Skip: { uint num = reader.ReadDword(); reader.Position += (long)((ulong)num); return(null); } case UnknownChunkIdPolicy.Abort: throw new UnknownChunkException("'" + text + "' chunk ID is unknown.", text); } } if (midiChunk is TrackChunk && expectedTrackChunksCount != null) { int?num2 = expectedTrackChunksCount; if (actualTrackChunksCount >= num2.GetValueOrDefault() & num2 != null) { MidiFile.ReactOnUnexpectedTrackChunksCount(settings.UnexpectedTrackChunksCountPolicy, actualTrackChunksCount, expectedTrackChunksCount.Value); ExtraTrackChunkPolicy extraTrackChunkPolicy = settings.ExtraTrackChunkPolicy; if (extraTrackChunkPolicy != ExtraTrackChunkPolicy.Read && extraTrackChunkPolicy == ExtraTrackChunkPolicy.Skip) { uint num3 = reader.ReadDword(); reader.Position += (long)((ulong)num3); return(null); } } } midiChunk.Read(reader, settings); } catch (NotEnoughBytesException exception) { MidiFile.ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, exception); } catch (EndOfStreamException exception2) { MidiFile.ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, exception2); } return(midiChunk); }
/// <summary> /// Reads a chunk from a MIDI-file. /// </summary> /// <param name="reader">Reader to read a chunk with.</param> /// <param name="settings">Settings according to which a chunk must be read.</param> /// <param name="actualTrackChunksCount">Actual count of track chunks at the moment.</param> /// <param name="expectedTrackChunksCount">Expected count of track chunks.</param> /// <returns>A MIDI-file chunk.</returns> /// <exception cref="ObjectDisposedException">Method was called after the reader was disposed.</exception> /// <exception cref="IOException">An I/O error occurred on the underlying stream.</exception> /// <exception cref="UnknownChunkException">Chunk to be read has unknown ID and that /// should be treated as error accordng to the specified <paramref name="settings"/>.</exception> /// <exception cref="UnexpectedTrackChunksCountException">Actual track chunks /// count is greater than expected one and that should be treated as error according to /// the specified <paramref name="settings"/>.</exception> /// <exception cref="InvalidChunkSizeException">Actual chunk's size differs from the one declared /// in its header and that should be treated as error according to the specified /// <paramref name="settings"/>.</exception> /// <exception cref="UnknownChannelEventException">Reader has encountered an unknown channel event.</exception> /// <exception cref="NotEnoughBytesException">Value cannot be read since the reader's underlying stream /// doesn't have enough bytes.</exception> /// <exception cref="UnexpectedRunningStatusException">Unexpected running status is encountered.</exception> /// <exception cref="MissedEndOfTrackEventException">Track chunk doesn't end with End Of Track event and that /// should be treated as error accordng to the specified <paramref name="settings"/>.</exception> /// <exception cref="InvalidChannelEventParameterValueException">Value of a channel event's parameter /// just read is invalid.</exception> /// <exception cref="InvalidMetaEventParameterValueException">Value of a meta event's parameter /// just read is invalid.</exception> private static MidiChunk ReadChunk(MidiReader reader, ReadingSettings settings, int actualTrackChunksCount, int?expectedTrackChunksCount) { MidiChunk chunk = null; try { var chunkId = reader.ReadString(MidiChunk.IdLength); if (chunkId.Length < MidiChunk.IdLength) { switch (settings.NotEnoughBytesPolicy) { case NotEnoughBytesPolicy.Abort: throw new NotEnoughBytesException("Chunk ID cannot be read since the reader's underlying stream doesn't have enough bytes.", MidiChunk.IdLength, chunkId.Length); case NotEnoughBytesPolicy.Ignore: return(null); } } // switch (chunkId) { case HeaderChunk.Id: chunk = new HeaderChunk(); break; case TrackChunk.Id: chunk = new TrackChunk(); break; default: chunk = TryCreateChunk(chunkId, settings.CustomChunkTypes); break; } // if (chunk == null) { switch (settings.UnknownChunkIdPolicy) { case UnknownChunkIdPolicy.ReadAsUnknownChunk: chunk = new UnknownChunk(chunkId); break; case UnknownChunkIdPolicy.Skip: var size = reader.ReadDword(); reader.Position += size; return(null); case UnknownChunkIdPolicy.Abort: throw new UnknownChunkException($"'{chunkId}' chunk ID is unknown.", chunkId); } } // if (chunk is TrackChunk && expectedTrackChunksCount != null && actualTrackChunksCount >= expectedTrackChunksCount) { ReactOnUnexpectedTrackChunksCount(settings.UnexpectedTrackChunksCountPolicy, actualTrackChunksCount, expectedTrackChunksCount.Value); switch (settings.ExtraTrackChunkPolicy) { case ExtraTrackChunkPolicy.Read: break; case ExtraTrackChunkPolicy.Skip: var size = reader.ReadDword(); reader.Position += size; return(null); } } // chunk.Read(reader, settings); } catch (NotEnoughBytesException ex) { ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, ex); } catch (EndOfStreamException ex) { ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, ex); } return(chunk); }
/// <summary> /// Reads a MIDI file from the stream. /// </summary> /// <param name="stream">Stream to read file from.</param> /// <param name="settings">Settings according to which the file must be read.</param> /// <returns>An instance of the <see cref="MidiFile"/> representing a MIDI file was read from the stream.</returns> /// <remarks> /// Stream must be readable, seekable and be able to provide its position and length via <see cref="Stream.Position"/> /// and <see cref="Stream.Length"/> properties. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="stream"/> doesn't support reading. -or /// <paramref name="stream"/> doesn't support seeking. -or- <paramref name="stream"/> is already read.</exception> /// <exception cref="IOException">An I/O error occurred while reading from the stream.</exception> /// <exception cref="ObjectDisposedException"><paramref name="stream"/> is disposed. -or- /// Underlying stream reader is disposed.</exception> /// <exception cref="NotSupportedException">Unable to get position of the <paramref name="stream"/>. -or /// Unable to get length of the <paramref name="stream"/>.</exception> /// <exception cref="NoHeaderChunkException">There is no header chunk in a file.</exception> /// <exception cref="InvalidChunkSizeException">Actual header or track chunk's size differs from the one declared /// in its header and that should be treated as error according to the <paramref name="settings"/>.</exception> /// <exception cref="UnknownChunkException">Chunk to be read has unknown ID and that /// should be treated as error accordng to the <paramref name="settings"/>.</exception> /// <exception cref="UnexpectedTrackChunksCountException">Actual track chunks /// count differs from the expected one and that should be treated as error according to /// the specified <paramref name="settings"/>.</exception> /// <exception cref="UnknownFileFormatException">The header chunk contains unknown file format and /// <see cref="ReadingSettings.UnknownFileFormatPolicy"/> property of the <paramref name="settings"/> set to /// <see cref="UnknownFileFormatPolicy.Abort"/>.</exception> /// <exception cref="NotEnoughBytesException">MIDI file cannot be read since the reader's underlying stream doesn't /// have enough bytes.</exception> /// <exception cref="UnexpectedRunningStatusException">Unexpected running status is encountered.</exception> /// <exception cref="MissedEndOfTrackEventException">Track chunk doesn't end with End Of Track event and that /// should be treated as error accordng to the specified <paramref name="settings"/>.</exception> /// <exception cref="InvalidChannelEventParameterValueException">Value of a channel event's parameter /// just read is invalid.</exception> /// <exception cref="InvalidMetaEventParameterValueException">Value of a meta event's parameter /// just read is invalid.</exception> public static MidiFile Read(Stream stream, ReadingSettings settings = null) { ThrowIfArgument.IsNull(nameof(stream), stream); if (!stream.CanRead) { throw new ArgumentException("Stream doesn't support reading.", nameof(stream)); } if (!stream.CanSeek) { throw new ArgumentException("Stream doesn't support seeking.", nameof(stream)); } if (stream.Position >= stream.Length) { throw new ArgumentException("Stream is already read.", nameof(stream)); } // if (settings == null) { settings = new ReadingSettings(); } var file = new MidiFile(); int? expectedTrackChunksCount = null; int actualTrackChunksCount = 0; bool headerChunkIsRead = false; // try { using (var reader = new MidiReader(stream)) { // Read RIFF header long?smfEndPosition = null; var chunkId = reader.ReadString(RiffChunkId.Length); if (chunkId == RiffChunkId) { reader.Position += RmidPreambleSize; var smfSize = reader.ReadDword(); smfEndPosition = reader.Position + smfSize; } else { reader.Position -= chunkId.Length; } // Read SMF while (!reader.EndReached && (smfEndPosition == null || reader.Position < smfEndPosition)) { // Read chunk var chunk = ReadChunk(reader, settings, actualTrackChunksCount, expectedTrackChunksCount); if (chunk == null) { continue; } // Process header chunk var headerChunk = chunk as HeaderChunk; if (headerChunk != null) { if (!headerChunkIsRead) { expectedTrackChunksCount = headerChunk.TracksNumber; file.TimeDivision = headerChunk.TimeDivision; file._originalFormat = headerChunk.FileFormat; } headerChunkIsRead = true; continue; } // Process track chunk if (chunk is TrackChunk) { actualTrackChunksCount++; } // Add chunk to chunks collection of the file file.Chunks.Add(chunk); } if (expectedTrackChunksCount != null && actualTrackChunksCount != expectedTrackChunksCount) { ReactOnUnexpectedTrackChunksCount(settings.UnexpectedTrackChunksCountPolicy, actualTrackChunksCount, expectedTrackChunksCount.Value); } } // Process header chunks count if (!headerChunkIsRead) { file.TimeDivision = null; if (settings.NoHeaderChunkPolicy == NoHeaderChunkPolicy.Abort) { throw new NoHeaderChunkException(); } } } catch (NotEnoughBytesException ex) { ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, ex); } catch (EndOfStreamException ex) { ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, ex); } // return(file); }