Exemplo n.º 1
0
        private int ReadGenericType()
        {
            ContextNode top;
            int         result;

            if ((top = GetCurrentContext()) != null)
            {
                var buffer = new byte[sizeof(uint)];
                result = ReadChunk(buffer, 0, buffer.Length);
                var type = BitConverter.ToUInt32(buffer, 0);
                Swap(ref type);
                top.Type = type;
                if (result == sizeof(uint))
                {
                    if (IdUtility.IsGoodType(top.Type))
                    {
                        return(0);
                    }
                    return((int)ParserStatus.Mangled);
                }
                if (result >= 0)
                {
                    result = (int)ParserStatus.PrematureEndOfFile;
                }
                return(result);
            }
            return((int)ParserStatus.EndOfFile);
        }
Exemplo n.º 2
0
        private int PushChunkWrite(uint type, uint id, uint size)
        {
            ContextNode cn;
            int         err;
            uint        parentType;
            Chunk       chunk;
            SmallChunk  smallChunk;
            bool        firstChunk;

            byte[] buffer;

            if ((cn = GetCurrentContext()) != null)
            {
                parentType = cn.Type;
                firstChunk = false;
            }
            else if (_newIO)
            {
                parentType = 0;
                firstChunk = true;
                _newIO     = false;

                /* first chunk must be FORM, CAT, or LIST */
                if ((id != GenericChunkIds.ID_FORM) &&
                    (id != GenericChunkIds.ID_CAT) &&
                    (id != GenericChunkIds.ID_LIST))
                {
                    return((int)ParserStatus.NotIFF);
                }
            }
            else
            {
                return((int)ParserStatus.EndOfFile);
            }
            if (!IdUtility.IsGoodId(id))
            {
                return((int)ParserStatus.SyntaxError);
            }
            if (IdUtility.IsGenericId(id))
            {
                if (id == GenericChunkIds.ID_PROP)
                {
                    /* the containing context for PROP must be a LIST */
                    if (cn.Id != GenericChunkIds.ID_LIST)
                    {
                        return((int)ParserStatus.SyntaxError);
                    }
                }
                /* Generic ID.  Check the validity of its subtype. */
                if (!IdUtility.IsGoodType(type))
                {
                    return((int)ParserStatus.NotIFF);
                }
            }
            else
            {
                /* Non-generic ID.  Containing context must be PROP or FORM or container */
                if ((cn.Id != GenericChunkIds.ID_FORM) &&
                    (cn.Id != GenericChunkIds.ID_PROP) &&
                    (!IsContainerId(cn.Id)))
                {
                    return((int)ParserStatus.SyntaxError);
                }
            }

            /* Write the chunk header: ID and size (if IFF_SIZE_UNKNOWN, it will
             * be patched later by PopChunkW()).
             */
            if ((size >= (uint)ChunkSize.Reserved) &&
                (size != (uint)ChunkSize.Unknown32Bit))
            {
                chunk.Id     = id;
                chunk.Filler = (uint)ChunkSize.Known64Bit;
                chunk.Size   = size;

                buffer = Marshal.StructToBytes(chunk);

                if (firstChunk)
                {
                    err = _streamOperations.Write(_ioContext, buffer, 0, buffer.Length);
                }
                else
                {
                    /* Update parent's count of bytes written. */
                    err = WriteChunkInternal(cn, buffer, 0, buffer.Length);
                }
            }
            else
            {
                smallChunk.Id   = id;
                smallChunk.Size = size;
                buffer          = Marshal.StructToBytes(smallChunk);

                if (firstChunk)
                {
                    err = _streamOperations.Write(_ioContext, buffer, 0, buffer.Length);
                }
                else
                {
                    /* Update parent's count of bytes written. */
                    err = WriteChunkInternal(cn, buffer, 0, buffer.Length);
                }
            }
            if (err < 0)
            {
                return(err);
            }
            /* Allocate and fill in a ContextNode for the new chunk */
            cn             = new ContextNode(id, 0);
            cn.Size        = size;
            cn.Offset      = 0;
            cn.CurrentSize = 0;
            _stack.AddHead(cn);

            /* For generic chunks, write the type out now that
             * the chunk context node is initialized.
             */
            if (IdUtility.IsGenericId(id) || IsContainerId(id))
            {
                if (IdUtility.IsGenericId(id))
                {
                    var bigEndianType = type;
                    Swap(ref bigEndianType);
                    buffer  = BitConverter.GetBytes(bigEndianType);
                    err     = WriteChunkInternal(cn, buffer, 0, buffer.Length);
                    cn.Type = type;
                }
                else
                {
                    cn.Type = 0;
                }
            }
            else
            {
                cn.Type = parentType;
            }
            return(err);
        }