Browse Source

增加 IniFile 模型,用于生成 INI 文件。

dev
王厅 2 months ago
parent
commit
4b04224e1c
  1. 196
      Apewer/Models/IniFile.cs
  2. 196
      Apewer/Models/IniSection.cs
  3. 57
      Apewer/Models/TextField.cs

196
Apewer/Models/IniFile.cs

@ -0,0 +1,196 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Apewer.Models
{
/// <summary>INI 文件。</summary>
[Serializable]
public sealed class IniFile : IEnumerable<IniSection>, IToJson
{
List<IniSection> _sections = new List<IniSection>();
#region Constructors
/// <summary></summary>
public IniFile() { }
/// <summary></summary>
public IniFile(IEnumerable<IniSection> sections)
{
if (sections == null) throw new ArgumentNullException(nameof(sections));
sections.ForEach(Add);
}
#endregion
#region CRUD
/// <summary>节的数量。</summary>
public int Count { get => _sections.Count; }
/// <summary>添加节。</summary>
public void Add(IniSection section)
{
if (section == null) return;
_sections.Add(section);
}
/// <summary>添加节。</summary>
public void Add(string name, TextField[] fields) => _sections.Add(new IniSection(name, fields));
/// <summary>获取节。</summary>
public IniSection Get(string sectionName)
{
var emptyName = sectionName.IsEmpty();
foreach (var section in _sections)
{
if (emptyName)
{
if (section.Name.IsEmpty()) return section;
}
else
{
if (section.Name == sectionName) return section;
}
}
return null;
}
/// <summary>移除节。</summary>
public void Remove(IniSection section)
{
while (_sections.Contains(section)) _sections.Remove(section);
}
/// <summary>移除节。</summary>
public void Remove(string sectionName)
{
var emptyName = sectionName.IsEmpty();
foreach (var section in _sections)
{
if (emptyName)
{
_sections = _sections.FindAll(x => x.Name.IsEmpty());
}
else
{
_sections = _sections.FindAll(x => x.Name == sectionName);
}
}
}
#endregion
#region IEnumerable<IniSection>
/// <summary></summary>
public IEnumerator<IniSection> GetEnumerator() => new Enumerator<IniSection>(i => i < _sections.Count ? new Class<IniSection>(_sections[i]) : null);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion
#region IToJson
/// <summary></summary>
public Json ToJson()
{
var json = Json.NewArray();
_sections.ForEach(section => json.AddItem(section.ToJson()));
return json;
}
#endregion
#region ToString
const string CRLF = "\r\n";
/// <summary></summary>
public override string ToString() => ToString(CRLF);
/// <summary></summary>
public string ToString(string seperator)
{
if (seperator.IsEmpty()) seperator = CRLF;
var sb = new StringBuilder();
var noName = 0;
foreach (var section in _sections)
{
if (section == null) continue;
if (section.Name.IsEmpty())
{
var count = section.Count;
for (var i = 0; i < count; i++)
{
var field = section.GetField(i);
if (Append(sb, field))
{
sb.Append(seperator);
noName += 1;
}
}
}
}
if (noName > 1) sb.Append(seperator);
foreach (var section in _sections)
{
if (section == null) continue;
if (section.Name.NotEmpty())
{
sb.Append("[");
sb.Append(section.Name);
sb.Append("]");
sb.Append(seperator);
foreach (var field in section)
{
if (Append(sb, field))
{
sb.Append(seperator);
}
}
}
sb.Append(seperator);
}
return sb.ToString();
}
static bool Append(StringBuilder sb, TextField field)
{
var nameEmpty = field.Name.IsEmpty();
var valueEmpty = field.Value.IsEmpty();
if (nameEmpty && valueEmpty) return false;
if (!nameEmpty)
{
sb.Append(field.Name);
sb.Append(" =");
}
if (!valueEmpty)
{
if (nameEmpty) sb.Append("; ");
else sb.Append(" ");
sb.Append(field.Value);
}
return true;
}
#endregion
}
}

196
Apewer/Models/IniSection.cs

