public static IEnumerable <SampleWithTrace> ParseFromFile(string filename) { if (!File.Exists(filename)) { throw new ArgumentException($"Cannot find filename: ${filename}."); } SampleWithTrace current = null; List <PerformanceSample> currentStack = new List <PerformanceSample>(); uint index = 0; using (var reader = new StreamReader(filename)) { using (CsvReader csvReader = new CsvReader(reader)) { while (csvReader.Read()) { var row = csvReader.GetRecord <dynamic>(); var dict = row as IDictionary <string, object>; if (dict["Function"] == null || dict["Function"].ToString() == string.Empty) { if (dict["Function Stack"] == null || dict["Function Stack"].ToString() == string.Empty) { current.AddStack(currentStack); currentStack = new List <PerformanceSample>(); } else { PerformanceSample s = new PerformanceSample(dict["Function Stack"].ToString(), dict["CPU Time"].ToString(), dict["Module"].ToString(), dict["Function (Full)"].ToString(), dict["Source File"].ToString(), dict["Start Address"].ToString()); currentStack.Add(s); } } else { if (current != null) { yield return(current); } PerformanceSample s = new PerformanceSample(dict["Function"].ToString(), dict["CPU Time"].ToString(), dict["Module"].ToString(), dict["Function (Full)"].ToString(), dict["Source File"].ToString(), dict["Start Address"].ToString() ); current = new SampleWithTrace(s); } index += 1; } } } if (current != null) { yield return(current); } }
public static IEnumerable <SampleWithTrace> ParseFromStream(this IEnumerable <string> seq) { Regex startsWithComma = new Regex("^(,+)(.*)$"); SampleWithTrace current = null; List <PerformanceSample> currentStack = null; bool atEnd = false; foreach (var l in seq) { Match m = startsWithComma.Match(l); if (!m.Success) { if (atEnd == true) { if (currentStack != null) { current.AddStack(currentStack); currentStack = null; } yield return(current); } atEnd = false; // should assert record is comma-separated, seven-field, second one empty var fields = l.Split(','); try { /* Function, CPUTime, Module, FunctionFull, SourceFile, StartAddress */ current = new SampleWithTrace(new PerformanceSample(fields[0], fields[2], fields[3], fields[4], fields[5], fields[6])); } catch (Exception ex) { // Discard record Console.WriteLine($"Caught exception {ex.Message}"); } } else { // assert m.Groups.Count is 3 if (m.Groups[1].Length == 1) { if (atEnd == true || currentStack == null) { if (currentStack != null) { current.AddStack(currentStack); } currentStack = new List <PerformanceSample>(); } atEnd = false; var fields = m.Groups[2].Value.Split(','); try { /* Function, CPUTime, Module, FunctionFull, SourceFile, StartAddress */ currentStack.Add(new PerformanceSample(fields[0], fields[1], fields[2], fields[3], fields[5], fields[5])); } catch (Exception ex) { // Discard record... happens on de-mangled C++ multi-templatized functions on Linux Console.WriteLine($"Caught exception {ex.Message}"); } } else { // verify that the only other allowed value for Groups[1].Length is 6? atEnd = true; } } } if (current != null) { if (currentStack != null) { current.AddStack(currentStack); } yield return(current); } }