<commit_before>﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Xml;
using SilentHunter.Formats;

namespace SilentHunter.Dat.Controllers
{
	public class ControllerAssemblyHelpText
	{
		private IDictionary<string, string> _dict = new Dictionary<string, string>(); 

		/// <summary>
		/// Loads help text into a dictionary.
		/// </summary>
		/// <param name="docFile">The doc file to load from.</param>
		public void Load(string docFile)
		{
			using (var xmlReader = XmlReader.Create(docFile))
				Load(xmlReader);
		}

		/// <summary>
		/// Loads help text into a dictionary.
		/// </summary>
		/// <param name="stream">The stream to load the doc file from.</param>
		public void Load(Stream stream)
		{
			using (var xmlReader = XmlReader.Create(stream))
				Load(xmlReader);
		}

		/// <summary>
		/// Loads help text into a dictionary.
		/// </summary>
		/// <param name="xmlReader">The reader to load the doc file from.</param>
		public void Load(XmlReader xmlReader)
		{
			_dict.Clear();
			
			do
			{
				if (!xmlReader.ReadToFollowing("member")) break;
				var name = xmlReader.GetAttribute("name");
				if (string.IsNullOrEmpty(name) || name.StartsWith("M:")) continue;
				if (!xmlReader.ReadToDescendant("summary")) break;
				_dict.Add(name, xmlReader.ReadInnerXml().Trim());
			} while (!xmlReader.EOF);
		}

		public string this[string key]
		{
			get { return _dict.ContainsKey(key) ? _dict[key] : null; }
		}

		public string this[Type type]
		{
			get
			{
				return type.GetAttribute<DescriptionAttribute>()?.Description ?? this["T:" + type.FullName];
			}
		}

		public string this[MemberInfo member]
		{
			get
			{
				return member.GetAttribute<DescriptionAttribute>()?.Description 
					?? this[string.Format("{0}:{1}.{2}", member.MemberType.ToString()[0], member.DeclaringType.FullName, member.Name)];
			} 
		}
	}
}<commit_msg>Use lazy to read help text<commit_after>﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Xml;
using SilentHunter.Formats;

namespace SilentHunter.Dat.Controllers
{
	public class ControllerAssemblyHelpText
	{
		private Lazy<IDictionary<string, string>> _loadHelpText;

		public ControllerAssemblyHelpText(string docFile)
			: this(XmlReader.Create(docFile), true)
		{
		}

		public ControllerAssemblyHelpText(Stream stream, bool disposeReader = false)
			: this(XmlReader.Create(stream), disposeReader)
		{
		}

		public ControllerAssemblyHelpText(XmlReader xmlReader, bool disposeReader = false)
		{
			_loadHelpText = new Lazy<IDictionary<string, string>>(() => LoadHelpText(xmlReader, disposeReader), LazyThreadSafetyMode.ExecutionAndPublication);
		}

		private static IDictionary<string, string> LoadHelpText(XmlReader xmlReader, bool disposeReader)
		{
			var dict = new Dictionary<string, string>();
			do
			{
				if (!xmlReader.ReadToFollowing("member"))
				{
					break;
				}

				string name = xmlReader.GetAttribute("name");
				if (string.IsNullOrEmpty(name) || name.StartsWith("M:"))
				{
					continue;
				}

				if (!xmlReader.ReadToDescendant("summary"))
				{
					break;
				}

				dict.Add(name, xmlReader.ReadInnerXml().Trim());
			} while (!xmlReader.EOF);

			if (disposeReader)
			{
				xmlReader.Dispose();
			}

			return dict;
		}

		public string this[string key] => _loadHelpText.Value.ContainsKey(key) ? _loadHelpText.Value[key] : null;

		public string this[Type type] => type.GetAttribute<DescriptionAttribute>()?.Description ?? this["T:" + type.FullName];

		public string this[MemberInfo member] =>
			member.GetAttribute<DescriptionAttribute>()?.Description
			?? this[$"{member.MemberType.ToString()[0]}:{member.DeclaringType.FullName}.{member.Name}"];
	}
}
{'fraction_non_alphanumeric': 0.13635180848295603, 'fraction_numerical': 0.0013010668748373666, 'mean_word_length': 3.998699609882965, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5528708', 'n_tokens_mistral': 1381, 'n_tokens_neox': 1175, 'n_words': 257}