//******************************************************************************************************
// LogStackFrame.cs - Gbtc
//
// Copyright © 2016, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 10/24/2016 - Steven E. Chisholm
// Generated original version of source code.
//
//
//******************************************************************************************************
using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Security;
using System.Text;
using GSF.IO;
using GSF.Reflection;
namespace GSF.Diagnostics
{
///
/// Provides information about the specific stack frame.
///
public class LogStackFrame
: IEquatable
{
///
/// The name of the method's type.
///
///
/// Example: System.Collections.Generic.List`1+Enumerable
///
public readonly string ClassName;
///
/// The name of the method
///
///
/// Example: MethodName<TKey,TValue>(String key, String value)
///
public readonly string MethodName;
///
/// The file name if debug symbols were compiled with the assembly
///
public readonly string FileName;
///
/// Gets the offset position in the IL Code.
///
public readonly int NativeOffset;
///
/// The line number of the data.
///
public readonly int LineNumber;
///
/// The column number of the execution point.
///
public readonly int ColumnNumber;
///
/// Creates a from a
///
///
public LogStackFrame(StackFrame frame)
{
if (frame == null)
{
ClassName = string.Empty;
MethodName = string.Empty;
FileName = string.Empty;
NativeOffset = 0;
LineNumber = 0;
ColumnNumber = 0;
return;
}
ClassName = frame.GetMethod().GetFriendlyClassName();
MethodName = frame.GetMethod().GetFriendlyMethodName();
using (Logger.SuppressFirstChanceExceptionLogMessages())
{
try
{
FileName = frame.GetFileName() ?? string.Empty;
}
catch (SecurityException)
{
FileName = string.Empty;
}
}
NativeOffset = frame.GetNativeOffset();
LineNumber = frame.GetFileLineNumber();
ColumnNumber = frame.GetFileColumnNumber();
}
///
/// Creates a from a .
///
/// the stream to load from
public LogStackFrame(Stream stream)
{
byte version = stream.ReadNextByte();
switch (version)
{
case 1:
ClassName = stream.ReadString();
MethodName = stream.ReadString();
FileName = stream.ReadString();
NativeOffset = stream.ReadInt32();
LineNumber = stream.ReadInt32();
ColumnNumber = stream.ReadInt32();
break;
default:
throw new VersionNotFoundException("Unknown StackTraceDetails Version");
}
}
///
/// Saves this class to a
///
/// the stream to write to.
public void Save(Stream stream)
{
stream.Write((byte)1);
stream.Write(ClassName);
stream.Write(MethodName);
stream.Write(FileName);
stream.Write(NativeOffset);
stream.Write(LineNumber);
stream.Write(ColumnNumber);
}
///
/// Makes a string
///
///
public override string ToString()
{
StringBuilder sb = new StringBuilder();
ToString(sb);
return sb.ToString();
}
///
/// Appends the details of this stack frame to the provided .
///
/// where to append this class information
///
/// Does not append a to the end of the line.
///
public void ToString(StringBuilder stringBuilder)
{
if (ClassName.Length > 0)
{
stringBuilder.Append(ClassName);
stringBuilder.Append('.');
}
stringBuilder.Append(MethodName);
if (FileName.Length == 0)
{
stringBuilder.Append(" IL offset: ");
stringBuilder.Append(NativeOffset);
}
else
{
stringBuilder.Append(" in ");
stringBuilder.Append(FileName);
stringBuilder.Append(": line ");
stringBuilder.Append(LineNumber);
stringBuilder.Append(':');
stringBuilder.Append(ColumnNumber);
}
}
///
/// Gets the hash code data from this frame
///
internal int ComputeHashCode()
{
return ClassName.GetHashCode() ^ MethodName.GetHashCode() ^ FileName.GetHashCode() ^ NativeOffset.GetHashCode() ^ LineNumber.GetHashCode() ^ ColumnNumber.GetHashCode();
}
///
/// Gets of the two classes are equal
///
/// the class to compare.
///
public bool Equals(LogStackFrame other)
{
return (object)other != null &&
NativeOffset == other.NativeOffset &&
LineNumber == other.LineNumber &&
ColumnNumber == other.ColumnNumber &&
ClassName == other.ClassName &&
MethodName == other.MethodName &&
FileName == other.FileName;
}
}
}