Ejemplo n.º 1
0
 /// <summary>
 /// Writes the <paramref name="value"/> to the <see cref="CurrentStream"/>.
 /// </summary>
 /// <param name="value">The value to be written.</param>
 public void WriteFourCharacterCode(FourCharacterCode value)
 {
     if (value != null)
     {
         value.WriteTo(this.CurrentStream);
     }
 }
Ejemplo n.º 2
0
        public static FourCharacterCode ReadFrom(Stream stream)
        {
            Contract.Requires(stream != null);
            Contract.Requires(stream.CanRead);
            Contract.Ensures(Contract.Result <FourCharacterCode>() != null);
            Check.IfArgumentNull(stream, "stream");

            if (!stream.CanRead)
            {
                throw new ArgumentException("The stream does not support reading.", "stream");
            }

            var fourCC = new FourCharacterCode();

            fourCC.fourCC = new byte[4];

            int bytesRead = stream.Read(fourCC.fourCC, 0, 4);

            if (bytesRead < 4)
            {
                throw new EndOfStreamException();
            }

            return(fourCC);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates and fill the data members of the runtime object for the specified <paramref name="chunkId"/>.
        /// </summary>
        /// <param name="stream">Must not be null.</param>
        /// <param name="chunkId">Must not be null.</param>
        /// <returns>Returns null when no runtime chunk type could be found for the <paramref name="chunkId"/>.</returns>
        /// <remarks>Note that chunks (types) are never mixed content. They are either containing other chunks
        /// or the contain data. This method is for reading sub chunks.
        /// Use the <see cref="M:ReadRuntimteChunkType"/> to read data.</remarks>
        public object ReadRuntimeContainerChunkType(Stream stream, FourCharacterCode chunkId)
        {
            Check.IfArgumentNull(stream, nameof(stream));
            Check.IfArgumentNull(chunkId, nameof(chunkId));

            var runtimeObject = _chunkTypeFactory.CreateChunkObject(chunkId);

            if (runtimeObject != null)
            {
                var writer = new ObjectMemberWriter(runtimeObject);

                // read all of the stream
                while (stream.Position < stream.Length)
                {
                    object runtimeChildObj = ReadNextChunk(stream);

                    // if null means there was no runtime type found.
                    if (runtimeChildObj != null)
                    {
                        // if returns false means can't find member
                        if (!writer.WriteChunkObject(runtimeChildObj))
                        {
                            // TODO: Log?
                            // just keep reading the stream...
                        }
                    }
                }
            }

            return(runtimeObject);
        }
Ejemplo n.º 4
0
        public IFileChunkHandler GetChunkHandler(FourCharacterCode chunkId)
        {
            Contract.Requires(chunkId != null);
            Contract.Ensures(Contract.Result <IFileChunkHandler>() != null);
            Check.IfArgumentNull(chunkId, "chunkId");

            return(GetChunkHandler(chunkId.ToString()));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Reads a four character code.
        /// </summary>
        /// <returns>Returns the code read. Never returns null.</returns>
        public FourCharacterCode ReadFourCharacterCode()
        {
            Contract.Ensures(Contract.Result <FourCharacterCode>() != null);

            var stream = this.CurrentStream;

            return(FourCharacterCode.ReadFrom(stream));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Pushes a new initialized header onto the stack.
        /// </summary>
        /// <param name="chunkId">Must not be null.</param>
        /// <returns>Returns the header object. Never returns null.</returns>
        private FileChunkHeader PushNewHeader(FourCharacterCode chunkId)
        {
            var header = new FileChunkHeader();

            header.DataStream = new MemoryStream();
            header.ChunkId    = chunkId;

            this.context.HeaderStack.Push(header);

            return(header);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Retrieves the <see cref="FileChunkHandlerAttribute"/> and initializes the <see cref="P:ChunkId"/> property.
        /// </summary>
        protected FileChunkHandler()
        {
            var attrs = GetType().GetCustomAttributes(typeof(FileChunkHandlerAttribute), true);

            if (attrs == null || attrs.Length == 0)
            {
                throw new InvalidOperationException(
                          "A File Chunk Handler derived class must be marked with the FileChunkHandlerExportAttribute.");
            }

            ChunkId = new FourCharacterCode(((FileChunkHandlerAttribute)attrs[0]).ChunkId);
        }
Ejemplo n.º 8
0
        public FileChunkHeader WriteNextChunk(object chunk)
        {
            Contract.Requires(chunk != null);
            Check.IfArgumentNull(chunk, "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 = this.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 = this.context.HeaderStack.Count;
            var header   = this.PushNewHeader(chunkTypeId);

            chunkHandler.Write(this.context, chunk);

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

            return(header);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Creates and fill the data members of the runtime object for the specified <paramref name="chunkId"/>.
        /// </summary>
        /// <param name="stream">Must not be null.</param>
        /// <param name="chunkId">Must not be null.</param>
        /// <returns>Returns null when no runtime chunk type could be found for the <paramref name="chunkId"/>.</returns>
        /// <remarks>Note that chunks (types) are never mixed content. They are either containing other chunks
        /// or the contain data. This method is for reading data.
        /// Use the <see cref="M:ReadRuntimteContainerChunkType"/> to read sub chunks.</remarks>
        public object ReadRuntimeChunkType(Stream stream, FourCharacterCode chunkId)
        {
            Check.IfArgumentNull(stream, nameof(stream));
            Check.IfArgumentNull(chunkId, nameof(chunkId));

            var runtimeObject = _chunkTypeFactory.CreateChunkObject(chunkId);

            if (runtimeObject != null)
            {
                var writer = new ObjectMemberWriter(runtimeObject);

                writer.ReadFields(this);
            }

            return(runtimeObject);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Creates and fill the data members of the runtime object for the specified <paramref name="chunkId"/>.
        /// </summary>
        /// <param name="stream">Must not be null.</param>
        /// <param name="chunkId">Must not be null.</param>
        /// <returns>Returns null when no runtime chunk type could be found for the <paramref name="chunkId"/>.</returns>
        /// <remarks>Note that chunks (types) are never mixed content. They are either containing other chunks
        /// or the contain data. This method is for reading data.
        /// Use the <see cref="M:ReadRuntimteContainerChunkType"/> to read sub chunks.</remarks>
        public object ReadRuntimeChunkType(Stream stream, FourCharacterCode chunkId)
        {
            Contract.Requires(stream != null);
            Contract.Requires(chunkId != null);
            Check.IfArgumentNull(stream, "stream");
            Check.IfArgumentNull(chunkId, "chunkId");

            var runtimeObject = this.chunkTypeFactory.CreateChunkObject(chunkId);

            if (runtimeObject != null)
            {
                var writer = new ObjectMemberWriter(runtimeObject);

                writer.ReadFields(this);
            }

            return(runtimeObject);
        }
Ejemplo n.º 11
0
        public FileChunk ReadChunkHeader(Stream stream)
        {
            Contract.Requires(stream != null);
            Check.IfArgumentNull(stream, "stream");

            if (this.ValidateStreamPosition(8))
            {
                var chunk = new FileChunk();
                chunk.ChunkId        = FourCharacterCode.ReadFrom(stream);
                chunk.DataLength     = this.numberReader.ReadUInt32AsInt64(stream);
                chunk.ParentPosition = stream.Position;
                chunk.FilePosition   = this.context.ChunkFile.BaseStream.Position;
                chunk.DataStream     = new SubStream(stream, chunk.DataLength);

                return(chunk);
            }

            return(null);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Reads the first (header) fields of a chunk from the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">Must not be null.</param>
        /// <returns>Returns null when the stream position does not allow to read the header.</returns>
        /// <remarks>The following properties are set on the returned <see cref="FileChunk"/>.
        /// <see cref="P:FileChunk.ChunkId"/>, <see cref="P:FileChunk.DataLength"/>,
        /// <see cref="P:FileChunk.ParentPosition"/>, <see cref="P:FileChunk.FilePosition"/>
        /// and <see cref="P:FileChunk.DataStream"/>.</remarks>
        public FileChunk ReadChunkHeader(Stream stream)
        {
            Check.IfArgumentNull(stream, nameof(stream));

            if (ValidateStreamPosition(8))
            {
                var chunk = new FileChunk
                {
                    ChunkId        = FourCharacterCode.ReadFrom(stream),
                    DataLength     = _numberReader.ReadUInt32AsInt64(stream),
                    ParentPosition = stream.Position,
                    FilePosition   = Context.ChunkFile.BaseStream.Position
                };
                chunk.DataStream = new SubStream(stream, chunk.DataLength);

                return(chunk);
            }

            return(null);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Reads a four character code from the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">Must not be null.</param>
        /// <returns>Never return null.</returns>
        public static FourCharacterCode ReadFrom(Stream stream)
        {
            Check.IfArgumentNull(stream, nameof(stream));

            if (!stream.CanRead)
            {
                throw new ArgumentException("The stream does not support reading.", nameof(stream));
            }

            var fourCC = new FourCharacterCode
            {
                _fourCC = new byte[4]
            };

            int bytesRead = stream.Read(fourCC._fourCC, 0, 4);

            if (bytesRead < 4)
            {
                throw new EndOfStreamException();
            }

            return(fourCC);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Reads a four character code.
        /// </summary>
        /// <returns>Returns the code read. Never returns null.</returns>
        public FourCharacterCode ReadFourCharacterCode()
        {
            var stream = CurrentStream;

            return(FourCharacterCode.ReadFrom(stream));
        }
 /// <summary>
 /// Retrieves a handler for the specified <paramref name="chunkId"/>.
 /// </summary>
 /// <param name="chunkId">Must not be null.</param>
 /// <returns>Never returns null.</returns>
 /// <remarks>If no specific chunk handler could be found, the default handler is returned.</remarks>
 public IFileChunkHandler GetChunkHandler(FourCharacterCode chunkId)
 {
     Check.IfArgumentNull(chunkId, nameof(chunkId));
     return(GetChunkHandler(chunkId.ToString()));
 }