private static void ValidateChunk(RiffChunk chunk, ref ValidationResult result) { var listChunk = chunk as ListChunk; if (listChunk == null) throw new FormatException("\"chunk\" must be a ListChunk"); if (listChunk.TypeId == FourCc.Zero) result.EditValidity(Validity.Invalid, "\"TypeId\" cannot be equal to zero"); listChunk._validationProcedure?.Invoke(listChunk, ref result); }
private static void WriteChunk(RiffChunk chunk, BinaryWriter writer) { var listChunk = chunk as ListChunk; if (listChunk == null) throw new FormatException("\"chunk\" must be a ListChunk"); writer.Write(listChunk.TypeId.ToUInt32()); listChunk._writeProcedure?.Invoke(listChunk, writer); }
private static void ReadChunk(RiffChunk chunk, BinaryReader reader) { var listChunk = chunk as ListChunk; if (listChunk == null) throw new FormatException("\"chunk\" must be a ListChunk"); // Verify that the type ID read from the stream matches the expected type ID var typeIdRead = reader.ReadFourCc(); var typeIdExpected = listChunk.TypeId; if (typeIdRead != typeIdExpected) { listChunk.TypeId = typeIdRead; throw new RiffException( $"The LIST chunk TypeId read from the stream ({typeIdRead}) does not match the expected value ({typeIdExpected})"); } // Run the read procedure listChunk._readProcedure?.Invoke(listChunk, reader); // Only predefined chunk IDs will be read into the LIST chunk // If the procedure list is empty, the entire contents of the LIST chunk will be ignored if (listChunk._subchunkProcedures.Count == 0) throw new RiffException("No subchunk IDs have been defined"); // Add all defined subchunks var bytesRemaining = listChunk.StreamIndicatedSize - 4; while (bytesRemaining > 0 && (reader.BaseStream.Length - reader.BaseStream.Position > 2)) { var chunkId = reader.ReadFourCc(); if (listChunk._subchunkProcedures.Exists(set => set is ListChunkProcedureSet && set.Id == chunkId)) { var chunkTypeId = reader.PeekFourCc(4); var listChunkProcedure = listChunk._subchunkProcedures .OfType<ListChunkProcedureSet>() .First(set => set.Id == chunkId && set.TypeId == chunkTypeId); if (listChunkProcedure != null) listChunk.Children.Add(new ListChunk(reader, listChunkProcedure)); } else if (listChunk._subchunkProcedures.Exists(set => set.Id == chunkId)) { var chunkProcedure = listChunk._subchunkProcedures.First(set => set.Id == chunkId); if (chunkProcedure != null) listChunk.Children.Add(new RiffChunk(reader, chunkProcedure)); bytesRemaining -= listChunk.Children.Last.ActualSize; } else { bytesRemaining -= SkipUnknownChunk(reader) + listChunk.HeaderSize; } } }