Example #1
0
        private static void ProcessChunks(ChunkReader chunkReader, Stream stream, long readLength,
                                          IReadOnlyDictionary <uint, ObjectActivator <IResourceReader> > activators,
                                          ICollection <IResource> resources,
                                          IResourceReader resourceReader = null)
        {
            var endPosition = stream.Position + readLength;

            while (stream.Position < endPosition)
            {
                var chunk = chunkReader.NextChunk();

                // Make sure we're dealing with a data chunk (ID 0 = padding)
                if (chunk.Id != 0)
                {
                    // resourceReader will be null if we're at the top level
                    if (resourceReader == null)
                    {
                        // Create resource reader and recurse
                        var activatorExists = activators.TryGetValue(chunk.Id, out var activator);
                        var newReader       = activatorExists
                            ? activator()
                            : new GenericResourceReader();

                        if (activatorExists && chunk.IsContainer)
                        {
                            ProcessChunks(chunkReader, stream, chunk.Size, activators, resources, newReader);
                        }
                        else
                        {
                            newReader.ProcessChunk(chunk, chunkReader.BinaryReader);
                        }

                        var resource = newReader.GetResource();
                        Debug.Assert(resource != null, "resource != null");
                        resources.Add(resource);
                    }
                    else
                    {
                        if (chunk.IsContainer)
                        {
                            ProcessChunks(chunkReader, stream, chunk.Size, activators, resources, resourceReader);
                        }
                        else
                        {
                            resourceReader.ProcessChunk(chunk, chunkReader.BinaryReader);
                        }
                    }
                }

                stream.Position = chunk.EndOffset;
            }
        }