コード例 #1
0
        /// <summary>
        /// Writes the <paramref name="chunk"/> to the file.
        /// </summary>
        /// <param name="chunk">Must not be null.</param>
        /// <returns>Returns the header information for the chunk that has just been written.</returns>
        public FileChunkHeader WriteNextChunk(object chunk)
        {
            Check.IfArgumentNull(chunk, nameof(chunk));

            // find chunk id
            var chunkId = ChunkAttribute.GetChunkId(chunk);

            if (String.IsNullOrEmpty(chunkId))
            {
                var msg = String.Format(
                    CultureInfo.InvariantCulture,
                    "No Chunk Attribute was found for the specified runtime object of type '{0}'.",
                    chunk.GetType().FullName);

                throw new ArgumentException(msg);
            }

            if (chunkId.HasWildcard())
            {
                // TODO: this must be pluggable in some way
                // for now only digits
                chunkId = chunkId.Merge("0000");
            }

            var chunkTypeId  = new FourCharacterCode(chunkId);
            var chunkHandler = _handlerMgr.GetChunkHandler(chunkTypeId);

            if (!chunkHandler.CanWrite(chunk))
            {
                var msg = String.Format(
                    CultureInfo.InvariantCulture,
                    "The chunk handler '{0}' cannot write the specified runtime object.",
                    chunkHandler.ChunkId);

                throw new ArgumentException(msg);
            }

            int stackPos = Context.HeaderStack.Count;
            var header   = PushNewHeader(chunkTypeId);

            chunkHandler.Write(Context, chunk);

            // wind down the stack to the level it was before we started.
            while (Context.HeaderStack.Count > stackPos)
            {
                var poppedHeader = PopHeader();
                WriteChunkHeader(poppedHeader);
            }

            return(header);
        }
コード例 #2
0
        /// <summary>
        /// Reads the next chunk from the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">Must not be null.</param>
        /// <returns>Returns null when there was no runtime chunk type found to represent the chunk read.</returns>
        public object ReadNextChunk(Stream stream)
        {
            Check.IfArgumentNull(stream, nameof(stream));

            object chunkObject = null;

            var chunk = ReadChunkHeader(stream);

            if (chunk != null)
            {
                Context.ChunkStack.PushChunk(chunk);

                var chunkHandler = _handlerMgr.GetChunkHandler(chunk.ChunkId);

                if (chunkHandler.CanRead(chunk))
                {
                    chunkObject = chunkHandler.Read(Context);

                    chunk.RuntimeInstance = chunkObject;
                }

                // makes sure all of the chunk is 'read' (skipped)
                // and aligns the stream position ready for the next chunk.
                SkipChunk(chunk);

                var poppedChunk = Context.ChunkStack.PopChunk();

                if (poppedChunk != null &&
                    !Object.ReferenceEquals(poppedChunk, chunk))
                {
                    throw new InvalidOperationException("The Chunk Stack has been corrupted.");
                }
            }

            return(chunkObject);
        }