Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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;
                }
            }
        }