예제 #1
0
        /// <summary>
        /// Creates a DumpWriter which writes rtpdump comptaible files.
        /// If <param name="modify" /> is true the StartTime and Source properties will be attempted to be copied from the source stream, if they are not present they will be used from the parameters given.
        ///
        /// Throws a <see cref="ArgumentNullException"/> if <paramref name="stream"/> or <paramref name="source"/> is null.
        /// Throws a <see cref="Common.Exception"/> with the Type `DumpWriter` if an unexpected error occurs, if the underlying exception is realted to reading any information being read from a stream being modified then it will be of type `DumpReader`.
        /// </summary>
        /// <param name="stream">The stream to write to</param>
        /// <param name="format">The format to write in</param>
        /// <param name="source">The source where packets came from in this dump</param>
        /// <param name="utcStart">The optional start of the file recording (used in the header)</param>
        /// <param name="modify">Optionally indicates if the file should be modified or created, by default it will not overwrite files if they exist.</param>
        /// <param name="leaveOpen">Indicates if the stream should be left open after calling Close or Dipose</param>
        public DumpWriter(System.IO.Stream stream, FileFormat format, System.Net.IPEndPoint defaultSource, DateTime?startTime = null, bool modify = false, bool leaveOpen = false, bool shouldDispose = true)
            : base(shouldDispose)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (defaultSource == null)
            {
                throw new ArgumentNullException("source");
            }

            m_Format = format;

            m_Source = defaultSource;

            m_Start = startTime ?? DateTime.UtcNow;

            if (false == modify) // New file
            {
                //Create the writer
                m_Writer = new System.IO.BinaryWriter(stream, Encoding.ASCII, leaveOpen);
            }
            else//Modifying
            {
                //The stream should be the same format.
                FileFormat streamFormat = m_Format;

                try
                {
                    //Header already written when modifying a file
                    //Need to read the header and advance the stream to the end, indicate the header was already written so it is not again.
                    using (DumpReader reader = new DumpReader(stream, m_WroteHeader = true))
                    {
                        //Create the writer forcing ASCII Encoding, leave the stream open if indicated
                        m_Writer = new System.IO.BinaryWriter(stream, Encoding.ASCII, leaveOpen);

                        //Read to the end so packets can be added
                        reader.ReadToEnd();

                        //Ensure the format of the writer matches the reader, if not throw an exception so it can be handled appropriately.
                        //The exception will be of type `DumpReader`
                        if (reader.m_Format != m_Format)
                        {
                            Media.Common.TaggedExceptionExtensions.RaiseTaggedException(reader, "Format of writer does not match reader, Expected: " + m_Format + " Found: " + reader.m_Format);
                        }

                        //Copy the file header from the reader if present, otherwise the file will have no header when written.
                        m_FileHeader = reader.m_FileHeader;

                        m_FileIdentifier = reader.m_FileIdentifier;

                        //Check for the header to be present on existing files if the format has a header. (only Binary)
                        //The exception will be of type `DumpReader`
                        if (m_FileHeader == null && m_Format.HasFileHeader())
                        {
                            Media.Common.TaggedExceptionExtensions.RaiseTaggedException(reader, "Did not find the expected Binary file header.");
                        }

                        //If not present use the start time indicated in the first entry...
                        if (m_Start == null)
                        {
                            m_Start = startTime ?? reader.m_StartTime;
                        }
                    }
                }
                catch (Exception ex)//Only catch exceptions which are unexpected and raise a generic DumpWriter exception
                {
                    Media.Common.TaggedExceptionExtensions.RaiseTaggedException(this, "An unexpected exception occured while reading the existing information present in the stream. See InnerException for more details.", ex);
                }
            }
        }