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); }
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); }