2017-06-06 21:13:25 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2017-07-22 19:27:41 +00:00
|
|
|
|
namespace Glove.INI {
|
2017-06-06 21:13:25 +00:00
|
|
|
|
public class SettingsFile {
|
|
|
|
|
private Dictionary<string, Section> Sections
|
|
|
|
|
= new Dictionary<string, Section>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
public SettingsFile(string path) {
|
|
|
|
|
var lines = File.ReadAllLines(path);
|
|
|
|
|
|
2017-06-07 21:02:29 +00:00
|
|
|
|
Instance currentInstance = null;
|
|
|
|
|
foreach(var rawLine in lines) {
|
|
|
|
|
var line = rawLine.Trim();
|
|
|
|
|
if(line.StartsWith("!", "#", ";"))
|
|
|
|
|
continue;
|
2017-06-06 21:13:25 +00:00
|
|
|
|
|
2017-06-07 21:02:29 +00:00
|
|
|
|
if(line.StartsWith("[") && line.EndsWith("]")) {
|
|
|
|
|
var section = line.Substring(1, line.Length - 2);
|
|
|
|
|
if(!Sections.ContainsKey(section))
|
|
|
|
|
Sections.Add(section, new Section());
|
|
|
|
|
|
|
|
|
|
currentInstance = Sections[section].Push();
|
|
|
|
|
} else {
|
|
|
|
|
if(currentInstance != null)
|
|
|
|
|
currentInstance.Push(line);
|
|
|
|
|
else
|
|
|
|
|
throw new FormatException("Non-section line before any define sections in '"+ path +"'");
|
|
|
|
|
}
|
2017-06-06 21:13:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-07 21:02:29 +00:00
|
|
|
|
public SettingsFile(string path, List<SectionRules> rules) : this(path) {
|
|
|
|
|
foreach(var rule in rules) {
|
|
|
|
|
var name = rule.Name;
|
|
|
|
|
|
|
|
|
|
if(ContainsSection(name)) {
|
|
|
|
|
var section = Sections[name];
|
|
|
|
|
if(!rule.AllowMultiple && section.Count > 1)
|
|
|
|
|
throw new FormatException("Section '"+ name +"' is not allowed to have multiple declarations in '"+ path +"'");
|
2017-06-06 21:13:25 +00:00
|
|
|
|
|
2017-06-07 21:02:29 +00:00
|
|
|
|
if(rule.RequiredFields.Length > 0) {
|
|
|
|
|
foreach(var instance in section) {
|
|
|
|
|
foreach(var field in rule.RequiredFields) {
|
|
|
|
|
if(instance.ContainsKey(field))
|
|
|
|
|
throw new FormatException("Expected field '"+ field +"' in section '" + name + "' was not found in '" + path + "'");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if(rule.Required)
|
|
|
|
|
throw new FormatException("Expected section '"+ name +"' was not found in '"+ path +"'");
|
|
|
|
|
}
|
2017-06-06 21:13:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Section this[string section] {
|
|
|
|
|
get {
|
|
|
|
|
if(Sections.ContainsKey(section))
|
|
|
|
|
return Sections[section];
|
|
|
|
|
else return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-07 21:02:29 +00:00
|
|
|
|
|
|
|
|
|
public bool ContainsSection(string section) {
|
|
|
|
|
return Sections.ContainsKey(section);
|
|
|
|
|
}
|
2017-06-06 21:13:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|