예제 #1
0
        private int PushChunkRead(bool firstChunk)
        {
            Chunk chunk;
            int   err;

            byte[] buffer;

            var top = GetCurrentContext();

            if (top == null && !firstChunk)
            {
                return((int)ParserStatus.EndOfFile);
            }
            var type = top != null ? top.Type : 0;

            if (firstChunk)
            {
                buffer = new byte[Marshal.SizeOf <SmallChunk>()];
                err    = _streamOperations.Read(_ioContext, buffer, 0, buffer.Length);
                if (err != Marshal.SizeOf <SmallChunk>())
                {
                    if (err >= 0)
                    {
                        err = (int)ParserStatus.NotIFF;
                    }
                    return(err);
                }
                var smallChunk = Marshal.BytesToStruct <SmallChunk>(buffer);
                chunk.Id   = smallChunk.Id;
                chunk.Size = smallChunk.Size;

                if (chunk.Size == (ulong)ChunkSize.Known64Bit)
                {
                    buffer = new byte[chunk.Size];
                    err    = _streamOperations.Read(_ioContext, buffer, 0, buffer.Length);
                    if ((ulong)err != chunk.Size)
                    {
                        if (err >= 0)
                        {
                            err = (int)ParserStatus.NotIFF;
                        }
                        return(err);
                    }
                    chunk.Size = BitConverter.ToUInt32(buffer, 0);
                }
                else if (chunk.Size >= (ulong)ChunkSize.Reserved)
                {
                    return((int)ParserStatus.Mangled);
                }
            }
            else
            {
                /* Using ReadChunk() causes these bytes to go into the
                 * parent's scan count
                 */
                buffer = new byte[Marshal.SizeOf <SmallChunk>()];
                err    = ReadChunk(buffer, 0, buffer.Length);
                if (err != Marshal.SizeOf <SmallChunk>())
                {
                    if (err >= 0)
                    {
                        err = (int)ParserStatus.PrematureEndOfFile;
                    }
                    return(err);
                }

                var smallChunk = Marshal.BytesToStruct <SmallChunk>(buffer);
                chunk.Id   = smallChunk.Id;
                chunk.Size = smallChunk.Size;

                if (chunk.Size == (ulong)ChunkSize.Known64Bit)
                {
                    buffer = new byte[chunk.Size];
                    err    = _streamOperations.Read(_ioContext, buffer, 0, buffer.Length);
                    if ((ulong)err != chunk.Size)
                    {
                        if (err >= 0)
                        {
                            err = (int)ParserStatus.NotIFF;
                        }
                        return(err);
                    }
                    chunk.Size = BitConverter.ToUInt32(buffer, 0);
                }
                else if (chunk.Size >= (ulong)ChunkSize.Reserved)
                {
                    return((int)ParserStatus.Mangled);
                }
                if (chunk.Size > (top.Size - top.Offset))
                {
                    return((int)ParserStatus.Mangled);
                }
            }
            if (IdUtility.IsGoodId(chunk.Id))
            {
                try {
                    var contextNode = new ContextNode(chunk.Id, type);
                    contextNode.Size        = chunk.Size;
                    contextNode.Offset      = 0;
                    contextNode.CurrentSize = chunk.Size;

                    _stack.AddHead(contextNode);
                    return(0);
                } catch (OutOfMemoryException) {
                    return((int)ParserStatus.OutOfMemory);
                }
            }
            if (this._newIO)
            {
                return((int)ParserStatus.NotIFF);
            }
            return((int)ParserStatus.SyntaxError);
        }