예제 #1
0
 /// <summary>
 /// Write the packet to the stream
 /// </summary>
 protected override void OnWrite(Stream stream)
 {
     //this will automatically figure out its length...
     BinarySerializer.SerializeValue(stream, m_Timestamp);
     BinarySerializer.SerializeValue(stream, m_ClockDrift);
     byte[] rawData = m_SessionHeader.RawData();
     stream.Write(rawData, 0, rawData.Length);
 }
예제 #2
0
        /// <summary>
        /// Initialize the GLF writer for storing information about the current live session
        /// </summary>
        /// <param name="file">The file stream to write the session file into (should be empty)</param>
        /// <param name="sessionSummary"></param>
        /// <param name="fileSequence"></param>
        /// <param name="fileStartTime">Used during initial collection to indicate the real time this file became the active file.</param>
        /// <param name="majorVersion">Major version of the serialization protocol</param>
        /// <param name="minorVersion">Minor version of the serialization protocol</param>
        /// <remarks>The file header is configured with a copy of the session summary, assuming that we're about to make a copy of the
        /// session. For live data collection the caller should supply the file start time to reflect the true time period
        /// covered by this file. </remarks>
        public GLFWriter(Stream file, SessionSummary sessionSummary, int fileSequence, DateTimeOffset?fileStartTime, int majorVersion, int minorVersion)
        {
            //for use to use the stream, it has to support
            if (file.CanSeek == false)
            {
                throw new ArgumentException("Provided stream can't be used because it doesn't support seeking", nameof(file));
            }

            m_SessionSummary = sessionSummary;
            m_OutputStream   = file;

            // This logic will store GZip compressed files for protocol version 2 and beyond
            if (majorVersion > 1)
            {
                //we are explicitly *NOT* using the system GZipStream because it doesn't support flush.
                m_PacketStream = new GZipStream(m_OutputStream, CompressionMode.Compress, CompressionLevel.Default, true)
                {
                    FlushMode = FlushType.Sync
                };
            }
            else
            {
                m_PacketStream = new MemoryStream(BufferSize + MaxExpectedPacketSize);
            }

            m_PacketWriter = new PacketWriter(m_PacketStream, majorVersion, minorVersion);

            //initialize the stream with the file header and session header
            m_FileHeader    = new FileHeader(majorVersion, minorVersion);
            m_SessionHeader = new SessionHeader(sessionSummary);

            //There are two variants of the GLF format:  One for a whole session, one for a session fragment.
            if (fileStartTime.HasValue)
            {
                m_SessionHeader.FileId            = Guid.NewGuid();
                m_SessionHeader.FileSequence      = fileSequence;
                m_SessionHeader.FileStartDateTime = fileStartTime.Value;
                m_SessionHeader.FileEndDateTime   = m_SessionHeader.EndDateTime;

                //by default, this is the last file - it won't be if we open another.
                m_SessionHeader.IsLastFile = true;
            }

            //we need to know how big the session header will be (it's variable sized) before we can figure out the data offset.
            byte[] sessionHeader = m_SessionHeader.RawData();

            //where are we going to start our data block?
            m_FileHeader.DataOffset = FileHeader.HeaderSize + sessionHeader.Length;

            byte[] header = m_FileHeader.RawData();
            m_OutputStream.Position = 0; //move to the start of the stream, we rely on this.
            m_OutputStream.Write(header, 0, FileHeader.HeaderSize);
            m_OutputStream.Write(sessionHeader, 0, sessionHeader.Length);
            m_OutputStream.Flush();

            m_OutputStream.Position = m_FileHeader.DataOffset; //so we are sure we start writing our data at the correct spot.

            // When we added GZip compression to streams we noticed that we were sometimes
            // losing a lot of data that went unflushed while programmers were testing in
            // Visual Studio.  To address this, we have the GZip stream flush to disk much
            // more aggressively when we detect that the debugger is attached.
#if !DEBUG // We only want this behavior for release builds, not for our own debug builds
// we might prefer the writing to be the more typical optimized behavior.
            AutoFlush = Debugger.IsAttached;
#endif
        }