コード例 #1
0
            // Reads the rest of a record after GetFlags() has read the flags.
            // TODO: This really shouldn't modify any class members until it completes successfully.
            private Record ReadRecordData(DataFlags flags, ulong thisRecordNum, bool reReading)
            {
                long startPos = _fileReader.BaseStream.Position;

                if ((flags & DataFlags.Time) != DataFlags.None)
                {
                    LastRecordTimeUtc = new DateTime(_fileReader.ReadInt64());
                }

                if ((flags & DataFlags.ThreadId) != DataFlags.None)
                {
                    ReadThreadID();
                }

                if ((flags & DataFlags.ThreadName) != DataFlags.None)
                {
                    // A normal thread's name can only change from null to non-null.
                    // ThreadPool threads can alternate between null and non-null.
                    // If a thread's name changes from non-null to null, the logger
                    // writes string.Empty for the thread name.

                    string threadNameStr;

                    if (Reader.Key == null)
                    {
                        threadNameStr = _fileReader.ReadString();
                    }
                    else
                    {
                        threadNameStr = Decrypt();
                    }

                    if (threadNameStr == string.Empty)
                    {
                        _curThread.ThreadName = _reader.FindOrCreateThreadName("Thread " + _curThread.Thread.Id);
                    }
                    else
                    {
                        _curThread.ThreadName = _reader.FindOrCreateThreadName(threadNameStr);
                    }
                }
                else if (_curThread.ThreadName == null)
                {
                    _curThread.ThreadName = _reader.FindOrCreateThreadName("Thread " + _curThread.Thread.Id);
                }

                if ((flags & DataFlags.TraceLevel) != DataFlags.None)
                {
                    _curThread.Level     = (TracerX.TraceLevel)_fileReader.ReadByte();
                    _reader.LevelsFound |= _curThread.Level;
                }

                if ((flags & DataFlags.StackDepth) != DataFlags.None)
                {
                    _curThread.Depth = _fileReader.ReadByte();

                    if (InCircularPart)
                    {
                        ReadStack();
                    }
                }

                // Starting in format version 5, the viewer decrements the depth on MethodExit
                // lines even if it was included on the line.
                if ((flags & DataFlags.MethodExit) != DataFlags.None && !reReading)
                {
                    --_curThread.Depth;
                }

                if ((flags & DataFlags.LoggerName) != DataFlags.None)
                {
                    string loggerName;

                    if (Reader.Key == null)
                    {
                        loggerName = _fileReader.ReadString();
                    }
                    else
                    {
                        loggerName = Decrypt();
                    }

                    _curThread.Logger = _reader.GetLogger(loggerName);
                }

                if ((flags & DataFlags.MethodName) != DataFlags.None)
                {
                    string methodName;

                    if (Reader.Key == null)
                    {
                        methodName = _fileReader.ReadString();
                    }
                    else
                    {
                        methodName = Decrypt();
                    }

                    _curThread.MethodName = _reader.GetMethod(methodName);
                }

                if ((flags & DataFlags.Message) != DataFlags.None)
                {
                    if (Reader.Key == null)
                    {
                        _msg = _fileReader.ReadString();
                    }
                    else
                    {
                        _msg = Decrypt();
                    }
                }

                // Construct the Record before incrementing depth.
                Record record = new Record(flags, thisRecordNum, LastRecordTimeUtc, _curThread, this, _msg);

                if (!reReading)
                {
                    if ((flags & DataFlags.MethodEntry) != DataFlags.None)
                    {
                        // Cause future records to be indented until a MethodExit is encountered.
                        ++_curThread.Depth;

                        // In format version 5+, we keep track of the call stack
                        // by "pushing" MethodEntry records and "popping" MethodExit records
                        if (_reader.FormatVersion >= 5)
                        {
                            _curThread.Push(record);
                        }
                    }
                    else if (_reader.FormatVersion >= 5 && (flags & DataFlags.MethodExit) != DataFlags.None)
                    {
                        _curThread.Pop();
                    }

                    _reader.BytesRead += _fileReader.BaseStream.Position - startPos;
                }

                if (InCircularPart && _fileReader.BaseStream.Position >= _maxFilePos)
                {
                    // We've read to the point where the log wraps.
                    Wrap();
                }

                return(record);
            }
