public SchedulerEvent(
     string comm, int tid, int pid,
     double time, int timeProp, int cpu,
     string eventName, string eventProp, IEnumerable <Frame> callerStacks, ScheduleSwitch schedSwitch) :
     base(EventKind.Scheduler, comm, tid, pid, time, timeProp, cpu, eventName, eventProp, callerStacks)
 {
     Switch = schedSwitch;
 }
        private IEnumerable <LinuxEvent> NextEvent(Regex regex, FastStream source)
        {
            string line = string.Empty;

            while (true)
            {
                source.SkipWhiteSpace();

                if (source.EndOfStream)
                {
                    break;
                }

                EventKind eventKind = EventKind.Cpu;

                StringBuilder sb = new StringBuilder();

                // Fetch Command (processName) - Stops when it sees the pattern \s+\d+/\d
                int idx = FindEndOfProcessCommand(source);
                if (idx < 0)
                {
                    break;
                }

                source.ReadFixedString(idx, sb);
                source.SkipWhiteSpace();
                string processCommand = sb.ToString();
                sb.Clear();

                // Process ID
                int pid = source.ReadInt();
                source.MoveNext(); // Move past the "/"

                // Thread ID
                int tid = source.ReadInt();

                // CPU
                source.SkipWhiteSpace();
                int cpu = -1;
                if (source.Peek(0) == '[')
                {
                    source.MoveNext(); // Move past the "["
                    cpu = source.ReadInt();
                    source.MoveNext(); // Move past the "]"
                }

                // Time
                source.SkipWhiteSpace();
                source.ReadAsciiStringUpTo(':', sb);

                double time = double.Parse(sb.ToString(), CultureInfo.InvariantCulture) * 1000; // To convert to MSec
                sb.Clear();
                source.MoveNext();                                                              // Move past ":"

                // Time Property
                source.SkipWhiteSpace();
                int timeProp = -1;
                if (IsNumberChar((char)source.Current))
                {
                    timeProp = source.ReadInt();
                }

                // Event Name
                source.SkipWhiteSpace();
                source.ReadAsciiStringUpTo(':', sb);
                string eventName = sb.ToString();
                sb.Clear();
                source.MoveNext();

                // Event Properties
                // I mark a position here because I need to check what type of event this is without screwing up the stream
                var markedPosition = source.MarkPosition();
                source.ReadAsciiStringUpTo('\n', sb);
                string eventDetails = sb.ToString().Trim();
                sb.Clear();

                if (eventDetails.Length >= SchedulerEvent.Name.Length && eventDetails.Substring(0, SchedulerEvent.Name.Length) == SchedulerEvent.Name)
                {
                    eventKind = EventKind.Scheduler;
                }

                // Now that we know the header of the trace, we can decide whether or not to skip it given our pattern
                if (regex != null && !regex.IsMatch(eventName))
                {
                    while (true)
                    {
                        source.MoveNext();
                        if (IsEndOfSample(source, source.Current, source.Peek(1)))
                        {
                            break;
                        }
                    }

                    yield return(null);
                }
                else
                {
                    LinuxEvent linuxEvent;

                    Frame threadTimeFrame = null;

                    // For the sake of immutability, I have to do a similar if-statement twice. I'm trying to figure out a better way
                    //   but for now this will do.
                    ScheduleSwitch schedSwitch = null;
                    if (eventKind == EventKind.Scheduler)
                    {
                        source.RestoreToMark(markedPosition);
                        schedSwitch = ReadScheduleSwitch(source);
                        source.SkipUpTo('\n');
                    }

                    IEnumerable <Frame> frames = ReadFramesForSample(processCommand, pid, tid, threadTimeFrame, source);

                    if (eventKind == EventKind.Scheduler)
                    {
                        linuxEvent = new SchedulerEvent(processCommand, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames, schedSwitch);
                    }
                    else
                    {
                        linuxEvent = new CpuEvent(processCommand, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames);
                    }

                    yield return(linuxEvent);
                }
            }
        }