You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.1 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. namespace Apewer.Models
  6. {
  7. /// <summary>INI 文件。</summary>
  8. [Serializable]
  9. public sealed class IniFile : IEnumerable<IniSection>, IToJson
  10. {
  11. List<IniSection> _sections = new List<IniSection>();
  12. #region Constructors
  13. /// <summary></summary>
  14. public IniFile() { }
  15. /// <summary></summary>
  16. public IniFile(IEnumerable<IniSection> sections)
  17. {
  18. if (sections == null) throw new ArgumentNullException(nameof(sections));
  19. sections.ForEach(Add);
  20. }
  21. #endregion
  22. #region CRUD
  23. /// <summary>节的数量。</summary>
  24. public int Count { get => _sections.Count; }
  25. /// <summary>添加节。</summary>
  26. public void Add(IniSection section)
  27. {
  28. if (section == null) return;
  29. _sections.Add(section);
  30. }
  31. /// <summary>添加节。</summary>
  32. public void Add(string name, TextField[] fields) => _sections.Add(new IniSection(name, fields));
  33. /// <summary>获取节。</summary>
  34. public IniSection Get(string sectionName)
  35. {
  36. var emptyName = sectionName.IsEmpty();
  37. foreach (var section in _sections)
  38. {
  39. if (emptyName)
  40. {
  41. if (section.Name.IsEmpty()) return section;
  42. }
  43. else
  44. {
  45. if (section.Name == sectionName) return section;
  46. }
  47. }
  48. return null;
  49. }
  50. /// <summary>移除节。</summary>
  51. public void Remove(IniSection section)
  52. {
  53. while (_sections.Contains(section)) _sections.Remove(section);
  54. }
  55. /// <summary>移除节。</summary>
  56. public void Remove(string sectionName)
  57. {
  58. var emptyName = sectionName.IsEmpty();
  59. foreach (var section in _sections)
  60. {
  61. if (emptyName)
  62. {
  63. _sections = _sections.FindAll(x => x.Name.IsEmpty());
  64. }
  65. else
  66. {
  67. _sections = _sections.FindAll(x => x.Name == sectionName);
  68. }
  69. }
  70. }
  71. #endregion
  72. #region IEnumerable<IniSection>
  73. /// <summary></summary>
  74. public IEnumerator<IniSection> GetEnumerator() => new Enumerator<IniSection>(i => i < _sections.Count ? new Class<IniSection>(_sections[i]) : null);
  75. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  76. #endregion
  77. #region IToJson
  78. /// <summary></summary>
  79. public Json ToJson()
  80. {
  81. var json = Json.NewArray();
  82. _sections.ForEach(section => json.AddItem(section.ToJson()));
  83. return json;
  84. }
  85. #endregion
  86. #region ToString
  87. const string CRLF = "\r\n";
  88. /// <summary></summary>
  89. public override string ToString() => ToString(CRLF);
  90. /// <summary></summary>
  91. public string ToString(string seperator)
  92. {
  93. if (seperator.IsEmpty()) seperator = CRLF;
  94. var sb = new StringBuilder();
  95. var noName = 0;
  96. foreach (var section in _sections)
  97. {
  98. if (section == null) continue;
  99. if (section.Name.IsEmpty())
  100. {
  101. var count = section.Count;
  102. for (var i = 0; i < count; i++)
  103. {
  104. var field = section.GetField(i);
  105. if (Append(sb, field))
  106. {
  107. sb.Append(seperator);
  108. noName += 1;
  109. }
  110. }
  111. }
  112. }
  113. if (noName > 1) sb.Append(seperator);
  114. foreach (var section in _sections)
  115. {
  116. if (section == null) continue;
  117. if (section.Name.NotEmpty())
  118. {
  119. sb.Append("[");
  120. sb.Append(section.Name);
  121. sb.Append("]");
  122. sb.Append(seperator);
  123. foreach (var field in section)
  124. {
  125. if (Append(sb, field))
  126. {
  127. sb.Append(seperator);
  128. }
  129. }
  130. }
  131. sb.Append(seperator);
  132. }
  133. return sb.ToString();
  134. }
  135. static bool Append(StringBuilder sb, TextField field)
  136. {
  137. var nameEmpty = field.Name.IsEmpty();
  138. var valueEmpty = field.Value.IsEmpty();
  139. if (nameEmpty && valueEmpty) return false;
  140. if (!nameEmpty)
  141. {
  142. sb.Append(field.Name);
  143. sb.Append(" =");
  144. }
  145. if (!valueEmpty)
  146. {
  147. if (nameEmpty) sb.Append("; ");
  148. else sb.Append(" ");
  149. sb.Append(field.Value);
  150. }
  151. return true;
  152. }
  153. #endregion
  154. }
  155. }