コード例 #2
0
ファイル: Reader.cs プロジェクト: NathDevAU/TracerX
        public Record ReadRecord()
        {
            // Read the DataFlags, then the data the Flags indicate is there.
            // Data must be read in the same order it was written (see FileLogging.WriteData).
            try {
                DataFlags flags = GetFlags();

                if (flags == DataFlags.None)
                {
                    return(null);
                }

                long startPos = _fileReader.BaseStream.Position;

                if ((flags & DataFlags.LineNumber) != DataFlags.None)
                {
                    _recordNumber = _fileReader.ReadUInt32();
                }
                else if (!InCircularPart)
                {
                    ++_recordNumber;
                }
                else
                {
                    // _recordNumber was incremented by GetFlags.
                }

                if ((flags & DataFlags.Time) != DataFlags.None)
                {
                    _time = new DateTime(_fileReader.ReadInt64());
                }

                if ((flags & DataFlags.ThreadId) != DataFlags.None)
                {
                    _threadId = _fileReader.ReadInt32();

                    // Look up or add the entry for this ThreadId.
                    if (!_foundThreadIds.TryGetValue(_threadId, out _curThread))
                    {
                        // First occurrence of this id.
                        _curThread = new ReaderThreadInfo();

                        if (!_oldThreadIds.TryGetValue(_threadId, out _curThread.Thread))
                        {
                            _curThread.Thread = new ThreadObject();
                        }

                        _curThread.Thread.Id = _threadId;
                        ThreadObject.AllThreads.Add(_curThread.Thread);
                        _foundThreadIds[_threadId] = _curThread;
                    }
                }

                if ((flags & DataFlags.ThreadName) != DataFlags.None)
                {
                    // A normal thread's name can only change from null to non-null.
                    // ThreadPool threads can alternate between null and non-null.
                    // If a thread's name changes from non-null to null, the logger
                    // writes string.Empty for the thread name.
                    string threadNameStr = _fileReader.ReadString();
                    if (threadNameStr == string.Empty)
                    {
                        _curThread.ThreadName = FindOrCreateThreadName("Thread " + _curThread.Thread.Id);
                    }
                    else
                    {
                        _curThread.ThreadName = FindOrCreateThreadName(threadNameStr);
                    }
                }
                else if (_curThread.ThreadName == null)
                {
                    _curThread.ThreadName = FindOrCreateThreadName("Thread " + _curThread.Thread.Id);
                }

                if ((flags & DataFlags.TraceLevel) != DataFlags.None)
                {
                    _curThread.Level = (TracerX.TraceLevel)_fileReader.ReadByte();
                    LevelsFound     |= _curThread.Level;
                }

                if (FormatVersion < 5)
                {
                    if ((flags & DataFlags.StackDepth) != DataFlags.None)
                    {
                        _curThread.Depth = _fileReader.ReadByte();
                    }
                    else if ((flags & DataFlags.MethodExit) != DataFlags.None)
                    {
                        --_curThread.Depth;
                    }
                }
                else
                {
                    if ((flags & DataFlags.StackDepth) != DataFlags.None)
                    {
                        _curThread.Depth = _fileReader.ReadByte();

                        if (InCircularPart)
                        {
                            if (_curThread.Depth > 0)
                            {
                                // In format version 5, we began logging each thread's current call
                                // stack on the thread's first line in each block (i.e. when the
                                // StackDepth flag is set). This is the thread's true call stack at
                                // this point in the log. It reflects MethodEntry and MethodExit
                                // records that may have been lost when the log wrapped (as well
                                // as those that weren't lost).

                                ReaderStackEntry[] trueStack = new ReaderStackEntry[_curThread.Depth];
                                for (int i = _curThread.Depth - 1; i >= 0; --i)
                                {
                                    ReaderStackEntry entry = new ReaderStackEntry();
                                    entry.EntryLineNum = _fileReader.ReadUInt32();
                                    entry.Level        = (TracerX.TraceLevel)_fileReader.ReadByte();
                                    entry.Logger       = GetLogger(_fileReader.ReadString());
                                    entry.Method       = _fileReader.ReadString();
                                    entry.Depth        = (byte)i;
                                    trueStack[i]       = entry;
                                }

                                _curThread.MakeMissingRecords(trueStack);
                            }
                            else
                            {
                                _curThread.MakeMissingRecords(null);
                            }
                        }
                    }

                    // Starting in format version 5, the viewer decrements the depth on MethodExit
                    // lines even if it was included on the line.
                    if ((flags & DataFlags.MethodExit) != DataFlags.None)
                    {
                        --_curThread.Depth;
                    }
                }

                if ((flags & DataFlags.LoggerName) != DataFlags.None)
                {
                    string loggerName = _fileReader.ReadString();
                    _curThread.Logger = GetLogger(loggerName);
                }

                if ((flags & DataFlags.MethodName) != DataFlags.None)
                {
                    _curThread.MethodName = _fileReader.ReadString();
                }

                if ((flags & DataFlags.Message) != DataFlags.None)
                {
                    _msg = _fileReader.ReadString();
                }

                // Construct the Record before incrementing depth.
                Record record = new Record(flags, _recordNumber, _time, _curThread, _msg);

                if ((flags & DataFlags.MethodEntry) != DataFlags.None)
                {
                    // Cause future records to be indented until a MethodExit is encountered.
                    ++_curThread.Depth;

                    // In format version 5+, we keep track of the call stack in the noncircular
                    // part of the log by "pushing" MethodEntry records and "popping" MethodExit records
                    if (FormatVersion >= 5 && !InCircularPart)
                    {
                        _curThread.Push(record);
                    }
                }
                else if (FormatVersion >= 5 && !InCircularPart && (flags & DataFlags.MethodExit) != DataFlags.None)
                {
                    _curThread.Pop();
                }

                BytesRead += _fileReader.BaseStream.Position - startPos;

                if (InCircularPart && _fileReader.BaseStream.Position >= MaxMb << 20)
                {
                    // We've read to the max file size in circular mode.  Wrap.
                    _fileReader.BaseStream.Position = _circularStartPos;
                }

                ++_recordsRead;
                return(record);
            } catch (Exception ex) {
                // The exception is either end-of-file or a corrupt file.
                // Either way, we're done.  Returning null tells the caller to give up.
                return(null);
            }
        }