Esempio n. 1
0
        // PROCESS CHUNKS
        private static void ProcessChunks(SequentialReader reader, long maxPosition, IRiffHandler handler)
        {
            // Processing chunks. Each chunk is 8 bytes header (4 bytes CC code + 4 bytes length of chunk) + data of the chunk

            while (reader.Position < maxPosition - 8)
            {
                string chunkFourCc = reader.GetString(4, Encoding.ASCII);
                int    chunkSize   = reader.GetInt32();

                // NOTE we fail a negative chunk size here (greater than 0x7FFFFFFF) as we cannot allocate arrays larger than this
                if (chunkSize < 0 || chunkSize + reader.Position > maxPosition)
                {
                    throw new RiffProcessingException("Invalid RIFF chunk size");
                }

                if (chunkFourCc == "LIST" || chunkFourCc == "RIFF")
                {
                    string listName = reader.GetString(4, Encoding.ASCII);
                    if (handler.ShouldAcceptList(listName))
                    {
                        ProcessChunks(reader, reader.Position + chunkSize - 4, handler);
                    }
                    else
                    {
                        reader.Skip(chunkSize - 4);
                    }
                }
                else
                {
                    if (handler.ShouldAcceptChunk(chunkFourCc))
                    {
                        // TODO is it feasible to avoid copying the chunk here, and to pass the sequential reader to the handler?
                        handler.ProcessChunk(chunkFourCc, reader.GetBytes(chunkSize));
                    }
                    else
                    {
                        reader.Skip(chunkSize);
                    }

                    // Skip any padding byte added to keep chunks aligned to even numbers of bytes
                    if (chunkSize % 2 == 1)
                    {
                        reader.Skip(1);
                    }
                }
            }
        }
Esempio n. 2
0
        // PROCESS CHUNKS
        public void ProcessChunks([NotNull] SequentialReader reader, int sizeLeft, [NotNull] IRiffHandler handler)
        {
            // Processing chunks. Each chunk is 8 bytes header (4 bytes CC code + 4 bytes length of chunk) + data of the chunk

            while (reader.Position < sizeLeft)
            {
                // Check if end of the file is closer then 8 bytes
                if (reader.IsCloserToEnd(8))
                {
                    return;
                }

                string chunkFourCc = reader.GetString(4, Encoding.ASCII);
                int    chunkSize   = reader.GetInt32();

                sizeLeft -= 8;

                // NOTE we fail a negative chunk size here (greater than 0x7FFFFFFF) as we cannot allocate arrays larger than this
                if (chunkSize < 0 || sizeLeft < chunkSize)
                {
                    throw new RiffProcessingException("Invalid RIFF chunk size");
                }

                // Check if end of the file is closer then chunkSize bytes
                if (reader.IsCloserToEnd(chunkSize))
                {
                    return;
                }

                if (chunkFourCc == "LIST" || chunkFourCc == "RIFF")
                {
                    string listName = reader.GetString(4, Encoding.ASCII);
                    if (handler.ShouldAcceptList(listName))
                    {
                        ProcessChunks(reader, sizeLeft - 4, handler);
                    }
                    else
                    {
                        reader.Skip(sizeLeft - 4);
                    }
                    sizeLeft -= chunkSize;
                }
                else
                {
                    if (handler.ShouldAcceptChunk(chunkFourCc))
                    {
                        // TODO is it feasible to avoid copying the chunk here, and to pass the sequential reader to the handler?
                        handler.ProcessChunk(chunkFourCc, reader.GetBytes(chunkSize));
                    }
                    else
                    {
                        reader.Skip(chunkSize);
                    }

                    sizeLeft -= chunkSize;

                    // Skip any padding byte added to keep chunks aligned to even numbers of bytes
                    if (chunkSize % 2 == 1)
                    {
                        reader.GetSByte();
                        sizeLeft--;
                    }
                }
            }
        }