<commit_before>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace DevelopersCommunity.PerformanceCounters
{
    class PCReaderEnumerator : IEnumerator<IReadOnlyList<PCItem>>, IEnumerator
    {
        PdhQueryHandle queryHandle;
        Dictionary<string, IntPtr> counterHandles = new Dictionary<string, IntPtr>();
        DateTime currentTimeStamp;
        string fileName;
        DateTime? start;
        DateTime? end;
        List<string> expandedCounters = new List<string>();

        private PCReaderEnumerator()
        { }

        public PCReaderEnumerator(string fileName, string[] counters, DateTime? start, DateTime? end)
        {
            this.fileName = fileName;
            this.start = start;
            this.end = end;
            foreach (string wildCard in counters)
            {
                foreach (string counter in ExpandWildCard(wildCard))
                {
                    expandedCounters.Add(counter);
                }
            }

            Open();
        }

        private void Open()
        {
            CheckPdhStatus(NativeMethods.PdhOpenQuery(fileName, IntPtr.Zero, out queryHandle));

            if (start.HasValue || end.HasValue)
            {
                var timeInfo = new NativeMethods.PDH_TIME_INFO();
                timeInfo.StartTime = start.HasValue ? FileTimeFromDateTime(start.Value) : 0;
                timeInfo.EndTime = end.HasValue ? FileTimeFromDateTime(end.Value) : long.MaxValue;
                CheckPdhStatus(NativeMethods.PdhSetQueryTimeRange(queryHandle, ref timeInfo));
            }

            foreach (string counter in expandedCounters)
            {
                IntPtr counterHandle;
                CheckPdhStatus(NativeMethods.PdhAddCounter(queryHandle, counter, IntPtr.Zero, out counterHandle));
                counterHandles.Add(counter, counterHandle);
            }

            var status = NativeMethods.PdhCollectQueryData(queryHandle);//Removes the first sample. It is always PDH_INVALID_DATA
            if (status != NativeMethods.PDH_NO_MORE_DATA)
            {
                CheckPdhStatus(status);
            }
        }

        public IReadOnlyList<PCItem> Current
        {
            get
            {
                List<PCItem> items = new List<PCItem>();

                foreach (var pair in counterHandles)
                {
                    NativeMethods.PDH_FMT_COUNTERVALUE value;
                    double formattedValue;
                    uint status = 
                        NativeMethods.PdhGetFormattedCounterValue(pair.Value, NativeMethods.PDH_FMT_DOUBLE, IntPtr.Zero, out value);

                    if (status == NativeMethods.PDH_CALC_NEGATIVE_DENOMINATOR ||
                        status == NativeMethods.PDH_CALC_NEGATIVE_VALUE ||
                        status == NativeMethods.PDH_CALC_NEGATIVE_TIMEBASE ||
                        status == NativeMethods.PDH_INVALID_DATA)
                    {
                        formattedValue = double.NaN;
                    }
                    else
                    {
                        CheckPdhStatus(status);
                        formattedValue = value.doubleValue;
                    }

                    items.Add(new PCItem(currentTimeStamp, pair.Key, formattedValue)); 
                }

                return items;
            }
        }

        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }

        public bool MoveNext()
        {
            long date;
            var status = NativeMethods.PdhCollectQueryDataWithTime(queryHandle, out date);
            if (status == NativeMethods.PDH_NO_MORE_DATA)
                return false;
            CheckPdhStatus(status);
            currentTimeStamp = DateTimeFromFileTime(date);
            return true;
        }

        public void Reset()
        {
            queryHandle.Dispose();
            counterHandles.Clear();
            Open();
        }

        IReadOnlyList<string> ExpandWildCard(string wildCard)
        {
            uint len = 0;
            uint status = NativeMethods.PdhExpandWildCardPath(fileName, wildCard, null, ref len, 0);
            if (status != NativeMethods.PDH_MORE_DATA)
            {
                CheckPdhStatus(status);
            }
            char[] buffer = new char[len];
            CheckPdhStatus(NativeMethods.PdhExpandWildCardPath(fileName, wildCard, buffer, ref len, 0));
            return PCReader.MultipleStringsToList(buffer);
        }

        private long FileTimeFromDateTime(DateTime date)
        {
            var st = new NativeMethods.SYSTEMTIME
            {
                wYear = (ushort)date.Year,
                wMonth = (ushort)date.Month,
                wDay = (ushort)date.Day,
                wHour = (ushort)date.Hour,
                wMinute = (ushort)date.Minute,
                wSecond = (ushort)date.Second,
                wMilliseconds = (ushort)date.Millisecond,
                wDayOfWeek = (ushort)date.DayOfWeek
            };

            long ft;
            if (!NativeMethods.SystemTimeToFileTime(ref st, out ft)) throw new Win32Exception();

            return ft;
        }

        private DateTime DateTimeFromFileTime(long date)
        {<commit_msg>Simplify code.<commit_after>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace DevelopersCommunity.PerformanceCounters
{
    class PCReaderEnumerator : IEnumerator<IReadOnlyList<PCItem>>, IEnumerator
    {
        PdhQueryHandle queryHandle;
        Dictionary<string, IntPtr> counterHandles = new Dictionary<string, IntPtr>();
        DateTime currentTimeStamp;
        string fileName;
        DateTime? start;
        DateTime? end;
        List<string> expandedCounters = new List<string>();

        private PCReaderEnumerator()
        { }

        public PCReaderEnumerator(string fileName, string[] counters, DateTime? start, DateTime? end)
        {
            this.fileName = fileName;
            this.start = start;
            this.end = end;
            foreach (string wildCard in counters)
            {
                expandedCounters.AddRange(ExpandWildCard(wildCard));
            }

            Open();
        }

        private void Open()
        {
            CheckPdhStatus(NativeMethods.PdhOpenQuery(fileName, IntPtr.Zero, out queryHandle));

            if (start.HasValue || end.HasValue)
            {
                var timeInfo = new NativeMethods.PDH_TIME_INFO();
                timeInfo.StartTime = start.HasValue ? FileTimeFromDateTime(start.Value) : 0;
                timeInfo.EndTime = end.HasValue ? FileTimeFromDateTime(end.Value) : long.MaxValue;
                CheckPdhStatus(NativeMethods.PdhSetQueryTimeRange(queryHandle, ref timeInfo));
            }

            foreach (string counter in expandedCounters)
            {
                IntPtr counterHandle;
                CheckPdhStatus(NativeMethods.PdhAddCounter(queryHandle, counter, IntPtr.Zero, out counterHandle));
                counterHandles.Add(counter, counterHandle);
            }

            var status = NativeMethods.PdhCollectQueryData(queryHandle);//Removes the first sample. It is always PDH_INVALID_DATA
            if (status != NativeMethods.PDH_NO_MORE_DATA)
            {
                CheckPdhStatus(status);
            }
        }

        public IReadOnlyList<PCItem> Current
        {
            get
            {
                var items = new List<PCItem>();

                foreach (var pair in counterHandles)
                {
                    NativeMethods.PDH_FMT_COUNTERVALUE value;
                    double formattedValue;
                    var status = 
                        NativeMethods.PdhGetFormattedCounterValue(pair.Value, NativeMethods.PDH_FMT_DOUBLE, IntPtr.Zero, out value);

                    if (status == NativeMethods.PDH_CALC_NEGATIVE_DENOMINATOR ||
                        status == NativeMethods.PDH_CALC_NEGATIVE_VALUE ||
                        status == NativeMethods.PDH_CALC_NEGATIVE_TIMEBASE ||
                        status == NativeMethods.PDH_INVALID_DATA)
                    {
                        formattedValue = double.NaN;
                    }
                    else
                    {
                        CheckPdhStatus(status);
                        formattedValue = value.doubleValue;
                    }

                    items.Add(new PCItem(currentTimeStamp, pair.Key, formattedValue)); 
                }

                return items;
            }
        }

        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }

        public bool MoveNext()
        {
            long date;
            var status = NativeMethods.PdhCollectQueryDataWithTime(queryHandle, out date);
            if (status == NativeMethods.PDH_NO_MORE_DATA)
                return false;
            CheckPdhStatus(status);
            currentTimeStamp = DateTimeFromFileTime(date);
            return true;
        }

        public void Reset()
        {
            queryHandle.Dispose();
            counterHandles.Clear();
            Open();
        }

        private IReadOnlyList<string> ExpandWildCard(string wildCard)
        {
            uint len = 0;
            var status = NativeMethods.PdhExpandWildCardPath(fileName, wildCard, null, ref len, 0);
            if (status != NativeMethods.PDH_MORE_DATA)
            {
                CheckPdhStatus(status);
            }
            var buffer = new char[len];
            CheckPdhStatus(NativeMethods.PdhExpandWildCardPath(fileName, wildCard, buffer, ref len, 0));
            return PCReader.MultipleStringsToList(buffer);
        }

        private long FileTimeFromDateTime(DateTime date)
        {
            var st = new NativeMethods.SYSTEMTIME
            {
                wYear = (ushort)date.Year,
                wMonth = (ushort)date.Month,
                wDay = (ushort)date.Day,
                wHour = (ushort)date.Hour,
                wMinute = (ushort)date.Minute,
                wSecond = (ushort)date.Second,
                wMilliseconds = (ushort)date.Millisecond,
                wDayOfWeek = (ushort)date.DayOfWeek
            };

            long ft;
            if (!NativeMethods.SystemTimeToFileTime(ref st, out ft)) throw new Win32Exception();

            return ft;
        }

        private DateTime DateTimeFromFileTime(long date)
        {
{'fraction_non_alphanumeric': 0.07599776202909363, 'fraction_numerical': 0.0011189854531891085, 'mean_word_length': 1.575030012004802, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1355875', 'n_tokens_mistral': 2783, 'n_tokens_neox': 2648, 'n_words': 525}