mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
145 lines
3.9 KiB
C#
145 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
using SabreTools.Library.Data;
|
|
|
|
namespace SabreTools.Library.Readers
|
|
{
|
|
public class IniReader : IDisposable
|
|
{
|
|
/// <summary>
|
|
/// Internal stream reader for inputting
|
|
/// </summary>
|
|
private StreamReader sr;
|
|
|
|
/// <summary>
|
|
/// Get if at end of stream
|
|
/// </summary>
|
|
public bool EndOfStream
|
|
{
|
|
get
|
|
{
|
|
return sr?.EndOfStream ?? true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Contents of the currently read line as a key value pair
|
|
/// </summary>
|
|
public KeyValuePair<string, string>? KeyValuePair { get; private set; } = null;
|
|
|
|
/// <summary>
|
|
/// Contents of the currently read line
|
|
/// </summary>
|
|
public string Line { get; private set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Current row type
|
|
/// </summary>
|
|
public IniRowType RowType { get; private set; } = IniRowType.None;
|
|
|
|
/// <summary>
|
|
/// Current section being read
|
|
/// </summary>
|
|
public string Section { get; private set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Validate that rows are in key=value format
|
|
/// </summary>
|
|
public bool ValidateRows { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// Constructor for reading from a file
|
|
/// </summary>
|
|
public IniReader(string filename)
|
|
{
|
|
sr = new StreamReader(filename);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor for reading from a stream
|
|
/// </summary>
|
|
public IniReader(Stream stream, Encoding encoding)
|
|
{
|
|
sr = new StreamReader(stream, encoding);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read the next line in the INI file
|
|
/// </summary>
|
|
public bool ReadNextLine()
|
|
{
|
|
if (!(sr.BaseStream?.CanRead ?? false) || sr.EndOfStream)
|
|
return false;
|
|
|
|
Line = sr.ReadLine().Trim();
|
|
ProcessLine();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process the current line and extract out values
|
|
/// </summary>
|
|
private void ProcessLine()
|
|
{
|
|
// Comment
|
|
if (Line.StartsWith(";"))
|
|
{
|
|
KeyValuePair = null;
|
|
RowType = IniRowType.Comment;
|
|
}
|
|
|
|
// Section
|
|
else if (Line.StartsWith("[") && Line.EndsWith("]"))
|
|
{
|
|
KeyValuePair = null;
|
|
RowType = IniRowType.SectionHeader;
|
|
Section = Line.TrimStart('[').TrimEnd(']');
|
|
}
|
|
|
|
// KeyValuePair
|
|
else if (Line.Contains("="))
|
|
{
|
|
// Split the line by '=' for key-value pairs
|
|
string[] data = Line.Split('=');
|
|
|
|
// If the value field contains an '=', we need to put them back in
|
|
string key = data[0].Trim();
|
|
string value = string.Join("=", data.Skip(1)).Trim();
|
|
|
|
KeyValuePair = new KeyValuePair<string, string>(key, value);
|
|
RowType = IniRowType.KeyValue;
|
|
}
|
|
|
|
// Empty
|
|
else if (string.IsNullOrEmpty(Line))
|
|
{
|
|
KeyValuePair = null;
|
|
Line = string.Empty;
|
|
RowType = IniRowType.None;
|
|
}
|
|
|
|
// Invalid
|
|
else
|
|
{
|
|
KeyValuePair = null;
|
|
RowType = IniRowType.Invalid;
|
|
|
|
if (ValidateRows)
|
|
throw new InvalidDataException($"Invalid INI row found, cannot continue: {Line}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dispose of the underlying reader
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
sr.Dispose();
|
|
}
|
|
}
|
|
}
|