#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2017 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
namespace Nuclex.Support.Settings {
/// Represents an ini- or cfg-like configuration file
///
///
/// This class tries its best to preserve the formatting of configuration files.
/// Changing a value will keep the line it appears in intact. The parser also takes
/// as much data from a line as it can - anything to the left of an equals sign
/// becomes the name, anything to the right (excluding comments) becomes the value.
///
///
/// To access the contents of a configuration file, simply parse it and use it like
/// you would any other settings store:
///
///
///
/// // # Settings.ini
/// // message = hello world ; the usual...
/// // show message = true
/// ISettingsStore settings;
/// using(var reader = new StreamReader("settings.ini")) {
/// settings = ConfigurationFile.Parse(reader);
/// }
///
/// if(settings.Get<bool>(null, "show message")) {
/// Console.WriteLine(settings.Get<string>(null, "message"));
/// }
///
///
///
/// It's usually a good idea to keep an application and all of its required files
/// together, whether it's code or data, but platforms often have their own conventions:
///
///
///
/// Operating System
/// Convention
///
///
/// Linux
///
/// System-wide configuration goes into /etc/<appname>/, user-specific
/// configuration goes into ~/.<appname>/ while static configuration that is
/// known at build time resides with the application in /opt/<appname>/
///
///
///
/// Windows
///
/// System-wide configuration goes into %ProgramData%, user-specific configuration
/// has no real place (try %AppData%/<appname>/ if you want to hide it from
/// the user, %UserProfile%/Documents/<appname> if the user should see it)
/// and static configuration resides with your application
/// in %ProgramFiles%/<appname>/.
///
///
///
/// MacOS
///
/// System-wide configuration goes into /etc/<appname>/, user-specific
/// configuration goes into /Users/<username>/.<appname>/ while static
/// configuration resides with the application in /Applications/<appname>/
///
///
///
///
public partial class ConfigurationFileStore : ISettingsStore {
#region class Category
/// Stores informations about a category found in the configuration file
private class Category {
/// Name of the category as a string
public StringSegment CategoryName;
/// Lookup table for the options in this category
public IDictionary OptionLookup;
/// Lines this category and its options consist of
public IList Lines;
}
#endregion // class Category
#region class Option
/// Stores informations about an option found in the configuration file
private class Option {
/// Index of the line the option is defined in
public int LineIndex;
/// Name of the option as a string
public StringSegment OptionName;
/// Value of the option as a string
public StringSegment OptionValue;
}
#endregion // class Option
/// Initializes a new, empty configuration file
public ConfigurationFileStore() {
this.options = new List