@ -0,0 +1,196 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using static System.Collections.Specialized.BitVector32;
namespace Apewer.Models
{
/// <summary>INI 节。</summary>
[Serializable]
public sealed class IniSection : ICollection<TextField>, IEnumerable<TextField>, IToJson
{
private List<TextField> _fields = new List<TextField>();
/// <summary>节的名称(不含方括号)。</summary>
public string Name { get; set; }
/// <summary></summary>
public override string ToString() => $"Name = \"{Name}\", Count = {_fields.Count}";
#region ICollection<TextField>
/// <summary></summary>
public int Count { get => _fields.Count; }
/// <summary>集合是只读的。</summary>
/// <value>此值始终为 FALSE。</value>
public bool IsReadOnly { get => false; }
/// <summary>添加字段。</summary>
/// <exception cref="ArgumentNullException" />
public void Add(TextField item)
{
if (item == null) throw new ArgumentNullException(nameof(item));
_fields.Add(item);
}
/// <summary>清空字段。</summary>
public void Clear() => _fields.Clear();
/// <summary>检查此集合是否包含指定的字段。</summary>
public bool Contains(TextField item) => _fields.Contains(item);
/// <summary>复制字段到数组中。</summary>
/// <exception cref="ArgumentException" />
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
public void CopyTo(TextField[] array, int arrayIndex)
{
if (array == null) throw new ArgumentNullException(nameof(array));
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (array.Length - arrayIndex < _fields.Count) throw new ArgumentException("目标数组长度不足。");
_fields.CopyTo(array, arrayIndex);
}
/// <summary>移除字段。</summary>
public bool Remove(TextField item)
{
var removed = false;
while (_fields.Contains(item))
{
_fields.Remove(item);
removed = true;
}
return removed;
}
#endregion
#region Enumerable
/// <summary></summary>
public IEnumerator<TextField> GetEnumerator() => new Enumerator<TextField>(i => i < _fields.Count ? new Class<TextField>(_fields[i]) : null);
/// <summary></summary>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion
#region IToJson
/// <summary></summary>
public Json ToJson()
{
var fields = Json.NewObject();
foreach (var field in _fields)
{
fields.SetProperty(field.Name, field.Value);
}
var json = Json.NewObject();
json.SetProperty("name", Name);
json.SetProperty("fields", fields);
return json;
}
#endregion
/// <summary>检查此集合是否包含指定的字段。</summary>
/// <param name="name">字段名称。</param>
public bool Contains(string name)
{
var count = _fields.Count;
for (var i = 0; i < count; i++)
{
if (_fields[0].Name == name) return true;
}
return false;
}
/// <summary>获取字段。</summary>
/// <exception cref="ArgumentOutOfRangeException" />"
public TextField GetField(int index)
{
if (index < 0 || index >= _fields.Count) throw new ArgumentOutOfRangeException(nameof(index));
return _fields[index];
}
/// <summary></summary>
public string GetValue(string name)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
foreach (var field in _fields)
{
if (field.Name == name) return field.Value;
}
return null;
}
/// <summary></summary>
public void SetValue(string name, string value)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
var count = _fields.Count;
var setted = false;
for (var i = 0; i < count; i++)
{
if (_fields[i].Name == name)
{
_fields[i].Value = value;
setted = true;
}
}
if (!setted)
{
var field = new TextField(name, value);
_fields.Add(field);
}
}
/// <summary>获取或设置字段。</summary>
public string this[string name] { get => GetValue(name); set => SetValue(name, value); }
/// <summary></summary>
public IniSection() { }
/// <summary></summary>
public IniSection(string name) : this()
{
this.Name = name;
}
/// <summary></summary>
/// <exception cref="ArgumentNullException" />
public IniSection(string name, IEnumerable<TextField> fields) : this(name)
{
if (fields == null) throw new ArgumentNullException(nameof(fields));
_fields.AddRange(fields.Map(x => x == null ? null : new TextField(x.Name, x.Value)).FindAll(x => x != null));
}
/// <summary></summary>
/// <exception cref="ArgumentNullException" />
public IniSection(IEnumerable<TextField> fields) : this(null, fields) { }
/// <summary></summary>
/// <exception cref="ArgumentNullException" />
public IniSection(string name, IEnumerable<KeyValuePair<string, string>> fields) : this(name)
{
if (fields == null) throw new ArgumentNullException(nameof(fields));
_fields.AddRange(fields.Map(x => new TextField(x)));
}
/// <summary></summary>
/// <exception cref="ArgumentNullException" />
public IniSection(IEnumerable<KeyValuePair<string, string>> fields) : this(null, fields) { }
}
}

57
Apewer/Models/TextField.cs

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Apewer.Models
{
/// <summary>文本字段。</summary>
[Serializable]
public sealed class TextField
{
/// <summary>名称。</summary>
public string Name { get; set; }
/// <summary>值。</summary>
public string Value { get; set; }
/// <summary>文本字段。</summary>
public TextField() { }
/// <summary>创建文本字段。</summary>
public TextField(string name, string value)
{
this.Name = name;
this.Value = value;
}
/// <summary>创建文本字段。</summary>
public TextField(KeyValuePair<string, string> pair)
{
this.Name = pair.Key;
this.Value = pair.Value;
}
/// <summary></summary>
public override string ToString() => $"{Name} = {Value}";
/// <summary></summary>
public override bool Equals(object obj)
{
if (obj != null && obj is TextField field) return field.Name == Name && field.Value == Value;
return false;
}
/// <summary></summary>
public override int GetHashCode() => (Name ?? "").GetHashCode() ^ (Value ?? "").GetHashCode();
/// <summary></summary>
public static implicit operator KeyValuePair<string, string>(TextField field) => field == null ? default : new KeyValuePair<string, string>(field.Name, field.Value);
/// <summary></summary>
public static implicit operator TextField(KeyValuePair<string, string> pair) => new KeyValuePair<string, string>(pair.Key, pair.Value);
}
}
Loading…
Cancel
Save