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
6.2 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using static System.Collections.Specialized.BitVector32;
  6. namespace Apewer.Models
  7. {
  8. /// <summary>INI 节。</summary>
  9. [Serializable]
  10. public sealed class IniSection : ICollection<TextField>, IEnumerable<TextField>, IToJson
  11. {
  12. private List<TextField> _fields = new List<TextField>();
  13. /// <summary>节的名称(不含方括号)。</summary>
  14. public string Name { get; set; }
  15. /// <summary></summary>
  16. public override string ToString() => $"Name = \"{Name}\", Count = {_fields.Count}";
  17. #region ICollection<TextField>
  18. /// <summary></summary>
  19. public int Count { get => _fields.Count; }
  20. /// <summary>集合是只读的。</summary>
  21. /// <value>此值始终为 FALSE。</value>
  22. public bool IsReadOnly { get => false; }
  23. /// <summary>添加字段。</summary>
  24. /// <exception cref="ArgumentNullException" />
  25. public void Add(TextField item)
  26. {
  27. if (item == null) throw new ArgumentNullException(nameof(item));
  28. _fields.Add(item);
  29. }
  30. /// <summary>清空字段。</summary>
  31. public void Clear() => _fields.Clear();
  32. /// <summary>检查此集合是否包含指定的字段。</summary>
  33. public bool Contains(TextField item) => _fields.Contains(item);
  34. /// <summary>复制字段到数组中。</summary>
  35. /// <exception cref="ArgumentException" />
  36. /// <exception cref="ArgumentNullException" />
  37. /// <exception cref="ArgumentOutOfRangeException" />
  38. public void CopyTo(TextField[] array, int arrayIndex)
  39. {
  40. if (array == null) throw new ArgumentNullException(nameof(array));
  41. if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
  42. if (array.Length - arrayIndex < _fields.Count) throw new ArgumentException("目标数组长度不足。");
  43. _fields.CopyTo(array, arrayIndex);
  44. }
  45. /// <summary>移除字段。</summary>
  46. public bool Remove(TextField item)
  47. {
  48. var removed = false;
  49. while (_fields.Contains(item))
  50. {
  51. _fields.Remove(item);
  52. removed = true;
  53. }
  54. return removed;
  55. }
  56. #endregion
  57. #region Enumerable
  58. /// <summary></summary>
  59. public IEnumerator<TextField> GetEnumerator() => new Enumerator<TextField>(i => i < _fields.Count ? new Class<TextField>(_fields[i]) : null);
  60. /// <summary></summary>
  61. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  62. #endregion
  63. #region IToJson
  64. /// <summary></summary>
  65. public Json ToJson()
  66. {
  67. var fields = Json.NewObject();
  68. foreach (var field in _fields)
  69. {
  70. fields.SetProperty(field.Name, field.Value);
  71. }
  72. var json = Json.NewObject();
  73. json.SetProperty("name", Name);
  74. json.SetProperty("fields", fields);
  75. return json;
  76. }
  77. #endregion
  78. /// <summary>检查此集合是否包含指定的字段。</summary>
  79. /// <param name="name">字段名称。</param>
  80. public bool Contains(string name)
  81. {
  82. var count = _fields.Count;
  83. for (var i = 0; i < count; i++)
  84. {
  85. if (_fields[0].Name == name) return true;
  86. }
  87. return false;
  88. }
  89. /// <summary>获取字段。</summary>
  90. /// <exception cref="ArgumentOutOfRangeException" />"
  91. public TextField GetField(int index)
  92. {
  93. if (index < 0 || index >= _fields.Count) throw new ArgumentOutOfRangeException(nameof(index));
  94. return _fields[index];
  95. }
  96. /// <summary></summary>
  97. public string GetValue(string name)
  98. {
  99. if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
  100. foreach (var field in _fields)
  101. {
  102. if (field.Name == name) return field.Value;
  103. }
  104. return null;
  105. }
  106. /// <summary></summary>
  107. public void SetValue(string name, string value)
  108. {
  109. if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
  110. var count = _fields.Count;
  111. var setted = false;
  112. for (var i = 0; i < count; i++)
  113. {
  114. if (_fields[i].Name == name)
  115. {
  116. _fields[i].Value = value;
  117. setted = true;
  118. }
  119. }
  120. if (!setted)
  121. {
  122. var field = new TextField(name, value);
  123. _fields.Add(field);
  124. }
  125. }
  126. /// <summary>获取或设置字段。</summary>
  127. public string this[string name] { get => GetValue(name); set => SetValue(name, value); }
  128. /// <summary></summary>
  129. public IniSection() { }
  130. /// <summary></summary>
  131. public IniSection(string name) : this()
  132. {
  133. this.Name = name;
  134. }
  135. /// <summary></summary>
  136. /// <exception cref="ArgumentNullException" />
  137. public IniSection(string name, IEnumerable<TextField> fields) : this(name)
  138. {
  139. if (fields == null) throw new ArgumentNullException(nameof(fields));
  140. _fields.AddRange(fields.Map(x => x == null ? null : new TextField(x.Name, x.Value)).FindAll(x => x != null));
  141. }
  142. /// <summary></summary>
  143. /// <exception cref="ArgumentNullException" />
  144. public IniSection(IEnumerable<TextField> fields) : this(null, fields) { }
  145. /// <summary></summary>
  146. /// <exception cref="ArgumentNullException" />
  147. public IniSection(string name, IEnumerable<KeyValuePair<string, string>> fields) : this(name)
  148. {
  149. if (fields == null) throw new ArgumentNullException(nameof(fields));
  150. _fields.AddRange(fields.Map(x => new TextField(x)));
  151. }
  152. /// <summary></summary>
  153. /// <exception cref="ArgumentNullException" />
  154. public IniSection(IEnumerable<KeyValuePair<string, string>> fields) : this(null, fields) { }
  155. }
  156. }